Se a sua aplicação está crescendo, mas os incidentes também, este guia mostra como sair do escuro e ganhar visibilidade concreta do seu stack usando OpenTelemetry, Prometheus, Grafana e Jaeger. Em 2026, observabilidade não é luxo: é o GPS que evita que a equipe dirija às cegas. Aqui você encontra um passo a passo prático para instrumentar métricas, logs e traces, configurar o OpenTelemetry Collector e visualizar no Prometheus, Grafana e Jaeger, com dicas de arquitetura, armadilhas reais e padrões que funcionam.
O que é observabilidade com OpenTelemetry: visão prática
Observabilidade não é juntar gráficos bonitos. É responder “por que está lento?” em minutos, não horas. O OpenTelemetry fornece SDKs, especificações e um coletor padronizado para três sinais: traces, métricas e logs. Pense nele como o adaptador universal: você instrumenta uma vez e escolhe o backend depois. Isso reduz acoplamento, evita agentes proprietários em cada linguagem e acelera a adoção de boas práticas.
Uma boa analogia é a de um hospital: métricas são sinais vitais (batimentos, pressão), traces são o prontuário do atendimento passo a passo, e logs são as anotações detalhadas do médico. Sozinhos dizem algo; combinados contam a história completa. OTel dá o padrão para todos esses registros “conversarem” entre si via identificadores como trace_id e span_id.
Planejamento da instrumentação: métricas, logs e traces
Antes de escrever a primeira linha de código, defina o que precisa ser observado. Instrumentar tudo, sem critério, gera ruído e custo. O caminho certo começa por metas operacionais (SLOs, latência p95, taxa de erro, saturação) e por perguntas que o time faz nos incidentes. Esses requisitos guiam o que coletar, onde e com qual frequência.
Definir objetivos e cobertura mínima
- Traces: cubra a borda externa (APIs públicas) e os pontos de fan-out (chamadas a bancos, filas e serviços críticos). Tracing distribuído é mais valioso onde há múltiplos saltos.
- Métricas: aplique RED (Rate, Errors, Duration) para serviços orientados a requisição e USE (Utilization, Saturation, Errors) para recursos como filas e bancos.
- Logs: mantenha logs estruturados, com trace_id/span_id quando disponíveis, e campos de negócio essenciais para diagnóstico.
Escolher convenções e contexto
Use as Semantic Conventions do OpenTelemetry para nomes de atributos e métricas. Padronizar http.method, db.system, messaging.system e atributos de recurso como service.name, deployment.environment evita painéis “quebrados”. Defina chaves de negócio com parcimônia e evite cardinalidade explosiva em rótulos como user_id ou request_id.
Instrumentação com OpenTelemetry na prática
Há dois caminhos: auto-instrumentação (rápida, cobre bibliotecas comuns) e instrumentação manual (controle fino, spans de domínio). Em geral, comece pelo automático e complemente o que falta no caminho crítico do usuário.
Traces distribuídos: HTTP, gRPC e mensageria
- Propagação de contexto: adote W3C Trace Context (headers traceparent e tracestate). Sem isso, os saltos perdem vínculo e o gráfico de dependências vira um mosaico.
- Sampling: use head sampling conservador em produção (por exemplo, 5–10% para rotas de alta taxa) e tail sampling no Collector para manter 100% de erros e outliers. Assim, reduz custo sem cegar o diagnóstico.
- Spans de domínio: crie spans claros para operações de negócio (“calcular_frete”, “autorizar_pagamento”), não apenas para I/O. Isso acelera a leitura em incidentes.
Métricas com OpenTelemetry: contadores e histogramas na medida certa
- Counter/UpDownCounter: para taxas e contagens de eventos. Evite decrementar Counter; use o tipo correto.
- Histogram: colete latências com buckets adequados ao seu SLO. Buckets ruins distorcem p95/p99. Ajuste conforme o perfil de tráfego real.
- Exemplars: habilite exemplars para ligar pontos de métricas a trace_id. Em diagnóstico, um clique leva do pico no gráfico ao trace que explica o porquê.
- Cardinalidade: limite rótulos. Prefira “rota normalizada” (por exemplo, /orders/{id}) a “URI crua”. Cardinalidade alta = memória alta e consultas lentas.
Logs estruturados e correlação com traces
- Formato: JSON por linha, timestamps com fuso UTC e precisão em nanos quando disponível.
- Correlação: injete trace_id e span_id no logger de requisição. Em tarefas assíncronas, propague contexto via mensagem.
- Níveis: INFO para fluxo normal, WARN para anomalias recuperáveis, ERROR para falhas. Não escale o nível para “aparecer”; gere alertas via métricas.
Dica de ouro: padronize service.name, deployment.environment e service.version em todos os serviços. Esses três atributos são o “CEP” da sua telemetria: sem eles, você não encontra nada.
OpenTelemetry Collector: pipeline de coleta e processamento
O OpenTelemetry Collector é o encanamento central. Recebe sinal via receivers (OTLP, Jaeger, Prometheus), processa e exporta para os backends. Ele permite políticas como amostragem por erro, tail sampling, enriquecimento de atributos e batch para reduzir overhead.
Desenho de pipelines e topologias
- Agent + Gateway: um Collector “agent” próximo ao app (sidecar/daemon) e um “gateway” central para agregação. Escalável e resiliente.
- Processadores essenciais: batch (eficiência), memory_limiter (pressão de memória), attributes (enriquecimento), tail_sampling (amostrar por regra).
- Isolamento: separe pipelines por sinal. Problemas em logs não devem travar métricas.
Exportação para Prometheus, Grafana e Jaeger
- Métricas no Prometheus: use o prometheus exporter do Collector para expor um endpoint scrapeável. O Grafana lê o Prometheus, então os dashboards virão daí.
- Traces no Jaeger: use otlp ou o jaeger exporter no Collector para enviar para o Jaeger. O Grafana também pode consumir o Jaeger como fonte de dados de tracing.
- Logs no Grafana: escolha um backend compatível (por exemplo, soluções de log timeseries). O Collector pode enviar via OTLP ou formatos suportados pelo backend escolhido.
Evite acoplar os apps a múltiplos agentes. Em vez disso, exporte OTLP para o Collector e deixe que ele faça o fan-out para Prometheus, Jaeger e demais destinos. Isso simplifica migrações e controle de custo.
Instalação e visualização: Prometheus, Grafana e Jaeger
No Prometheus, registre o endpoint do prometheus exporter do Collector. Valide as séries-chave (taxa, erro, latência). No Grafana, conecte o Prometheus e o Jaeger como fontes e crie painéis ou importe dashboards oficiais como ponto de partida. No Jaeger, confirme a propagação: o gráfico de dependências deve refletir o seu mapa de serviços, não apenas um serviço isolado.
Para um guia de implantação mais amplo em microsserviços e Kubernetes, consulte o artigo guia completo de observabilidade com OpenTelemetry em microsserviços.
Observabilidade em Kubernetes e VMs: práticas que evitam dor
- Kubernetes: rode o Collector como DaemonSet (agent) e Deployment (gateway). Use PodAnnotations para autodiscovery de endpoints e injete atributos de recurso como k8s.namespace.name.
- Sidecar vs. Daemon: sidecar dá isolamento por pod e custo maior; daemon simplifica e economiza recursos. Escolha conforme latência e compliance.
- VMs: instale o Collector como serviço do sistema. Padronize host.name e tags de ambiente para diferenciação clara.
- Segurança: use TLS em OTLP, autenticação por token e segregação por tenant, quando necessário.
Para um roteiro prático de ponta a ponta, veja também como implementar observabilidade full-stack com OpenTelemetry.
Dashboards, alertas e SLOs: do dado à ação
Dados só viram resultado quando se transformam em decisões. Comece por painéis de saúde do serviço (RED), depois crie painéis de comportamento (erros por tipo, variação de latência por rota) e finalize com painéis de causa (dependências e hotspots). Alerta deve ser raro e preciso: foque em SLOs quebrados e sintomas do usuário, não em métricas internas ruidosas.
- Prometheus: defina regras de alerta por SLO e “múltiplas janelas” para evitar flaps.
- Grafana: use alertas centralizados e anotações em gráficos para correlação com eventos de deploy.
- Jaeger: padronize tags obrigatórias para facilitar filtros e salve consultas úteis por domínio.
Se o seu foco é tracing distribuído, logs estruturados e métricas em orquestrações modernas, aprofunde em observabilidade de ponta a ponta com OpenTelemetry.
Erros comuns e como evitar
- Cardinalidade descontrolada: rótulos com valores únicos explodem o Prometheus. Normalize caminhos, faça hashing quando necessário e audite séries ativas.
- Amostragem mal calibrada: 100% de traces em alta escala é caro; 0,1% cega outliers. Combine head + tail sampling e garanta 100% para erros.
- Collector gargalando: sem memory_limiter e batch, riscos de OOM e perda de dados aumentam. Monitore fila interna e tempo de exportação.
- Falta de correlação: logs sem trace_id desperdiçam potencial. Integre o logger ao contexto do trace.
- Relógios desalinhados: sem NTP, timeline de spans e métricas fica incoerente. Padronize sincronização de tempo.
- Dependências não instrumentadas: um elo opaco sabota o tracing. Cubra SDKs de HTTP, gRPC, DB e mensageria usados.
Checklist rápido para ir à produção
- OTLP habilitado no app com recurso de serviço, ambiente e versão.
- Collector em agent + gateway, com batch, memory_limiter e tail_sampling.
- Prometheus scraping do exporter de métricas do Collector.
- Jaeger recebendo traces e Grafana conectado a Prometheus e Jaeger.
- Dashboards RED/USE e alertas por SLO com exemplars ativos.
- Logs estruturados com trace_id e retenção adequada ao compliance.
FAQ: perguntas frequentes sobre OpenTelemetry e visualização
Preciso de agentes diferentes para cada backend?
Não. Padronize a exportação via OTLP para o OpenTelemetry Collector e deixe o Collector fazer o fan-out para Prometheus, Jaeger e outros. Isso reduz acoplamento e simplifica migrações.
Como decidir entre head sampling e tail sampling?
Use head sampling para reduzir tráfego já no cliente e tail sampling no Collector para preservar traces relevantes (por exemplo, erros e latências acima de um limiar). A combinação é o equilíbrio entre custo e diagnóstico.
É possível correlacionar métricas com traces no Grafana?
Sim. Habilite exemplars nas métricas e configure o Grafana com Prometheus e Jaeger. Assim, pontos específicos dos gráficos podem abrir o trace associado.
Como visualizar logs no Grafana junto com métricas e traces?
Envie logs para um backend compatível e adicione-o como fonte no Grafana. Garanta que os logs carreguem trace_id e span_id para permitir navegação cruzada.
Quais métricas são obrigatórias para começar?
Implemente o trio RED: taxa de requisições, taxa de erro e latência (p50, p95, p99) por rota normalizada. Elas antecipam a maioria dos incidentes e orientam a evolução dos painéis.
Pronto para dar o próximo passo? Aplique as recomendações neste guia, compartilhe dúvidas ou resultados nos comentários e navegue por outros conteúdos em appnoodles.com para aprofundar sua estratégia de observabilidade.