Analisar solicitações HTTP com filtros de log Java
javax.servlet.FilterUma maneira conveniente de implementar e analisar o conteúdo de solicitações HTTP e logs de saída.FiltroApresentando a aula.
Este filtro de log usa "java.util.logging.Logger" para saída de log e você pode alterar a saída de informações alterando o nível de log.
O que é javax.servlet.Filter?
Ao construir uma aplicação web, além do processamento comercial principal, é necessário realizar o processamento secundário comum antes e depois do processamento comercial principal.
Por exemplo, autenticação de cliente, verificação de autoridade, registro, etc.
Codificar esse processamento secundário em cada recurso torna-se uma das principais causas de dificultar a manutenção do software, resultando em um aplicativo de difícil manutenção.
Ao implementar javax.servlet.Filter, normalmente é possível executar esse processamento secundário antes que a solicitação seja passada para a classe do servlet.
Além disso, como as configurações de filtro podem ser feitas em web.xml, você pode adicionar ou excluir filtros de maneira flexível, sem alterar o código-fonte.
Tente usar um filtro de log
Na verdade, vamos usar um filtro de log para filtrar solicitações HTTP e analisá-las.
Desta vezgatoUsaremos o aplicativo de exemplos que está disponível desde o início.
Você pode executar esse filtro imediatamente fazendo as seguintes configurações.
2. Coloque o arquivo de classe compilado em "/examples/WEB-INF/classes".
3.Defina a seguinte definição em web.xml.
Filtro de registro Filtro de registro registro.Level MULTAR Filtro de registro /*
*O padrão de URL ao usar a estrutura Struts é o seguinte.
*.fazer
Verifique os resultados da saída de log da execução da tela Exemplo de Sessões.
Informações de log de saída e nível de log
●Registrar conteúdo de saída
Informações de registro | nível de registro |
---|---|
Informações sobre cookies | MULTAR |
Informações do cabeçalho HTTP | MULTAR |
HTTPOutras informações | MULTAR |
Parâmetros de solicitação HTTP | CONFIGURAÇÃO |
objeto de escopo de solicitação | CONFIGURAÇÃO |
objeto com escopo de sessão | CONFIGURAÇÃO |
Uso de memória antes e depois das solicitações | CONFIGURAÇÃO |
Informações de transição de tela | INFORMAÇÕES |
É melhor usar níveis de log da seguinte forma.
- FINE: Produz o log mais detalhado. Defina isto se quiser analisar detalhadamente a solicitação HTTP.
- CONFIG... Produz um log um tanto detalhado. É uma boa ideia mantê-lo neste nível durante o período de desenvolvimento.
- INFO: Produz apenas informações de transição de tela.
●Como alterar o nível de registro
Você pode alterar o nível de saída do log definindo o parâmetro de inicialização logging.Level.
exemplo:
registro.Level INFORMAÇÕES
Código fonte
importar javax.servlet.Filter;
importar javax.servlet.FilterChain;
importar javax.servlet.FilterConfig;
importar javax.servlet.ServletException;
importar javax.servlet.ServletRequest;
importar javax.servlet.ServletResponse;
importar javax.servlet.http.Cookie;
importar javax.servlet.http.HttpServletRequest;
importar javax.servlet.http.HttpServletResponse;
importar javax.servlet.http.HttpSession;
/**
* Implemente javax.servlet.Filter para analisar o conteúdo de solicitações HTTP e logs de saída
* Filtrar classe.
*/
classe pública LogFilter implementa Filter {
registrador estático privado =
Logger.getLogger(LogFilter.class.getName());
string final estática privada LINE_SEPA =
System.getProperty(“linha.separador”);
string final estática privada NEXT_PAGE = “LogFilter.NEXT_PAGE”;
/**
* Inicialize este filtro de log.
* @param mapeamento
*/
public void init(mapeamento FilterConfig) {
String str = mapeamento.getInitParameter(“logging.Level”);
System.out.println(“Definir nível de log para “+str+”.”);
Nível nível = nulo;
tentar {
nível = Nível.parse(str);
} catch (Exceção e) {
e.printStackTrace();
nível = Nível.INFO;
}
LogManager.getLogManager().reset();
Manipulador manipulador = new CustomConsoleHandler();
manipulador.setFormatter(novo CustomFormatter());
manipulador.setLevel(nível);
logger.setLevel(nível);
logger.getParent().addHandler(manipulador);
}
/**
* Este é um filtro que gera logs.
* @param request Solicitação HTTP sendo processada
* @param resposta Resposta HTTP sendo gerada
* @param cadeia
*/
public void doFilter(ServletRequest _request, ServletResponse _response,
Cadeia FilterChain) lança IOException, ServletException {
// --------------------" Pré-processando "
Solicitação HttpServletRequest = (HttpServletRequest) _request;
Resposta HttpServletResponse = (HttpServletResponse) _response;
if (logger.isLoggable(Level.CONFIG)) {
registrador.config(
“============ Solicitar início !!”
+”ID do tópico:”
+ Thread.currentThread().hashCode()
+ ” ========================================================”);
}
// uso de memória
String actionMemory = null;
if (logger.isLoggable(Level.CONFIG)) {
actionMemory = getMemoryInfo(” ”
+ new Time(System.currentTimeMillis()) + ”Solicitação[anterior]”);
}
if (logger.isLoggable(Level.FINE)) {
logger.fine (“Informações sobre cookies” + getCookieInfo (solicitação));
}
if (logger.isLoggable(Level.FINE)) {
logger.fine(“Informações do cabeçalho HTTP” + getHeadersInfo(request));
}
if (logger.isLoggable(Level.FINE)) {
registrador
.fine(“Outras informações HTTP” + getRequestOtherInfo(request));
}
if (logger.isLoggable(Level.CONFIG)) {
String reqlog = getRequestParametersInfo(solicitação);
logger.config(“Parâmetros de solicitação HTTP” + reqlog);
}
if (logger.isLoggable(Level.CONFIG)) {
logger.config (“objeto de escopo de solicitação”
+ getRequestAttributeInfo(solicitação));
}
if (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(solicitação,true);
logger.config(“objeto de escopo de sessão (antes do processamento da solicitação)”
+ log de sessão);
}
//chama o próximo filtro
chain.doFilter(solicitação,resposta);
// -------------------- "Pós-processamento"
if (logger.isLoggable(Level.CONFIG)) {
String sessionlog = getSessionInfo(solicitação,falso);
logger.config(“objeto de escopo de sessão (após processamento da solicitação)”
+ log de sessão);
}
// uso de memória
if (logger.isLoggable(Level.CONFIG)) {
actionMemory = ”Uso de memória antes e depois da solicitação”+LINE_SEPA
+ actionMemory + LINE_SEPA
+ getMemoryInfo(” ” + new Time(System.currentTimeMillis())
+ ”solicitação[depois]”);
logger.config(actionMemory+LINE_SEPA);
}
//Informações de transição de tela
if (logger.isLoggable(Level.INFO)) {
String nextPage = (String) request.getAttribute(NEXT_PAGE);
if (nextPage == null || nextPage.length() == 0) {
nextPage = request.getRequestURI();
}
logger.info(“NEXT_PAGE=[” + nextPage + “], ”
+ “IP_ADDRESS=[” + request.getRemoteAddr() + “], ”
+ “SESSION_ID=[” + request.getSession().getId() + “], ”
+ “USER-AGENT=[” + request.getHeader(“user-agent”) + “]”);
}
if (logger.isLoggable(Level.CONFIG)) {
registrador.config(
“============ Fim da solicitação!!”
+”ID do tópico:”+ Thread.currentThread().hashCode()
+ ” =========================================================”
+LINE_SEPA+LINE_SEPA);
}
}
/**
*
*/
public void destruir() {
}
// ---------- Método privado abaixo -----------
private static String getMemoryInfo(String mensagem) {
DecimalFormat dFromat = novo DecimalFormat(“#,###KB”);
longo livre = Runtime.getRuntime().freeMemory() / 1024;
total longo = Runtime.getRuntime().totalMemory() / 1024;
máximo longo = Runtime.getRuntime().maxMemory() / 1024;
usado há muito tempo = total – grátis;
String msg = mensagem + ”: ” + “total =” + dFromat.format (total) + “, ”
+ “Quantidade usada=” + dFromat.format(usado) + ”(” + (usado * 100 / total)
+ “%), máximo disponível=” + dFromat.format(max);
retornar mensagem;
}
/**
* Envie todos os cabeçalhos de solicitação para o log.
*/
string estática privada getHeadersInfo(solicitação HttpServletRequest) {
Buff de StringBuffer = novo StringBuffer(LINE_SEPA);
Enumeração headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
buff.append(” “);
buff.append(headerName);
buff.append(“=”);
buff.append(request.getHeader(headerName));
buff.append(LINE_SEPA);
}
retornar buff.toString();
}
string estática privada getCookieInfo(solicitação HttpServletRequest) {
Buff de StringBuffer = new StringBuffer();
Cookie[] cookies = request.getCookies();
if (cookies == nulo) {
retornar "";
}
for (int i = 0; i < cookies.length; i++) {
buff.append(“\n — Cookie[” + i + “] —\n”);
buff.append(” “);
buff.append(cookies[i].getName());
buff.append(“=”);
buff.append(cookies[i].getValue());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getVersion()”);
buff.append(“=”);
buff.append(cookies[i].getVersion());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getComment()”);
buff.append(“=”);
buff.append(cookies[i].getComment());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getDomain()”);
buff.append(“=”);
buff.append(cookies[i].getDomain());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getMaxAge()”);
buff.append(“=”);
buff.append(cookies[i].getMaxAge());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getPath()”);
buff.append(“=”);
buff.append(cookies[i].getPath());
buff.append(LINE_SEPA);
buff.append(” “);
buff.append(“getSecure()”);
buff.append(“=”);
buff.append(cookies[i].getSecure());
buff.append(LINE_SEPA);
}
retornar buff.toString();
}
string estática privada getRequestParametersInfo(solicitação HttpServletRequest) {
Buff de StringBuffer = novo StringBuffer(LINE_SEPA);
Mapa mapa = convertRequest(solicitação);
TreeMap trr = new TreeMap(mapa);
Iterador itr = trr.keySet().iterator();
enquanto (itr.hasNext()) {
String chave = (String) itr.next();
buff.append(” “);
buff.append(chave);
buff.append(“=”);
Valor do objeto = map.get(key);
Valores String[] = valor (String[]);
if (valores.comprimento == 1) {
buff.append(valores[0]);
} outro {
//Array de string é convertido
String strValue = estrato(valores);
buff.append(strValue);
}
buff.append(LINE_SEPA);
}
retornar buff.toString();
}
private static String getRequestAttributeInfo(solicitação HttpServletRequest) {
Buff de StringBuffer = novo StringBuffer(LINE_SEPA);
Enumeração e = request.getAttributeNames();
enquanto (e.hasMoreElements()) {
String nome = (String) e.nextElement();
buff.append(”nome=” + nome + “,tributoClass=”
+ request.getAttribute(nome).getClass().getName()
+ “, toString() = ” + request.getAttribute(nome)
+ LINHA_SEPA);
}
retornar buff.toString();
}
private static String getRequestOtherInfo(solicitação HttpServletRequest) {
Buff de StringBuffer = new StringBuffer();
buff.append(LINE_SEPA);
buff.append(”getCharacterEncoding()=”);
buff.append(request.getCharacterEncoding());
buff.append(LINE_SEPA);
buff.append(”getContentLength()=”);
buff.append(request.getContentLength());
buff.append(LINE_SEPA);
buff.append(”getContentType()=”);
buff.append(request.getContentType());
buff.append(LINE_SEPA);
buff.append(”getLocale()=”);
buff.append(request.getLocale());
buff.append(LINE_SEPA);
buff.append(”getProtocol()=”);
buff.append(request.getProtocol());
buff.append(LINE_SEPA);
buff.append(”getRemoteAddr()=”);
buff.append(request.getRemoteAddr());
buff.append(LINE_SEPA);
buff.append(”getRemoteHost()=”);
buff.append(request.getRemoteHost());
buff.append(LINE_SEPA);
buff.append(”getScheme()=”);
buff.append(request.getScheme());
buff.append(LINE_SEPA);
buff.append(”getServerName()=”);
buff.append(request.getServerName());
buff.append(LINE_SEPA);
buff.append(”getServerPort()=”);
buff.append(request.getServerPort());
buff.append(LINE_SEPA);
buff.append(”isSecure()=”);
buff.append(request.isSecure());
buff.append(LINE_SEPA);
buff.append(”getAuthType()=”);
buff.append(request.getAuthType());
buff.append(LINE_SEPA);
buff.append(”getContextPath()=”);
buff.append(request.getContextPath());
buff.append(LINE_SEPA);
buff.append(”getMethod()=”);
buff.append(request.getMethod());
buff.append(LINE_SEPA);
buff.append(”getPathInfo()=”);
buff.append(request.getPathInfo());
buff.append(LINE_SEPA);
buff.append(”getPathTranslated()=”);
buff.append(request.getPathTranslated());
buff.append(LINE_SEPA);
buff.append(”getQueryString()=”);
buff.append(request.getQueryString());
buff.append(LINE_SEPA);
buff.append(”getRemoteUser()=”);
buff.append(request.getRemoteUser());
buff.append(LINE_SEPA);
buff.append(”getRequestedSessionId()=”);
buff.append(request.getRequestedSessionId());
buff.append(LINE_SEPA);
buff.append(”getRequestURI()=”);
buff.append(request.getRequestURI());
buff.append(LINE_SEPA);
buff.append(”getServletPath()=”);
buff.append(request.getServletPath());
buff.append(LINE_SEPA);
buff.append(”getUserPrincipal()=”);
buff.append(request.getUserPrincipal());
buff.append(LINE_SEPA);
buff.append(”isRequestedSessionIdFromCookie()=”);
buff.append(request.isRequestedSessionIdFromCookie());
buff.append(LINE_SEPA);
buff.append(”isRequestedSessionIdFromURL()=”);
buff.append(request.isRequestedSessionIdFromURL());
buff.append(LINE_SEPA);
buff.append(”isRequestedSessionIdValid()=”);
buff.append(request.isRequestedSessionIdValid());
buff.append(LINE_SEPA);
retornar buff.toString();
}
private static String getSessionInfo(solicitação HttpServletRequest,boolean antes) {
Sessão HttpSession = request.getSession();
Buff de StringBuffer = new StringBuffer();
buff.append(LINE_SEPA);
se (antes) {
buff.append(”sessão.isNew() =” +sessão.isNew());
buff.append(LINE_SEPA);
buff.append(”sessão.getId() =” +sessão.getId());
buff.append(LINE_SEPA);
}
Enumeração e = session.getAttributeNames();
enquanto (e.hasMoreElements()) {
String sessionName = (String) e.nextElement();
String sessionClassName = session.getAttribute(sessionName)
.getClass().getNome();
buff.append(”nome =” + nomedasessão + “, valor =”
+ session.getAttribute(sessionName) + “,tributoClass = ”
+ sessionClassName+LINE_SEPA);
}
retornar buff.toString();
}
private static Hashtable convertRequest(solicitação HttpServletRequest) {
Tabela de hash tempHash = new Tabela de hash();
Enumeração e = request.getParameterNames();
enquanto (e.hasMoreElements()) {
String chave = (String) e.nextElement();
String[] valores = request.getParameterValues(chave);
String[] parâmetroValores = new String[valores.comprimento];
for (int i = 0; i < valores.comprimento; i++) {
parâmetroValores[i] = convUnicode(valores[i]);
}
tempHash.put(chave, parâmetrosValores);
}
retornar tempHash;
}
estrato de String estática privada (valor do objeto) {
if (valor == nulo) {
retorne “nulo”;
} else if (valor instância de String[]) {
retornar convString((String[]) valor);
} outro {
retornar valor.toString();
}
}
/**
* Retorna o conteúdo do array de strings [strArray] como uma String como a mostrada abaixo.
* “[temp1,temp2,temp3]”
* @param strArray Array de strings a ser avaliado
* @return String após a conversão
*/
string estática privada convString(String[] strArray) {
if (strArray == nulo)
retornar nulo;
StringBuffer buff = new StringBuffer(“[“);
for (int i = 0; i < strArray.length; i++) {
buff.append(strArray[i] + “, “);
}
buff.delete(buff.length() – 2, buff.length());
buff.append(“]”);
retornar buff.toString();
}
/**
* Converta [str] para Unicode.
* @paramstr
* @retornar
*/
string estática privada convUnicode(String str) {
if (str == nulo)
retornar nulo;
tentar {
retornar nova String(str.getBytes(“8859_1”), “JISAutoDetect”);
} catch (UnsupportedEncodingException e) {
lançar nova RuntimeException(e);
}
}
// ———————————————————————–
classe estática CustomFormatter estende Formatador {
padrão de string final estático = “aaaa/MM/dd HH:mm:ss”;
formato de string sincronizado público (registro LogRecord) {
StringBuffer buf = new StringBuffer();
//define data e hora
Data data = new Data();
date.setTime(record.getMillis());
Formatador SimpleDateFormat = new SimpleDateFormat(padrão);
buf.append(formatter.format(data));
buf.append(“:”);
//define o nível
buf.append(“[” + record.getLevel().getName() + “]”);
buf.append(“:”);
buf.append(record.getMessage());
buf.append(LINE_SEPA);
retornar buf.toString();
}
}
classe estática CustomConsoleHandler estende StreamHandler {
public CustomConsoleHandler() {
super();
setOutputStream(System.out);
}
/**
* Emite um LogRecord.
* Inicialmente, as solicitações de registro são enviadas para um objeto Logger.
* e este objeto inicializa o LogRecord e
*Redirecionado aqui.
*
* @param record Descrição do evento de log. registros nulos são simplesmente ignorados
* e nenhuma notificação será enviada.
*/
publicação void pública (registro LogRecord) {
super.publicar(registro);
rubor();
}
/**
* Substitua StreamHandler.close para liberar, mas
* O fluxo de saída não está fechado. Em outras palavras, System.err não está fechado.
*/
público void fechar() {
rubor();
}
}
}