Logs em Json com Micronaut e Logback
04 Mar 2022Introdução
Logs sempre foram importantes para ajudar os desenvolvedores a identificar problemas em suas aplicações quando estão rodando em ambiente produtivo.
Atualmente, com a arquitetura de microsservços, cada microsserviço emite logs nas saídas padrão do sistema operacional e essas informações são capturadas por agregadores de logs. Em aplicações monolíticas é comum que as aplicações escrevam logs em arquivos e gerenciem o tamanho e idade dos logs.
Logs no Micronaut
Segundo a documentação, Micronaut usa o SLF4J para fazer o log de mensagens. A sigla SLF4J significa Simple Logging Facade for Java, ou seja, é apenas um conjunto de interfaces que as implementações de logs usam. Dessa forma é possível escolher a implementação que será usada em seu projeto sem impactar as bibliotecas que você importou.
Micronaut usa o Logback como implementação padrão da SLF4J, por isso, quando você cria um novo projeto com Micronaut, se você olhar no diretório resources irá notar a existência de um arquivo chamado logback.xml
. Esse arquivo possui as configurações do Logback.
O Logback é uma implementação muito utilizada e nasceu para substituir o Log4j, inclusive ela foi criada pelos mesmos desenvolvedores da Log4j. Então, se você está iniciando um projeto, dê preferência para o Logback.
Configuração do Logback via XML para gerar logs em JSON
-
Adicione as dependências abaixo no arquivo
build.gradle
oubuild.gradle.kts
:runtimeOnly("ch.qos.logback.contrib:logback-json-classic:0.1.5") runtimeOnly("ch.qos.logback.contrib:logback-jackson:0.1.5")
-
Atualize o arquivo
logback.xml
que fica no diretóriosrc/main/resources
. Você precisa adicionar as configurações abaixo dentro da tagappender
:
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<jsonFormatter
class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>false</prettyPrint>
</jsonFormatter>
<timestampFormat>yyyy-MM-dd' 'HH:mm:ss.SSS</timestampFormat>
<appendLineSeparator>true</appendLineSeparator>
</layout>
Pronto! Agora os logs serão gerados no formato Json.
Como configurar o Logback programaticamente para gerar logs em JSON
-
Apague o arquivo
logback.xml
do seu projeto. -
Adicione as dependências abaixo no arquivo
build.gradle
oubuild.gradle.kts
:implementation("ch.qos.logback.contrib:logback-json-classic:0.1.5") implementation("ch.qos.logback.contrib:logback-jackson:0.1.5")
-
Crie a classe abaixo, ela será responsável pelas configurações:
package com.johnowl import ch.qos.logback.classic.Level import ch.qos.logback.classic.Logger import ch.qos.logback.classic.LoggerContext import ch.qos.logback.contrib.json.classic.JsonLayout import ch.qos.logback.classic.spi.Configurator import ch.qos.logback.classic.spi.ILoggingEvent import ch.qos.logback.contrib.jackson.JacksonJsonFormatter import ch.qos.logback.core.ConsoleAppender import ch.qos.logback.core.encoder.LayoutWrappingEncoder import ch.qos.logback.core.spi.ContextAwareBase class MyCustomJsonConfigurator : ContextAwareBase(), Configurator { override fun configure(loggerContext: LoggerContext) { val consoleAppender = ConsoleAppender<ILoggingEvent>() consoleAppender.context = loggerContext consoleAppender.name = "console" val encoder = LayoutWrappingEncoder<ILoggingEvent>() encoder.context = loggerContext val jsonFormatter = JacksonJsonFormatter() jsonFormatter.isPrettyPrint = false val layout = JsonLayout() layout.isAppendLineSeparator = true layout.timestampFormat = "yyyy-MM-dd' 'HH:mm:ss.SSS" layout.jsonFormatter = jsonFormatter layout.context = loggerContext layout.start() encoder.layout = layout consoleAppender.encoder = encoder consoleAppender.start() val rootLogger: Logger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME) rootLogger.addAppender(consoleAppender) rootLogger.level = Level.INFO } }
- Crie a estrutura de diretórios
META-INF/services
dentro do diretóriosrc/main/resources
- Adicione um arquivo chamado
ch.qos.logback.classic.spi.Configurator
no diretório recém criado. - Adicione o nome do pacote e nome da classe de configuração no arquivo que você acabou de criar, no meu caso ficou como
com.johnowl.MyCustomJsonConfigurator
.
Pronto! Agora o Logback irá gerar logs no formato Json. Caso você queira alterar o log level de algum pacote, veja no próximo capítulo como fazer isso.
Como mudar o log level de pacotes com Logback e Micronaut
Caso você esteja usando o arquivo logback.xml
, a maneira mais simples é adicionar dentro da tag configuration
uma nova tag informando o nome do pacote e o log level, veja no exemplo abaixo:
<logger name="my.package" level="debug" />
Outra forma de fazer isso é usando o arquivo de configurações do Micronaut, ele fica no diretório resources e chama application.yml. Isso é bastante útil se você escolheu usar a configuração do Logback via código. Veja abaixo um exemplo:
logger:
levels:
my.package: DEBUG
my.other.package: INFO
Conclusão
A forma de configurar o Logback tanto via XML quanto programaticamente pode ser usado em qualquer framework, isso não se limita ao Micronaut. Se quiser fazer com Spring os passos a serem seguidos serão os mesmos. Uma vantagem de gerar os logs no formato Json é facilitar sua captura por ferramentas de agregação de logs.
A forma de configuração via código pode ser útil se você quer criar uma biblioteca customizada para sua empresa. Normalmente isso não é necessário, a não ser que você tenha necessidades muito específicas no seu caso de uso.
Caso tenha dúvidas ou sugestões, utilize a caixa de comentários abaixo ou entre em contato pelo twitter em @john_owl