Instrumentação Java com Elven Observability

Guia completo para adicionar traces, métricas e correlação de logs às aplicações Java usando a distribuição OpenTelemetry da Elven.


Sumário

  • Visão geral

  • Pré-requisitos

  • Caminho recomendado

  • Quick Start — Docker + ENV (zero-code recomendado)

  • Pacotes disponíveis

  • Quick Start — Java Agent embedded sem Docker

  • Quick Start — Java Agent oficial com extensão Elven

  • Quick Start — Spring Boot Starter

  • Quick Start — Inicialização manual

  • Configuração por variáveis de ambiente

  • Deploy com Docker — variações

  • Logs e correlação com Loki

  • Traces manuais, erros e atributos semânticos

  • Métricas manuais

  • Instrumentações automáticas

  • Configuração por arquivo

  • Privacidade e dados sensíveis

  • Boas práticas para SaaS multi-tenant

  • Validação ponta a ponta

  • Troubleshooting

  • FAQ


Visão geral

A instrumentação Java da Elven é uma distribuição OpenTelemetry para aplicações Java 11+. Ela usa o Java Agent oficial do OpenTelemetry para auto-instrumentação e aplica os padrões da Elven para o stack LGTM.

O Collector OTLP fica sempre no ambiente do cliente. A aplicação envia traces e métricas para esse Collector local/do cliente, e o Collector encaminha os dados para Tempo e Mimir conforme a arquitetura contratada.

  • Grafana Tempo para traces

  • Grafana Mimir para métricas

  • Grafana Loki para logs, via logs-interceptor-java

  • Grafana para consulta, correlação, painéis e alertas

Componente
O que faz

elven-opentelemetry-instrumentation-javaagent

Java agent embedded: agent oficial + extensão Elven no mesmo JAR. É o modo zero-code mais simples.

elven-opentelemetry-instrumentation-javaagent-extension

Extensão Elven para usar junto com o Java agent oficial via OTEL_JAVAAGENT_EXTENSIONS.

elven-opentelemetry-instrumentation-core

API manual: Observability, GlobalObservability, TracerFacade, MetricFacade e LogCorrelation.

elven-opentelemetry-instrumentation-spring-boot-starter

Auto-configuração para Spring Boot quando a aplicação precisa inicializar a SDK no próprio processo.

elven-opentelemetry-instrumentation-autoconfigure

Defaults Elven via SPI do OpenTelemetry SDK. Usado pelo agent e por cenários avançados.

elven-opentelemetry-instrumentation-bom

Alinhamento de versões Maven.

logs-interceptor-java

Biblioteca separada para envio de logs ao Loki. Esta doc mostra como correlacionar logs com traces.

Recomendação: para aplicações web, APIs, workers com HTTP/JDBC/messaging e serviços já existentes, use o Java Agent embedded. Ele entrega auto-instrumentação sem alterar o código da aplicação.


Pré-requisitos

  • Java 11+

  • Maven ou Gradle para aplicações que usam dependências da API manual

  • Endpoint do Collector OTLP implantado no ambiente do cliente

  • Credenciais da Elven Observability:

    • Tenant ID

    • API Token

    • Endpoint do Collector OTLP do cliente para traces e métricas

    • Endpoint Loki para logs, quando usar logs-interceptor-java

Baseline técnico

Item
Versão

Java mínimo

Java 11

OpenTelemetry SDK BOM

1.61.0

OpenTelemetry Java Agent

2.27.0

OpenTelemetry Instrumentation BOM

2.27.0

Semantic Conventions

1.41.0

Versão atual da lib Elven

0.1.1

Protocolos suportados

Protocolo
Valor
Uso recomendado

OTLP HTTP/protobuf

http/protobuf

Padrão recomendado para ambientes HTTP, proxies e gateways.

OTLP gRPC

grpc

Útil quando o Collector do cliente aceita gRPC.

Para métricas, envie OTLP para o Collector do cliente. O Collector faz a tradução para Mimir/Prometheus remote write quando necessário.


Caminho recomendado

A ordem recomendada de adoção é sempre começar pelo caminho de menor atrito:

Prioridade
Caminho
Quando usar

1

Docker + ENV + Java Agent embedded

Caminho padrão para clientes. Zero-code, previsível e fácil de aplicar em serviços existentes.

2

JAVA_TOOL_OPTIONS em VM/ECS/serviço já empacotado

Quando a aplicação não é rebuildada em Docker, mas permite variáveis de ambiente no runtime.

3

Java Agent oficial + extensão Elven

Quando a empresa já padronizou o opentelemetry-javaagent.jar oficial e quer só acoplar os defaults Elven.

4

Spring Boot Starter / API manual

Quando a aplicação precisa criar spans/métricas de negócio, controlar lifecycle ou inicializar a SDK por código.

5

Configuração por arquivo

Quando o ambiente exige arquivo versionado ou montado por secret/config.

Para a maioria dos clientes, o fluxo é:


Quick Start — Docker + ENV (zero-code recomendado)

Este é o caminho padrão para aplicações Java em container. Não exige alteração no código da aplicação.

1. Adicione o Java Agent no Dockerfile

2. Configure as variáveis no runtime

3. Configure logs quando precisar enviar para Loki

A instrumentação Java envia traces e métricas. Logs continuam com o logs-interceptor-java, mantendo correlação por trace_id e span_id.

4. Valide o startup

No log da aplicação, confirme que o agent iniciou:

Depois gere uma request e valide service.name no Tempo.


Pacotes disponíveis

Maven com BOM

Use o BOM para travar as versões de todos os artefatos Elven:

API manual

Spring Boot Starter

SDK autoconfigure

Use em cenários avançados nos quais a aplicação já usa AutoConfiguredOpenTelemetrySdk:

Gradle

Ou sem plugin de dependency management:


Quick Start — Java Agent embedded sem Docker

Use este modo quando a aplicação roda em VM, ECS task customizada, systemd, serviço gerenciado ou qualquer runtime em que você consegue adicionar arquivos e variáveis de ambiente, mas não quer alterar o Dockerfile.

1. Baixe o agent embedded

2. Configure as variáveis de ambiente

3. Inicie a aplicação com JAVA_TOOL_OPTIONS

Pronto. A aplicação passa a gerar spans automaticamente para frameworks, HTTP, banco, mensageria e bibliotecas suportadas pelo Java Agent oficial.


Quick Start — Java Agent oficial com extensão Elven

Use este modo quando o ambiente já padroniza o JAR oficial opentelemetry-javaagent.jar e você quer carregar apenas a extensão Elven.

1. Baixe o Java Agent oficial

2. Baixe a extensão Elven

3. Configure agent + extensão

Use um formato de agent por processo: embedded ou oficial + extensão. Não combine os dois no mesmo JAVA_TOOL_OPTIONS.


Quick Start — Spring Boot Starter

Use o starter quando você quer inicializar a SDK no processo da aplicação via Spring Boot.

Para auto-instrumentação profunda de HTTP/JDBC/frameworks, o Java Agent continua sendo o modo recomendado. O starter é útil para aplicações que preferem bootstrap explícito, custom spans, custom metrics e lifecycle integrado ao contexto Spring.

1. Adicione o BOM e o starter

2. Configure o ambiente

3. Injete ObservabilityHandle quando precisar de spans ou métricas manuais

4. Configuração Spring opcional

Variáveis equivalentes:


Quick Start — Inicialização manual

Use este modo para jobs, aplicações console, serviços sem Spring ou cenários em que você precisa controlar a inicialização por código.

1. Adicione a dependência

2. Inicialize a partir das variáveis de ambiente

3. Ou inicialize com builder explícito

Precedência de configuração

A resolução segue esta ordem:

Exemplo com system properties:


Configuração por variáveis de ambiente

Identidade do serviço

Variável
Descrição
Default

OTEL_SERVICE_NAME

Nome do serviço. Deve ser estável e único por aplicação.

unknown-service

OTEL_SERVICE_VERSION

Versão da aplicação.

0.0.0

OTEL_SERVICE_NAMESPACE

Domínio, produto ou agrupador lógico.

OTEL_DEPLOYMENT_ENVIRONMENT

Ambiente: production, staging, development.

OTEL_RESOURCE_ATTRIBUTES

Atributos extras no formato key=value,key2=value2.

Exemplo:

Export OTLP

Variável
Descrição
Default

OTEL_EXPORTER_OTLP_ENDPOINT

Endpoint base OTLP. Em HTTP/protobuf, a lib deriva /v1/traces e /v1/metrics.

http://localhost:4318

OTEL_EXPORTER_OTLP_TRACES_ENDPOINT

Endpoint específico de traces.

Derivado do endpoint base

OTEL_EXPORTER_OTLP_METRICS_ENDPOINT

Endpoint específico de métricas.

Derivado do endpoint base

OTEL_EXPORTER_OTLP_PROTOCOL

http/protobuf ou grpc.

http/protobuf

OTEL_EXPORTER_OTLP_HEADERS

Headers em key=value,key2=value2.

OTEL_EXPORTER_OTLP_COMPRESSION

gzip ou none.

none na API manual; gzip pode ser definido no ambiente

OTEL_EXPORTER_OTLP_TIMEOUT

Timeout em milissegundos.

30000

OTEL_EXPORTER_OTLP_INSECURE

Permitir transporte inseguro em gRPC quando aplicável.

false

Sinais

Variável
Descrição
Default

OTEL_TRACES_EXPORTER

Exporter de traces: otlp, console ou none.

otlp

OTEL_METRICS_EXPORTER

Exporter de métricas: otlp, console ou none.

otlp

OTEL_LOGS_EXPORTER

Exporter de logs OpenTelemetry.

none

OTEL_TRACING_ENABLED

Liga/desliga tracing na API manual.

Conforme exporter

OTEL_METRICS_ENABLED

Liga/desliga métricas na API manual.

Conforme exporter

A lib Java da Elven não exporta logs via OpenTelemetry. Logs devem ser enviados pelo logs-interceptor-java ou pela pipeline de logs da aplicação.

Sampling e propagação

Variável
Descrição
Default

OTEL_PROPAGATORS

Propagadores de contexto.

tracecontext,baggage

OTEL_TRACES_SAMPLER

Sampler de traces.

parentbased_traceidratio

OTEL_TRACES_SAMPLER_ARG

Taxa de sampling entre 0.0 e 1.0.

1

OTEL_METRIC_EXPORT_INTERVAL

Intervalo de export de métricas em ms.

60000

OTEL_METRIC_EXPORT_TIMEOUT

Timeout de export de métricas em ms.

30000

Exemplos:

Privacy Elven

Variável
Descrição
Default

OTEL_ELVEN_PRIVACY_REDACT_DB_STATEMENT

Redactar db.statement e texto de queries por padrão.

true

OTEL_ELVEN_PRIVACY_HASH_USER_ID

Converter identidade de usuário para hash/pseudônimo.

true

OTEL_ELVEN_PRIVACY_REDACT_URL_CREDENTIALS

Remover credenciais e segredos de URLs.

true

OTEL_ELVEN_PRIVACY_REDACT_HEADERS

Redactar headers sensíveis.

true

OTEL_ELVEN_PRIVACY_REDACT_PAYLOADS

Redactar atributos com payloads/mensagens sensíveis.

true

OTEL_ELVEN_PRIVACY_ALLOW_RAW_ATTRIBUTES

Lista de atributos que podem sair sem redaction.

OTEL_ELVEN_AUTO_SHUTDOWN

Registrar shutdown hook automático.

true

OTEL_ELVEN_CONFIG_FILE

Caminho de arquivo .properties, .yaml ou .yml.

Exemplo para uma investigação temporária de SQL:

Use allowlist de atributos crus apenas por tempo limitado e com aprovação do time responsável por segurança/dados.

Java Agent

Variável
Descrição

JAVA_TOOL_OPTIONS

Injeta -javaagent:/path/agent.jar sem alterar o comando original da aplicação.

OTEL_JAVAAGENT_EXTENSIONS

Caminho do JAR de extensão quando usar o agent oficial.

OTEL_JAVAAGENT_DEBUG

Habilita debug do Java Agent. Use apenas em troubleshooting.

OTEL_JAVAAGENT_LOGGING

Estratégia de logs internos do agent. Padrão Elven: simple.

OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED

Liga/desliga instrumentações por padrão.

OTEL_INSTRUMENTATION_<NOME>_ENABLED

Liga/desliga uma instrumentação específica do agent.

Exemplos:


Deploy com Docker — variações

Dockerfile — app com JAR pronto

Credenciais e endpoints devem entrar no runtime, nunca hardcoded no Dockerfile:

Dockerfile multi-stage com Maven

Dockerfile usando Maven para copiar o agent

Útil quando o build já usa Maven e você quer evitar URLs no Dockerfile:

docker-compose.yml


Logs e correlação com Loki

Esta lib não cria pipeline de exportação de logs OpenTelemetry. Ela fornece correlação com trace_id, span_id e trace_flags, para que os logs enviados ao Loki possam ser relacionados com traces no Tempo.

Use logs-interceptor-java para envio ao Loki.

Dependências de logs

Exemplo com Logback:

Substitua VERSAO_PUBLICADA_DA_LIB_DE_LOGS pela versão vigente do logs-interceptor-java disponibilizada pela Elven no gerenciador de pacotes usado pelo cliente.

Variáveis de logs

Correlação manual com MDC

Pattern Logback local

Mesmo quando o envio ao Loki é feito por appender dedicado, manter trace_id e span_id no console ajuda no troubleshooting:

Como a correlação aparece

Um log correlacionado deve carregar:

No Grafana, use trace_id para navegar de Loki para Tempo.


Traces manuais, erros e atributos semânticos

O Java Agent cria spans automaticamente para bibliotecas suportadas. Use a API manual para eventos de negócio e spans que só a aplicação conhece.

Span simples

Registrar exceções

O helper recordException() adiciona:

  • evento de exception no span

  • status ERROR

  • atributo error.type

Usuário final com privacidade

Prefira enduser.pseudo.id em vez de enduser.id.

Isso gera um identificador pseudonimizado, adequado para correlação sem expor o ID bruto do usuário.

Quando usar atributos crus

Evite:

Use apenas quando houver política explícita e allowlist:


Métricas manuais

Use métricas manuais para indicadores de negócio, filas, batches e estados internos que não aparecem automaticamente.

Counter

Histogram

UpDownCounter

Gauge

Cuidados de cardinalidade

Evite labels com alta cardinalidade:

Prefira labels com cardinalidade controlada:


Instrumentações automáticas

O Java Agent oficial instrumenta automaticamente bibliotecas e frameworks comuns. A lista exata evolui com o OpenTelemetry Java Agent, mas os grupos mais importantes são:

Categoria
Exemplos

HTTP server

Servlet, Spring MVC, Spring WebFlux, JAX-RS, Jetty, Tomcat, Undertow, Netty

HTTP client

Java HttpClient, Apache HttpClient, OkHttp, Spring RestTemplate, WebClient

Banco de dados

JDBC, HikariCP, PostgreSQL, MySQL, MariaDB, Oracle, SQL Server

Messaging

Kafka, RabbitMQ, JMS, AWS SQS/SNS em bibliotecas suportadas

Cache/datastores

Redis, MongoDB, Cassandra, Elasticsearch em versões suportadas

Frameworks

Spring Boot, Micronaut, Quarkus, Dropwizard em cenários suportados

Logging

Correlação com frameworks suportados pelo agent e MDC quando aplicável

GraphQL

GraphQL Java em versões suportadas pelo agent

Habilitar/desabilitar instrumentações

SQL statements

Por padrão, a Elven aplica redaction em statements SQL:

Para investigar um problema específico, habilite temporariamente:

Volte para o padrão seguro ao terminar a análise.


Configuração por arquivo

Além de variáveis de ambiente e system properties, a API manual aceita arquivo .properties, .yaml ou .yml.

Usando variável

Usando builder

Exemplo .properties

Exemplo .yaml


Privacidade e dados sensíveis

Os defaults da Elven são privacy-first. A instrumentação assume que aplicações podem carregar dados pessoais, tokens, cookies, queries sensíveis e payloads de negócio.

Redactado por padrão

  • db.statement

  • db.query.text

  • credenciais em URL

  • query params com tokens/secrets

  • headers de autenticação

  • cookies

  • payloads e atributos com aparência de corpo de mensagem

  • user.id e enduser.id vindos de dependências legadas ou customizadas

Identidade de usuário

Use:

Evite:

Permitir atributo cru

Use somente em ambientes controlados ou janelas curtas de diagnóstico.

Headers

Nunca coloque tokens diretamente em OTEL_RESOURCE_ATTRIBUTES. Para autenticação OTLP, use:

E mantenha esses valores em secret manager, variável segura do runtime ou ferramenta equivalente.


Boas práticas para SaaS multi-tenant

Identidade do serviço

Use nomes estáveis:

Exemplos:

Tenant routing

O roteamento de tenant deve ficar no header do transporte ou no Collector do cliente:

Atributos de tenant

Para spans, use atributos de tenant apenas quando eles forem necessários para investigação:

Para métricas, tenha cuidado redobrado. tenant.id como label pode explodir cardinalidade em SaaS com muitos clientes.

Prefira métricas agregadas por dimensões controladas:

Logs

No Loki, labels devem ser de baixa cardinalidade:

Evite labels como:

Esses valores devem ir no corpo do log, não como label indexado.

Sampling

Para serviços críticos ou baixo volume:

Para alto volume:

Em incidentes, aumente temporariamente a taxa do serviço afetado.


Validação ponta a ponta

1. Verifique o log de startup

Com Java Agent, procure por mensagens indicando que o agent iniciou:

Se OTEL_JAVAAGENT_DEBUG=true, o agent mostra mais detalhes das instrumentações carregadas.

2. Gere tráfego

3. Verifique traces

No Grafana Tempo:

  • filtre por service.name="checkout-api"

  • confirme spans HTTP server/client

  • confirme spans JDBC ou messaging quando a aplicação usar essas bibliotecas

  • abra erros e confirme exception events

4. Verifique métricas

No Grafana/Mimir:

  • procure métricas runtime/processo geradas pelo agent

  • procure métricas manuais criadas por MetricFacade

  • valide labels de baixa cardinalidade

Exemplos de nomes manuais:

5. Verifique logs correlacionados

No Loki:

Depois copie o trace_id e procure o trace correspondente no Tempo.

6. Valide redaction

Confirme que dados sensíveis não aparecem crus:

  • tokens em URL devem aparecer como redigidos

  • headers de auth não devem aparecer em claro

  • db.statement deve estar redigido quando OTEL_ELVEN_PRIVACY_REDACT_DB_STATEMENT=true

  • IDs de usuário devem aparecer como enduser.pseudo.id, não enduser.id


Troubleshooting

Traces não aparecem

  1. Confirme que o agent está carregado:

  2. Verifique se existe -javaagent:/caminho/agent.jar.

  3. Confirme OTEL_SERVICE_NAME.

  4. Confirme OTEL_TRACES_EXPORTER=otlp.

  5. Confirme OTEL_EXPORTER_OTLP_ENDPOINT ou OTEL_EXPORTER_OTLP_TRACES_ENDPOINT.

  6. Verifique headers:

  7. Habilite debug temporariamente:

Métricas não aparecem

  1. Confirme OTEL_METRICS_EXPORTER=otlp.

  2. Confirme que o endpoint OTLP aceita /v1/metrics.

  3. Verifique OTEL_METRIC_EXPORT_INTERVAL; o default é 60000 ms.

  4. Confirme que o Collector do cliente encaminha métricas para Mimir.

  5. Evite testar e encerrar a aplicação antes do primeiro ciclo de export. Para jobs curtos, chame forceFlush() antes de finalizar.

Logs não aparecem no Loki

  1. Confirme que logs-interceptor-java está instalado/configurado.

  2. Confirme as variáveis:

  3. Confirme que a aplicação realmente emite logs.

  4. Confirme que o appender/agent de logs está ativo.

  5. Se traces aparecem mas logs não, o problema está na pipeline de logs, não na instrumentação OpenTelemetry.

Logs aparecem sem trace_id

  1. Confirme que o log foi emitido dentro de um span ativo.

  2. Em spans manuais, use:

  3. Confirme que o pattern/appender captura MDC.

  4. Em chamadas assíncronas, confirme que o contexto OpenTelemetry está sendo propagado para a thread.

JDBC não gera spans

  1. Confirme que a aplicação está rodando com Java Agent.

  2. Confirme que a dependência JDBC está em versão suportada pelo agent.

  3. Confirme que a conexão passa por java.sql/JDBC ou pool suportado.

  4. Verifique se a instrumentação foi desabilitada:

  5. Habilite debug temporariamente para ver decisões do agent.

db.statement não aparece

Por padrão, a Elven redacta SQL para evitar vazamento de dados.

Para diagnóstico temporário:

Depois volte:

Erro de endpoint OTLP inválido

Sintomas comuns:

Verifique:

O endpoint precisa ter scheme e host (http:// ou https://).

Erro em headers OTLP

Formato correto:

Formato inválido:

Cada item precisa estar no formato key=value.

Sampling inválido

OTEL_TRACES_SAMPLER_ARG precisa estar entre 0.0 e 1.0:

Valores como 25, 100 ou -1 são inválidos.

Aplicação não inicia com agent

  1. Confirme que o JAR existe:

  2. Confirme permissão de leitura.

  3. Confirme que a imagem usa Java 11+.

  4. Confirme que há apenas um -javaagent OpenTelemetry no processo.

  5. Rode localmente com debug:

Duplicate SDK setup

Se a aplicação já registra GlobalOpenTelemetry, a API manual reutiliza a instância global quando possível. Evite inicializar múltiplas SDKs no mesmo processo.

Boas práticas:

  • com Java Agent, não chame outro bootstrap OpenTelemetry concorrente

  • com Spring Boot Starter, deixe apenas um bean ObservabilityHandle

  • em testes, isole processos ou use reset apenas em contexto de teste


FAQ

Preciso alterar código para usar a lib?

Não no modo Java Agent embedded. Basta adicionar o JAR e configurar JAVA_TOOL_OPTIONS + variáveis de ambiente.

A lib envia logs para Loki?

Não diretamente. Ela configura traces, métricas e correlação de logs. Para envio de logs ao Loki, use logs-interceptor-java.

Posso usar só a API manual sem Java Agent?

Sim. Nesse modo você consegue criar spans e métricas manuais, configurar SDK e exportar OTLP. Para auto-instrumentação completa de HTTP, JDBC e frameworks, use o Java Agent.

Posso usar Java Agent e Spring Boot Starter juntos?

Pode, mas normalmente não é necessário. Em aplicações Spring Boot, prefira:

  • Java Agent para auto-instrumentação zero-code

  • Starter/API manual apenas quando precisar de ObservabilityHandle, spans manuais ou métricas manuais

Evite criar duas SDKs OpenTelemetry concorrentes.

Qual endpoint devo usar?

Na maioria dos ambientes, use o endpoint do Collector OTLP implantado no cliente:

Se usar endpoints separados:

Como vejo SQL statements?

Por padrão eles são redigidos. Para diagnóstico temporário:

Use com cuidado e volte ao padrão seguro depois.

Como correlaciono Loki e Tempo?

Garanta que logs tenham trace_id e span_id.

Com spans manuais, use:

Com logs-interceptor-java, o MDC é enviado junto no corpo do log.

Qual versão devo usar?

Use:

com groupId:

e artifact principal:


Checklist de deploy

Last updated

Was this helpful?