>_ DevTrendspt

Idioma

Início

Linguagens

Seções

Frontend Backend Mobile DevOps AI / ML GameDev Blockchain Embarcados Segurança
Java

Como Parar de Reescrever Código para Logs e Métricas

Imagine o seguinte: você tem uma dúzia de microsserviços Java rodando em produção. Em algum momento, um deles começa a "travar". Você abre os logs, mas não há nada lá — as mensagens padrão não são suficientes para entender em qual etapa exata a requisição está travando. História familiar? Geralmente nesse ponto, o desenvolvedor vai até o código, decora métodos com anotações, adiciona dependências de tracing, rebuilda o projeto e faz o deploy novamente. E se houver centenas de serviços escritos em diferentes frameworks?

No ecossistema OpenTelemetry, existe um projeto que resolve esse problema de forma elegante e, o que é especialmente bom, quase sem esforço. Este é o opentelemetry-java-instrumentation. É um agente Java especial que pode se injetar na sua aplicação "on the fly" e coletar telemetria sem uma única linha de novo código.

O Que É Esse Agente e Por Que Você Precisa Dele

Essencialmente, é um arquivo JAR que você anexa ao iniciar a JVM. Ele usa injeção dinâmica de bytecode. Quando sua aplicação carrega classes de bibliotecas populares (por exemplo, Spring, Hibernate, gRPC ou Kafka), o agente injeta cuidadosamente lógica para criação de spans e coleta de métricas.

Esta é uma opção ideal para dois cenários. Primeiro, quando você precisa adicionar rapidamente observabilidade a um projeto legado que dá medo de mexer. Segundo, quando você quer padronizar a coleta de dados em toda a empresa sem fazer cada equipe configurar manualmente o SDK.

Três Recursos Legais Que Facilitam a Vida

Magia Automática Pronta para Usar

O agente suporta um número enorme de bibliotecas. Se você usa uma stack padrão como Spring Boot com PostgreSQL e Redis, não precisa configurar nada. Você apenas anexa o agente e, no seu sistema de monitoramento (por exemplo, Jaeger ou Zipkin), obtém uma árvore de chamadas: desde a requisição HTTP recebida até a query no banco de dados e resposta do cache.

Propagando Contexto para os Logs (MDC)

Uma das coisas mais úteis no dia a dia do debugging é a inserção automática do Trace ID nos logs. O agente consegue encontrar seus loggers (Logback, Log4j2) por conta própria e adicionar o identificador do trace atual no MDC. Agora, quando você vê um erro nos logs, pode simplesmente copiar o ID e encontrar todo o caminho daquela requisição em todos os serviços. Acabou-se o chute de qual usuário disparou aquele NullPointerException.

Configuração Flexível Sem Rebuild

Todos os parâmetros — para onde enviar dados, com que frequência fazer sample, quais atributos adicionar aos spans — são passados através de variáveis de ambiente ou propriedades do sistema Java. Isso significa que o mesmo binário da sua aplicação pode enviar dados para o console no dev e para um cluster pesado do OpenTelemetry Collector em produção.

Como Colocar Isso Para Funcionar

O processo de configuração é surpreendentemente simples. Primeiro, baixe a versão mais recente do opentelemetry-javaagent.jar na página de releases. Depois adicione uma flag ao comando de inicialização da sua aplicação:

java -javaagent:path/to/opentelemetry-javaagent.jar \
     -Dotel.resource.attributes=service.name=my-cool-service \
     -jar myapp.jar

Por padrão, o agente espera que um collector aceitando dados via protocolo OTLP esteja rodando em algum lugar no localhost:4318. Se você quiser usar outra coisa, por exemplo o Zipkin, basta mudar com uma flag: -Dotel.traces.exporter=zipkin.

Por Trás dos Panos e Extensibilidade

Curiosamente, o projeto não te limita apenas à "automação". Se as funcionalidades embutidas não forem suficientes, você pode usar o mecanismo de extensões. Você pode escrever seu próprio arquivo JAR que adicionará regras de instrumentação customizadas ou atributos específicos da empresa.

Para aqueles que não confiam nada na magia do agente, o projeto também distribui as mesmas bibliotecas de instrumentação separadamente. Você pode adicioná-las como dependências regulares e configurá-las manualmente, mas aí terá que aceitar a necessidade de modificar o código.

Vale a Pena Usar?

Eu frequentemente encontro a opinião de que agentes Java são uma "caixa preta" que pode deixar a aplicação mais lenta. Há alguma verdade nisso: o agente realmente gasta recursos com transformação de bytecode na inicialização e adiciona uma pequena sobrecarga na execução das requisições. Porém, em 95% dos casos, essa sobrecarga é insignificante comparada ao benefício que você obtém quando está caçando bugs em um sistema distribuído.

A quem vai servir especialmente bem:

  1. Times migrando para microsserviços e se afogando sem tracing.
  2. Suporte que precisa de "ontem" para entender por que o monolith antigo está lento.
  3. Arquitetos implementando um padrão unificado de monitoramento.

Se você ainda não experimentou o OpenTelemetry nos seus projetos Java, esse agente é a forma mais rápida e menos dolorosa de começar. Basta rodar localmente e ver quanta coisa interessante você aprende sobre o comportamento do seu código sob carga.

Projetos relacionados