Monitoramento e Logging Kotlin: Como não perder bugs em produção

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Por que uma aplicação Kotlin "silenciosa" é uma bomba-relógio

\n\n

Imagine: você colocou um serviço em Kotlin no ar, ele funciona perfeitamente. Os usuários estão satisfeitos, as métricas estão verdes. Mas um belo dia, a carga aumenta, a latência dispara, e você não faz ideia do porquê. Sem logging e monitoramento, você é um capitão de navio sem mapa e radar. Neste artigo, vamos mostrar como transformar sua aplicação de uma "caixa-preta" em um sistema transparente, onde cada falha fica visível a olho nu.

\n\n

Não vamos apenas copiar a documentação. Em vez disso, traremos casos reais, snippets prontos e soluções arquiteturais que funcionam em produção. Vamos nessa.

\n\n

Dividindo o problema: logging vs monitoramento

\n\n

Antes de escrever código, vamos alinhar os conceitos. Logging é o registro de eventos (erros, avisos, informações de depuração) em formato estruturado ou textual. Monitoramento é a coleta de métricas (tempo de resposta, número de requisições, uso de CPU) e sua visualização. Idealmente, eles trabalham juntos: logs são para análise profunda de incidentes, métricas são para detecção rápida de anomalias.

\n\n

Configurando logging em Kotlin: do básico ao avançado

\n\n

Escolhendo a biblioteca: SLF4J + Logback — o padrão ouro

\n\n

Kotlin se integra perfeitamente com o ecossistema Java, então SLF4J (fachada) e Logback (implementação) são a escolha número 1. Eles são leves, performáticos e suportam logging assíncrono.

\n\n

Adicione ao build.gradle.kts:

\n\n
implementation("ch.qos.logback:logback-classic:1.4.14")\nimplementation("io.github.microutils:kotlin-logging-jvm:3.0.5")
\n\n

kotlin-logging é uma camada fina sobre o SLF4J que deixa o código mais limpo. Compare:

\n\n

Sem a biblioteca:

\n
private val logger = LoggerFactory.getLogger(MyService::class.java)\nlogger.info("User {} logged in", userId)
\n\n

Com kotlin-logging:

\n
private val logger = KotlinLogging.logger {}\nlogger.info { "User $userId logged in" }
\n\n

A avaliação preguiçosa da string é um bônus para performance: a string só será montada se o nível de logging estiver ativo.

\n\n

Configuração do Logback: logs estruturados são obrigatórios

\n\n

Crie o arquivo logback.xml em src/main/resources:

\n\n
<configuration>\n    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">\n        <encoder class="net.logstash.logback.encoder.LogstashEncoder"/>\n    </appender>\n\n    <root level="INFO">\n        <appender-ref ref="CONSOLE"/>\n    </root>\n</configuration>
\n\n

Estamos usando o LogstashEncoder — ele transforma os logs em JSON. Isso é essencial se você envia logs para Elasticsearch, Loki ou qualquer outro agregador. Logs em JSON são fáceis de parsear, filtrar e analisar.

\n\n

Não esqueça de adicionar a dependência:

\n
implementation("net.logstash.logback:logstash-logback-encoder:7.4")
\n\n

Escrevendo logs com significado: contexto é tudo

\n\n

Logs como "Ocorreu um erro" são inúteis. Adicione o MDC (Mapped Diagnostic Context) — é como colocar tags nos seus logs.

\n\n
import org.slf4j.MDC\n\nclass OrderService {\n    private val logger = KotlinLogging.logger {}\n\n    fun processOrder(orderId: String, userId: String) {\n        MDC.put("orderId", orderId)\n        MDC.put("userId", userId)\n        try {\n            logger.info { "Processando pedido" }\n            // lógica de negócio\n        } catch (e: Exception) {\n            logger.error(e) { "Falha ao processar pedido" }\n        } finally {\n            MDC.clear()\n        }\n    }\n}
\n\n

Agora, no seu agregador de logs, você consegue encontrar todos os registros de um pedido ou usuário específico em segundos.

\n\n

Monitoramento de aplicações Kotlin:

Blogs

Book Recommendations