Articles

Como Log4J2 Funciona: 10 Maneiras de Ficar Mais De Fora

Log4j2 é a versão atualizada do popular e influente biblioteca log4j, usado amplamente em todo o ecossistema Java por tantos anos. Version 2.x mantém todas as características de registro de seu antecessor e constrói sobre essa fundação com algumas melhorias significativas, especialmente na área de desempenho.

E, claro, dada a forma como o registro instrumental é para qualquer aplicação, tanto para fins de auditoria e depuração, escolher uma biblioteca de registro sólido é uma decisão muito importante.

nas seguintes seções, vamos dar uma olhada por que a biblioteca log4j2 é uma ótima escolha para essa decisão e como podemos usá-la em uma aplicação.

Configuração Básica do Log4j2

para começar a usar o log4j2 no seu projecto, basta adicionar a dependência do núcleo do log4j. Se estiver a usar o Maven, pode adicionar a seguinte dependência ao seu pom.ficheiro xml:

E se você está trabalhando com Gradle, você precisa adicionar a dependência à compilação.gradle file:

dependencies { compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.8.2'}

fora da caixa, log4j2 irá automaticamente fornecer uma configuração simples, se você não definir explicitamente uma. Os registros de configuração padrão para a consola em um nível de erro ou acima.

para iniciar o registo de mensagens com esta configuração básica, tudo o que precisa de fazer é obter uma instância de registo com a classe LogManager:

private static Logger logger = LogManager.getLogger(MyService.class);

então poderá usar o objecto de registo com métodos correspondentes ao nível de registo que deseja:

logger.error("This is an error message");

personalizar a configuração de Log4j2

uma configuração de log4j2 personalizada pode ser criada programaticamente ou através de um ficheiro de configuração.

a biblioteca suporta arquivos de configuração escritos em XML, JSON, YAML, bem como o .formato de propriedades. Aqui, vamos usar XML para discutir todos os exemplos principalmente.

primeiro, você pode substituir a configuração padrão simplesmente criando um log4j2.ficheiro xml no classpath:

Vamos dar uma olhada mais de perto as marcas usados nesta configuração simples:

  • Configuração: o elemento raiz de um log4j2 arquivo de configuração; o estado de atributo representa o nível no qual interno log4j eventos devem ser registrados
  • Appenders: este elemento contém uma lista de appenders; no nosso exemplo, um appender correspondente para o console do Sistema é definido
  • Madeireiros: este elemento contém uma lista de Registrador de instâncias. O elemento Root é um logger padrão que produz todas as mensagens

é importante entender que o logger Root é obrigatório em cada configuração. Como discutido, se você não fornecer um, ele será automaticamente configurado por padrão com um appender de consola e o nível de registro de erros.

configurar os remetentes

na arquitectura log4j2, um remetente é basicamente responsável pelo envio de mensagens de registo para um determinado destino de saída.

Aqui estão alguns dos tipos de aplicações mais úteis que a biblioteca oferece:

  • ConsoleAppender – registra mensagens para o console do Sistema
  • FileAppender – grava mensagens de log para um arquivo
  • RollingFileAppender – escreve as mensagens para um rolamento de arquivo de log
  • JDBCAppender – usa um banco de dados relacional para os logs
  • AsyncAppender – contém uma lista de outros appenders e determina os logs para estes a ser escrito em uma thread separada

Para entender melhor como appenders trabalho, vejamos alguns exemplos de configuração.

o Rollingfilappender

registar tudo num único ficheiro não é, obviamente, o ideal. Geralmente é muito melhor rolar o arquivo de log ativo regularmente-que é exatamente o que o Rollingfilappender faz.

Você também será capaz de ir além do básico com este tipo de appender e configurar tanto uma política de acionamento personalizado, bem como a estratégia de rollover.

a Política de desencadeamento determina quando o arquivo de log é rolado, o que significa que um novo arquivo é criado, enquanto a estratégia de rollover determina como o arquivo é rolado.

Como um exemplo rápido, vamos configurar um appender que cria um novo arquivo de log com base em 3 políticas:

  • OnStartupTriggeringPolicy – um novo arquivo de log é criado cada vez que a JVM inicia
  • TimeBasedTriggeringPolicy – o arquivo de log é implementado com base em uma data/horário padrão
  • SizeBasedTriggeringPolicy – o arquivo é revertida quando se atinge um determinado tamanho

A configuração irá utilizar o DefaultRolloverStrategy:

Você pode ver o quão flexível este estilo de configuração é, e como você pode sintonizar a semântica exata de sua estratégia de registro – até o último detalhe.

The JDBCAppender

As the name suggests, this appender uses JDBC to write logs to a relational database.

para esta configuração, você precisa definir um ConnectionSource, que pode ser tanto uma fonte de dados JNDI ou um Conectionfactory personalizado. O logger usa o ConnectionSource para obter conexões JDBC, e é por isso que é importante usar um pool de conexão para um melhor desempenho.

para configurar o appender no ficheiro de configuração XML, poderá usar a marca JDBC:

Como poderá ver, a fonte de dados JNDI é simplesmente indicada usando o atributo jndiName da marca DataSource. Junto com o ConnectionSource, você pode definir a tabela e as colunas a serem usadas para armazenar os dados de log.

o FailoverAppender

finalmente, vamos dar uma olhada no FailoverAppender; isto define um appender primário e uma lista de backups que irão intervir para lidar com o registo no caso do primeiro falhar.

Por exemplo, você pode configurar um JDBCAppender primário, com um secundário o RollingFile e o console appenders, no caso de não ser possível estabelecer uma ligação à base de dados:

num ambiente de produção, ter uma estratégia de falha para o seu mecanismo de registo é sempre uma boa ideia.

configurar as disposições

enquanto os remetentes são responsáveis pelo envio de mensagens de registo para um destino, as disposições são usadas pelos remetentes para definir como uma mensagem de registo será formatada.

Aqui está uma breve descrição de alguns dos layouts mais comumente usados que log4j2 oferece:

  • PatternLayout – configura as mensagens de acordo com um padrão de Seqüência de caracteres
  • JsonLayout – define um formato JSON para mensagens de log
  • CsvLayout – pode ser usado para criar mensagens em formato CSV

O PatternLayout

O primeiro tipo de layout, nós vamos olhar é o PatternLayout. Esta é uma solução bastante flexível que lhe dá um monte de controle sobre a saída final da mensagem de log.

O mecanismo é primariamente impulsionado por um padrão de conversão que contém especificadores de conversão. Cada especificador começa com o sinal%, seguido por modificadores que controlam coisas como a largura e a cor da mensagem, e um caractere de conversão que representa o conteúdo, como a data ou o nome do tópico.

vejamos um exemplo de configuração de uma PatternLayout que configura linhas de log para mostrar a data, a linha, o nível de log e log de mensagens, com diferentes cores para diferentes níveis de log:

Esses especificadores são bem vale a pena compreender em detalhes, então vamos dar uma olhada mais de perto:

  • %d{HH:mm:ss.SSS} – saídas a data do evento de log no formato especificado
  • %t – saídas o nome do thread
  • %nível – exibe o nível de log da mensagem
  • %realçar{%nível} – é usado para definir as cores para o padrão entre parênteses
  • %erro%n – saídas a mensagem de registo

A saída exibirá os níveis de log com cores diferentes:

Você pode ler mais sobre o conjunto completo de opções para a definição de padrões no log4j2 documentação sobre PatternLayout.

o JsonLayout

Logging dados usando o formato JSON tem algumas vantagens significativas, tais como tornar os logs mais fáceis de ser analisados e processados por ferramentas de registro abaixo da linha.

Para configurar o JSONLayout em log4j2, você pode simplesmente definir a tag correspondente:

<JSONLayout complete="true" compact="false"/>

Configuração completa=true irá produzir um bem formado JSON documento:

Para ser capaz de produzir JSON, você também precisará adicionar o jackson-databind biblioteca ao classpath:

configurar os filtros

filtros no log4j2 são usados para determinar se uma mensagem de registo deve ser processada ou ignorada.

um filtro pode ser configurado para toda a configuração ou ao nível de logger ou appender.

a biblioteca oferece vários tipos de filtros que podem ser usados:

  • BurstFilter – controla o número de registo de eventos permitido
  • DynamicThresholdFilter – filtros de linhas de log com base em determinados atributos
  • RegexFilter – filtros de mensagens baseados em se eles correspondem a uma expressão regular

Você pode, por exemplo, controlar a velocidade com a qual o aplicativo é permitido o registo de dados.

A fim de fazer, você pode configurar um BurstFilter e aplicar isso às mensagens INFO:

<Filters> <BurstFilter level="INFO" rate="10" maxBurst="100"/></Filters>

isto irá ignorar selectivamente o controlo do tráfego de mensagens de nível de informação e abaixo, enquanto se assegura de que não está a perder nenhuma das mensagens mais importantes acima do INFO.

neste caso, a rate define as mensagens de logs médias que devem ser processadas por segundo, e a maxBurst controla o tamanho global da ruptura de tráfego antes do filtro começar a eliminar entradas de log.da mesma forma, podemos configurar o appender apenas para aceitar mensagens de registo que correspondam a uma expressão regular específica:

No geral, este mecanismo de filtragem pode ser usado com grande precisão para se certificar de que cada appender na sua configuração de registo global está a seguir a informação correcta. A capacidade de apenas logar informações muito específicas e relevantes geralmente leva a uma análise de causas de raiz muito rápida, especialmente em sistemas complexos – especialmente quando associado com uma poderosa ferramenta de visualização de logs.

configurar os Loggers

além do logger de raiz, também podemos definir elementos adicionais de Logger com diferentes níveis de log, adicionadores ou filtros. Cada Registrador requer um nome que pode ser usado posteriormente para a referência:

<Loggers> <Logger name="RollingFileLogger"> <AppenderRef ref="RollingFileAppender" /> </Logger></Loggers>

Para escrever mensagens de log usando este determinado Registrador, você pode obter uma referência para o LogManager classe:

Logger rfLogger = LogManager.getLogger("RollingFileLogger");rfLogger.info("User info updated");

Outra forma muito comum para estruturar a hierarquia destas madeireiros é baseado na classe Java:

Logger logger = LogManager.getLogger(MyServiceTest.class);

a Utilização de Pesquisas

as Pesquisas representam uma forma de inserir os valores externos para o log4j2 de configuração. Já vimos um exemplo da pesquisa de data na configuração Rollingfilappender:

<RollingFile name="RollingFileAppender" fileName="logs/app.log" filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">

a pesquisa ${date:YYYY-MM} irá inserir a data actual no nome do ficheiro, enquanto que o $ anterior é um carácter de escape, para inserir a expressão de procura no atributo filePattern.

Você também pode inserir propriedades do Sistema de valores em log4j2 de configuração usando o formato ${sys:property_name}:

<File name="ApplicationLog" fileName="${sys:path}/app.log"/>

Outro tipo de informação que você pode pesquisar e inserir é o ambiente Java informação:

<PatternLayout header="${java:version} - ${java:os}"> <Pattern>%d %m%n</Pattern></PatternLayout>

Você pode encontrar mais detalhes sobre o tipo de dados que você pode inserir através de pesquisas no log4j2 documentação.

configuração programática

além de arquivos de configuração, log4j2 também pode ser configurado programaticamente. Existem algumas maneiras diferentes de o fazer:

  • criar um personalizado ConfigurationFactory
  • use o Configurador de classe
  • modificar a configuração após a inicialização
  • combinar arquivos de propriedades e a programação de configuração

Vamos dar uma olhada em como configurar um layout e um appender por meio de programação:

em seguida, você pode definir um logger utilizando o LoggerConfig classe, associar o appender para ele, e atualizar a configuração:

então, você pode começar a usar o logger como de costume:

Logger pLogger = LogManager.getLogger("programmaticLogger");pLogger.info("Programmatic Logger Message");

Este estilo de API fluente pode levar a um desenvolvimento mais rápido e iteração em configurações de registro mais complexas, porque você agora está se beneficiando dos benefícios de trabalhar diretamente com o código Java.

no entanto, dado que o XML ainda pode ser mais legível e compacto, você pode muitas vezes desenvolver a configuração programaticamente e, em seguida, convertê-lo em XML quando tudo é feito.

níveis de Registo personalizados

os níveis de Registo incorporados para o log4j2 são:

  • FORA
  • FATAL
  • ERRO
  • WARN
  • INFO
  • DEBUG
  • TRACE
  • TODAS

além desses, você também pode definir um registo personalizado de nível de acordo com as suas necessidades de aplicação.

Por exemplo, para definir este novo nível de log, você pode fazer uso do nível.API forName () – especificando o novo nome do nível e um inteiro que representa o lugar do nível na hierarquia de níveis de log:

Level myLevel = Level.forName("NEW_LEVEL", 350);

Para determinar o valor inteiro para utilizar, você pode ter um olhar para os valores definidos para os outros níveis de log no log4j2 documentação:

A 350 valor coloca o nível de entre AVISAR e INFORMAÇÕES, o que significa que as mensagens que serão exibidas quando o nível é definido para INFO ou acima.

para registar uma mensagem ao nível personalizado, é necessário usar o método log ():

logger.log(myLevel, "Custom Level Message");

a configuração XML equivalente poderia ser:

<CustomLevels> <CustomLevel name="NEW_XML_LEVEL" intLevel="350" /></CustomLevels>

então pode ser usado através da log API padrão:

logger.log(Level.getLevel("NEW_XML_LEVEL"),"Custom XML Level Message");

os novos níveis personalizados serão apresentados da mesma forma que os normais:

11:28:23.558 NEW_LEVEL - Custom Level Message11:28:23.559 NEW_XML_LEVEL - Custom XML Level Message

migrando do Log4j 1.x

Se estiver a migrar uma aplicação usando o 1.versão x da biblioteca para o actual 2.X version, existem algumas rotas que você pode seguir:

  • use o log4j 1.x bridge
  • actualiza manualmente a API e a configuração

Usando a ponte é trivial. Só precisa de substituir a dependência do log4j pela biblioteca log4j-1.2-api:

embora este seja o método mais rápido, ele tem a desvantagem de ser limitado no tipo de configuração que pode ser convertido.

o método manual é, é claro, mais trabalho, mas acabará por levar a uma solução de registro mais flexível e poderosa.

Aqui estão alguns dos tipos mais comuns de mudanças que você terá que fazer:

conclusão

os arquivos de Log são críticos em qualquer ambiente de produção, e escolher uma boa solução de registro pode ser a diferença entre gastar 5 minutos e passar um dia inteiro para entender um problema na produção.

Log4j2 é uma poderosa e robusta solução de registro para aplicações Java modernas, com uma ampla gama de opções de configuração.

permite uma configuração fácil das melhores práticas avançadas de Registo, tais como ficheiros de rolamento, diferentes tipos de destinos de saída de Registo, suporte para formatos de Registo estruturados, tais como JSON ou XML, usando vários loggers e filtros, e níveis de Registo personalizados.

finalmente, quando você precisa ir além da análise manual de dados de log, verifique definitivamente as capacidades de login incluídas no Retrace APM.