Olá queridos Khabrovites.
O material apresentado no artigo é destinado a iniciantes e, possivelmente, economizará várias horas de pesquisa no StackOverFlow e em outros sites, a fim de obter um sistema de registro conveniente que ele próprio entenda onde efetuar logon - no console, arquivo ou logstash.
No início do projeto, sempre surge a tarefa de configurar corretamente o log, enquanto no ambiente local os logs devem ser exibidos no console e no arquivo por conveniência durante a depuração, e é extremamente indesejável enviar os logs para o console no servidor remoto, mas eles devem ser gravados no arquivo, logstash ou no banco de dados. E se você possui o Windows localmente e em uma máquina Linux remota, o endereço do local desse arquivo de log é diferente.
Portanto, há muitas situações em que você precisa corrigir constantemente a configuração do sistema de registro com as mãos, dependendo das circunstâncias externas.
Eu estava cansado de lembrar e comentar constantemente sobre anexadores e desenvolvi uma maneira de configurar o Log4j2 para que, dependendo do perfil Maven selecionado, apenas os anexos certos fossem automaticamente ativados.
Abaixo está uma instrução para configurar um projeto usando o Spring Boot + Maven + Log4j2, cujo resultado será um sistema de log configurado e dois anexos: CONSOLE e SOCKET.
Primeiramente, faremos alterações na configuração do Maven (pom.xml):
Nas variáveis em todo o nível pom.xml, adicione o endereço do host para logstash-appender:
<properties> <logstash.host>logstashcsm.example.ru</logstash.host> </properties>
Adicione as dependências necessárias para o trabalho:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> </dependencies>
Observe que excluímos a dependência do spring-boot-starter-logging do spring-boot-starter-web.
Configure perfis do Maven para gerenciar dinamicamente os anexos conectados. No nível de cada perfil, configuramos as variáveis logstash.port, logger.console.tresholdFilter, logger.socket.tresholdFilter
.
<profiles> <profile> <id>local</id> <properties> <logstash.port>10000</logstash.port> <logger.console.tresholdFilter>ALL</logger.console.tresholdFilter> <logger.socket.tresholdFilter>OFF</logger.socket.tresholdFilter> </properties> </profile> <profile> <id>dev</id> <properties> <logstash.port>10001</logstash.port> <logger.console.tresholdFilter>OFF</logger.console.tresholdFilter> <logger.socket.tresholdFilter>ALL</logger.socket.tresholdFilter> </properties> </profile> </profiles>
logstash.port - a porta para a qual os logs devem ser enviados.
logger.console.tresholdFilter - o valor define o nível de filtragem dos logs exibidos no console. No nosso caso, ALL significa que os registros de log de todos os níveis serão exibidos no console do appender.
logger.socket.tresholdFilter - o valor define o nível de filtragem dos logs enviados para o logstash. DESLIGADO - significa que nenhum registro enviado a este aplicativo passará.
Agora precisamos fazer alterações em application.properties para que, a partir do arquivo Log4j2.xml, possamos acessar o valor das variáveis especificadas em pom.xml:
logstash.host=@logstash.host@
logstash.port=@logstash.port@
logger.console.tresholdFilter=@logger.console.tresholdFilter@
logger.socket.tresholdFilter=@logger.socket.tresholdFilter@
E, finalmente, definimos a configuração do próprio Log4j2 no arquivo log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?> <Configuration> <Properties> <Property name="socket.host">${bundle:application:logstash.host}</Property> <Property name="socket.port">${bundle:application:logstash.port}</Property> <Property name="console.thresholdFilter">${bundle:application:logger.console.tresholdFilter}</Property> <Property name="socket.thresholdFilter">${bundle:application:logger.socket.tresholdFilter}</Property> </Properties> <Appenders> <Console name="CONSOLE" target="SYSTEM_OUT"> <ThresholdFilter level="${console.thresholdFilter}"/> <PatternLayout pattern="%d %-5p [%t] %c{10} - %m%n"/> </Console> <Socket name="SOCKET" host="${socket.host}" port="${socket.port}" immediateFlush="true"> <ThresholdFilter level="${socket.thresholdFilter}"/> <JSONLayout eventEol="true" compact="true"/> </Socket> <Async name="ASYNC"> <AppenderRef ref="CONSOLE"/> <AppenderRef ref="SOCKET"/> </Async> </Appenders> <Loggers> <Logger name="ru.example" level="debug" additivity="false"> <AppenderRef ref="ASYNC"/> </Logger> <Root level="error"> <AppenderRef ref="ASYNC"/> </Root> </Loggers> </Configuration>
Agora, para chamar o criador de logs na sua classe, você precisa criar uma instância dele:
private static Logger logger = LoggerFactory.getLogger(YourClass.class);
e vire para ele:
logger.info(" ");
Isso é tudo. Agora, o registro funcionará levando em consideração o perfil do Maven que está ativo no projeto.
Observe que, na lista do arquivo log4j2.xml
, são ru.example
dois registradores - ru.example
e root
, e eles têm níveis diferentes de registro de eventos. O primeiro funcionará em todos os eventos gerados pelas classes a partir do ru.example.*
e ru.example.*
tudo no nível DEBUG, e o root
logs root
registrará eventos de absolutamente todas as classes, exceto do nível ERROR.
Ao mesmo tempo, para que as entradas não sejam duplicadas nos logs, a configuração additivity="false"
é usada.