Pular para o conteúdo

Instrumentação Automática vs Manual

Uma das primeiras decisões ao adotar o OpenTelemetry é escolher entre instrumentação automática e manual — ou uma combinação das duas. Cada abordagem tem seus pontos fortes e fracos, e a escolha certa depende do seu contexto.

A instrumentação automática (ou auto-instrumentação) injeta código de telemetria automaticamente em bibliotecas e frameworks populares, sem que você precise modificar o código da sua aplicação.

Dependendo da linguagem, a auto-instrumentação usa diferentes mecanismos:

LinguagemMecanismo
JavaAgente Java (bytecode manipulation)
.NETBibliotecas de instrumentação via DI
Pythonopentelemetry-instrument (monkey patching)
Node.jsMódulos de instrumentação automática
GoNão tem auto-instrumentação — instrumentação manual via bibliotecas
  • Zero alteração no código — especialmente em Java, basta adicionar o agente
  • Cobertura ampla — instrumenta HTTP, banco de dados, mensageria, cache de uma vez
  • Rápido para começar — resultados em minutos
  • Mantido pela comunidade — as instrumentações são atualizadas quando bibliotecas mudam
  • Spans genéricos — os spans gerados refletem operações de infraestrutura (HTTP request, SQL query), não a lógica de negócio
  • Ruído — pode gerar muitos spans que você não precisa
  • Menos controle — difícil customizar atributos ou filtrar spans específicos
  • Overhead — em alguns casos, a auto-instrumentação pode adicionar overhead de performance

Use instrumentação automática quando:

  • Está começando com OpenTelemetry e quer resultados rápidos
  • Quer visibilidade básica de infraestrutura (HTTP, DB, cache)
  • O time não tem experiência com instrumentação
  • Está avaliando o OpenTelemetry em um projeto existente

A instrumentação manual significa adicionar código explícito para criar spans, registrar métricas e emitir logs nos pontos que você escolher.

from opentelemetry import trace
tracer = trace.get_tracer("meu-servico")
def processar_pedido(pedido):
with tracer.start_as_current_span("processar_pedido") as span:
span.set_attribute("pedido.id", pedido.id)
span.set_attribute("pedido.valor", pedido.valor_total)
span.set_attribute("pedido.itens", len(pedido.itens))
validar_estoque(pedido)
calcular_frete(pedido)
processar_pagamento(pedido)
  • Spans significativos — representam operações de negócio, não apenas infraestrutura
  • Atributos relevantes — você escolhe exatamente quais dados associar aos spans
  • Controle total — decida onde instrumentar e com qual nível de detalhe
  • Melhor depuração — traces contam a história do que aconteceu no seu domínio
  • Mais trabalho — requer escrever e manter código de instrumentação
  • Precisa de conhecimento — o time precisa entender como OTel funciona
  • Risco de inconsistência — sem padrões claros, cada dev instrumenta de um jeito

Use instrumentação manual quando:

  • Precisa de visibilidade da lógica de negócio
  • Quer spans que representem operações do seu domínio
  • Precisa de atributos específicos nos spans (IDs de pedido, dados do cliente, etc.)
  • Quer controlar o nível de detalhe da telemetria

Na prática, a maioria dos times acaba usando as duas abordagens juntas:

┌─────────────────────────────────────┐
│ Instrumentação Automática │
│ → HTTP, banco de dados, cache, │
│ mensageria, gRPC │
├─────────────────────────────────────┤
│ Instrumentação Manual │
│ → Lógica de negócio, operações │
│ específicas do domínio │
└─────────────────────────────────────┘
  1. Comece com auto-instrumentação — ative para ter visibilidade básica imediatamente
  2. Identifique gaps — olhe os traces e veja onde falta contexto de negócio
  3. Adicione spans manuais — instrumente as operações de negócio mais importantes
  4. Enriqueça com atributos — adicione dados do domínio aos spans (IDs, status, valores)
  5. Itere — à medida que precisa de mais visibilidade, adicione mais instrumentação manual
[auto] HTTP POST /api/pedidos (200ms)
└── [manual] processar_pedido (180ms)
├── [manual] validar_estoque (20ms)
│ └── [auto] SQL SELECT estoque... (5ms)
├── [manual] calcular_frete (30ms)
│ └── [auto] HTTP GET api-correios... (25ms)
└── [manual] processar_pagamento (120ms)
├── [auto] HTTP POST gateway-pagamento... (100ms)
└── [auto] SQL INSERT pagamento... (10ms)

Neste exemplo, a auto-instrumentação captura as chamadas HTTP e SQL, enquanto a instrumentação manual adiciona contexto de negócio (processar pedido, validar estoque, etc.).

Antes de sair instrumentando, combine com o time como nomear spans e atributos. Veja nosso guia de Convenções de Nomes.

Mais spans nem sempre é melhor. Foque nas operações que:

  • São frequentes e/ou lentas
  • Representam pontos de decisão de negócio
  • Cruzam limites de serviço
  • São difíceis de depurar quando falham

Se a auto-instrumentação gera spans demais, use o Collector para filtrar e amostrar em vez de desativar a instrumentação.

Especialmente com auto-instrumentação em linguagens interpretadas (Python, Node.js), meça o impacto no desempenho em um ambiente de staging antes de ir para produção.

Discussão

Tem alguma dúvida ou quer compartilhar sua experiência? Comente abaixo!