Pilares da Observabilidade: logs, métricas e traces
Ambientes de TI modernos rodam em centenas de microsserviços, containers efêmeros e regiões cloud distribuídas. Sobretudo nesse contexto, entender por que uma requisição falhou exige mais do que checar se um servidor está no ar. É preciso reconstruir o caminho daquela requisição, medir seu impacto agregado e ler o que cada componente registrou no caminho.
Os pilares da observabilidade nasceram exatamente para responder a essa pergunta. Métricas, logs e traces são os três sinais de telemetria que, quando coletados de forma coordenada, permitem investigar incidentes em sistemas distribuídos sem precisar reproduzir o problema em ambiente controlado.
Cada pilar resolve uma dimensão específica do diagnóstico. Nenhum funciona bem isolado dos outros dois.
Esta página é o guia de referência da OpServices sobre o tema. Ao longo dela, você verá o que cada pilar resolve, como eles se correlacionam, como o OpenTelemetry virou o padrão de instrumentação e quais armadilhas operacionais aparecem quando a stack vai para produção em escala real.
O que é observabilidade e por que três pilares
A observabilidade descreve a capacidade de inferir o estado interno de um sistema a partir das saídas que ele produz, sem precisar adicionar instrumentação nova para cada nova pergunta. Em outras palavras, um sistema observável responde perguntas inéditas com os dados que já está emitindo.
Para entender a base conceitual, vale o nosso guia sobre o que é observabilidade e como ela se diferencia de práticas mais antigas.
A divisão em três pilares ganhou força com o livro Distributed Systems Observability, de Cindy Sridharan, em 2018. Naquele momento, microsserviços já tinham se tornado o padrão e os times perceberam que o monitoramento tradicional, baseado em checks pontuais, não conseguia explicar o comportamento emergente desses ambientes.
Cada pilar cobre uma lacuna que os outros dois não cobrem. Logs trazem o evento bruto com contexto narrativo. Métricas trazem o estado quantitativo agregado ao longo do tempo. Traces trazem o fluxo de uma requisição específica através de múltiplos serviços. Por isso, falar em “três pilares” é menos um dogma e mais uma forma prática de organizar os tipos de dado que um operador precisa cruzar.
Ainda assim, vale entender o limite dessa divisão. A relação entre monitoramento e observabilidade não é antagônica: o monitoramento continua respondendo às perguntas conhecidas, enquanto a observabilidade dá a flexibilidade para investigar as desconhecidas. Os três sinais alimentam ambas as práticas.
Logs: o pilar do evento
Logs são registros imutáveis com data e hora de algo que aconteceu em um componente do sistema. Eles preservam o detalhe narrativo de cada evento: uma exceção, uma requisição recebida, uma transição de estado, uma decisão de roteamento. Por isso, são a primeira linha de investigação quando algo falha de forma específica e localizada.
Tradicionalmente, logs aparecem em três formatos. O texto livre é o mais comum em sistemas legados, mas dificulta consultas. O log estruturado, normalmente em JSON, codifica cada campo (timestamp, severity, trace_id, mensagem) como propriedade indexável. O formato binário, por fim, otimiza espaço em pipelines de alto volume.
Structured logging: o formato que tornou logs investigáveis
A diferença prática entre log de texto e log estruturado aparece no momento da consulta. Em texto, encontrar “todas as requisições do cliente X que falharam com timeout” exige regex frágil. Em JSON, é uma query exata sobre os campos customer_id e error_code.
Adicionalmente, o log estruturado carrega o trace_id da requisição. Isso permite saltar do log direto para o trace correspondente, fechando o ciclo de investigação.
Estruturar bem o log significa definir, antes de escrever código, quais campos toda entrada deve carregar. Em equipes maduras, esse padrão vira parte do contrato de cada serviço. O guia completo de gerenciamento de logs aprofunda como organizar essa coleta em escala corporativa, incluindo rotação, retenção e parsing centralizado.
O custo de armazenar tudo
Logs têm uma característica que assusta operações em escala: o volume cresce de forma quase linear com o tráfego. Cada requisição gera múltiplas entradas em múltiplos componentes. Em produção, manter logs por 90 dias pode custar mais que a infraestrutura de aplicação.
Por isso, equipes maduras adotam estratégias híbridas. Logs de erro vão para armazenamento quente por semanas. Logs informacionais vão para armazenamento frio em S3 ou similar, consultáveis sob demanda. Logs de debug ficam ligados apenas para serviços sob investigação.
O artigo dedicado sobre logs como sinal de observabilidade mostra exemplos concretos de pipelines de coleta para cada nível.
Métricas: o pilar do estado quantitativo
Métricas são valores numéricos coletados em intervalos regulares e armazenados como séries temporais. Cada métrica responde a uma pergunta do tipo “quanto”: quantas requisições por segundo, qual é a latência P95, qual o uso de CPU, qual a taxa de erros HTTP 500.
A força do pilar de métricas como sinal de observabilidade está em permitir comparações ao longo do tempo e detectar tendências antes que virem incidentes.
Diferentemente dos logs, métricas têm volume previsível. Você decide quais métricas coletar e em qual frequência. O custo de armazenamento fica conhecido. Em contrapartida, métricas perdem o detalhe narrativo: você sabe que a latência subiu, mas não sabe qual requisição específica causou.
Tipos fundamentais de métrica
Os três tipos clássicos cobrem 90% dos casos. Counters só sobem (total de requisições, total de erros). Gauges oscilam (uso de memória atual, threads ativas). Histograms agrupam valores em buckets (distribuição de latência, tamanho de payload). Cada tipo determina como o backend faz agregação ao consultar séries longas.
Em seguida, equipes maduras combinam tipos em methods reconhecidos. O método RED (Rate, Errors, Duration) caracteriza serviços de requisição/resposta. O método USE (Utilization, Saturation, Errors) caracteriza recursos como CPU, disco e rede. Ambos servem como ponto de partida para escolher quais métricas instrumentar primeiro.
Cardinalidade: a pegadinha que explode o custo
A cardinalidade de uma métrica é o número de combinações únicas de labels que ela tem. Uma métrica http_requests_total com labels {method, status, endpoint} pode ter dezenas de combinações. Adicione customer_id como label e, dependendo do volume de clientes, a cardinalidade vai a milhões.
Backends de métricas como Prometheus mantêm uma série separada para cada combinação única. Cardinalidade alta significa memória alta, consultas lentas e custo crescente. Por isso, decidir o que vira label e o que vira atributo de log é uma decisão de arquitetura: não cosmética. Identificadores únicos quase nunca devem virar labels de métrica.
Traces: o pilar do fluxo distribuído
Traces reconstroem o caminho completo de uma única requisição através de todos os serviços que ela tocou. Cada parada da requisição em um serviço vira um span: um intervalo de tempo com nome, atributos e a relação pai/filho com outros spans. Ao final, o trace completo mostra a árvore de chamadas, com o tempo gasto em cada nó.
Em arquiteturas monolíticas, tracing tinha pouco valor: bastava um stack trace local. Já em microsserviços, uma única requisição pode atravessar 20 serviços, 3 filas e 2 bancos de dados. Sem trace, descobrir qual nó causou um aumento de latência exige correlacionar timestamps de logs de diferentes serviços: tarefa lenta e propensa a erro.
Propagação de contexto: o que faz o trace existir
Para um trace existir, cada serviço precisa receber o identificador da requisição (o trace_id) e propagá-lo para os próximos. Esse mecanismo se chama propagação de contexto. Sem propagação, cada serviço produz spans órfãos que não se conectam.
O padrão atual é o cabeçalho traceparent, definido pela especificação W3C Trace Context. Quando um serviço recebe esse cabeçalho, ele cria um novo span filho do span anterior e propaga o mesmo trace_id adiante. Bibliotecas modernas (OpenTelemetry, principalmente) fazem isso automaticamente para HTTP, gRPC, Kafka e a maioria dos protocolos comuns.
Sampling: coletar tudo é inviável
Em escala de produção, gravar 100% dos traces gera volume comparável ao de logs. Por isso, todas as stacks sérias aplicam sampling de telemetria. A escolha do sampling muda completamente o custo e a utilidade da telemetria.
O head-based sampling decide manter ou descartar o trace logo no primeiro span. Essa abordagem é barata, mas perde informação importante quando o problema aparece só no final da chamada.
O tail-based sampling espera o trace completar antes de decidir. É mais caro, em compensação garante que todo trace com erro ou latência anômala seja preservado. O dynamic sampling ajusta a taxa por endpoint, mantendo 100% nos críticos e amostrando agressivamente os triviais.
Ferramentas como o Jaeger implementam diversas dessas estratégias e, em geral, ficam atrás de um OTel Collector que aplica regras de sampling antes de exportar o dado.
Como os três pilares se correlacionam
Os três pilares só entregam valor pleno quando consultados juntos. Em ambientes maduros, o operador sai de uma métrica anômala, salta para um trace específico daquela janela. Do trace pula direto para os logs do span problemático. Esse fluxo se chama cross-signal correlation e é o que diferencia uma stack moderna de coleções isoladas de dashboards.
A tabela a seguir resume como cada sinal se comporta nas dimensões que importam na operação:
| Dimensão | Logs | Métricas | Traces |
|---|---|---|---|
| Pergunta que responde | O que aconteceu? | Quanto e quando aconteceu? | Onde aconteceu na cadeia? |
| Formato típico | JSON estruturado |
série temporal |
árvore de spans |
| Volume por requisição | Alto (vários por hop) | Baixo (agregado) | Médio a alto |
| Latência de análise | Segundos a minutos | Tempo real | Segundos |
| Boa para alertar | Limitado (alto ruído) | Ideal | Possível com agregação |
| Custo de armazenamento | Alto | Baixo | Médio (com sampling) |
Exemplar trace: a cola entre os três sinais
O conceito de exemplar é o que materializa a correlação na prática. Um exemplar é um trace_id anexado a um bucket de histograma de métrica. Quando você vê um pico no histograma de latência, clica no exemplar daquele bucket e cai direto no trace que originou aquela amostra: sem precisar adivinhar timestamps.
A partir do trace, cada span carrega seu trace_id e span_id embutidos nos logs daquele serviço. Logo, do trace você navega para os logs do span exato em segundos. Essa cadeia métrica → trace → log é o que torna uma stack observável de verdade: não apenas três silos de dados.
🎬 Para entender mais sobre o panorama geral do conceito de observabilidade, neste corte do nosso podcast, abordamos as diferenças entre a monitoração tradicional e a observabilidade:
OpenTelemetry: o padrão que unifica os três pilares
Por muito tempo, cada pilar tinha sua biblioteca dedicada e cada ferramenta tinha seu agente proprietário. Migrar entre vendors significava reinstrumentar todo o código. O OpenTelemetry mudou esse cenário ao consolidar SDKs, protocolos e semântica em um único projeto vendor-neutral mantido pela CNCF.
Hoje, o OTel é o padrão de fato para emitir logs, métricas e traces. Ele cobre instrumentação automática para a maioria das linguagens populares, define convenções semânticas (nomes padronizados de atributos como http.method, db.system, service.name) e usa um protocolo de transporte único: o OTLP.
A documentação oficial dos sinais de telemetria detalha como cada sinal é representado e propagado.
Anatomia da stack OTel: SDKs, Collector, exporters
A tabela abaixo resume os componentes que toda implementação OTel apresenta:
| Componente | Detalhe / Como atua | Por que importa |
|---|---|---|
| SDK por linguagem | Biblioteca embarcada na aplicação que produz spans, métricas e logs em formato OTLP |
Instrumentação consistente em qualquer stack |
| Auto-instrumentation | Agente que injeta instrumentação sem alterar código para frameworks populares | Cobertura rápida de serviços legados |
| OTel Collector | Processo intermediário que recebe, processa (sampling, filtros) e exporta telemetria | Desacopla apps do backend final e centraliza políticas |
| Exporters | Conectores do Collector para backends como Prometheus, Jaeger, Loki, Datadog | Liberdade de trocar backend sem mexer na app |
| Convenções semânticas | Nomes padronizados como http.status_code e service.name |
Dashboards e queries portáveis entre vendors |
A consequência prática dessa arquitetura é direta. Instrumentar com OTel hoje significa que, ao trocar de backend (de Datadog para Grafana Cloud, por exemplo), basta reconfigurar o exporter no Collector. O código da aplicação fica intacto.
Ferramentas de coleta e visualização por pilar
O ecossistema cloud-native consolidou ferramentas específicas para cada pilar, todas integráveis ao OTel Collector. A escolha entre open-source e comercial depende mais de capacidade operacional do que de funcionalidade: ambos os caminhos entregam os três pilares de forma robusta.
Para métricas, o padrão open-source é o Prometheus, que coleta via scraping HTTP e armazena séries temporais com query language própria (PromQL).
Para logs, o Loki adota uma abordagem similar ao Prometheus: indexa apenas labels, mantendo o corpo do log barato em armazenamento. Para traces, Tempo e Jaeger dominam o open-source, ambos compatíveis com OTLP.
Em cima dessa coleta, o Grafana oferece dashboards unificados sobre todos os três pilares, com navegação cruzada entre métricas, logs e traces na mesma interface. Equipes que preferem uma stack consolidada e gerenciada partem para Datadog, New Relic ou Dynatrace: todas suportam OTLP nativamente desde 2023.
Para se manter atualizado sobre o ecossistema completo, o landscape oficial da CNCF é a referência canônica. Ele mapeia centenas de projetos cloud-native categorizados por função, incluindo a categoria de Observabilidade e Análise.
Arquitetura de referência para os três pilares em produção
Uma stack típica de produção segue um padrão em camadas. Na borda, as aplicações emitem dados via SDK OTel ou auto-instrumentation. Esses dados vão para um Collector próximo (em geral, um sidecar ou DaemonSet em Kubernetes). O Collector aplica sampling, filtros e enriquecimento, então exporta para os backends de cada pilar.
A separação entre Collector local e Collector central é uma boa prática que aparece em ambientes maduros. O Collector local agrega dados do nó e reduz fan-out. Já o Collector central concentra políticas que precisam de visão global: tail-based sampling, por exemplo, exige ver todos os spans de um trace antes de decidir, o que só faz sentido no Collector central.
Esse padrão arquitetural cobre a maioria dos cenários em microsserviços e Kubernetes. Ele aparece detalhado em literatura técnica sobre observabilidade em sistemas distribuídos.
Backends ficam atrás dos Collectors. Prometheus armazena métricas, Loki armazena logs, Tempo ou Jaeger armazena traces. O Grafana (ou equivalente comercial) consome dos três e expõe a interface unificada. Alertas, por sua vez, normalmente saem do Prometheus via Alertmanager: porque alertas são, na essência, queries sobre métricas com threshold.
Em equipes com SRE estabelecido, essa stack alimenta os indicadores do programa de observabilidade: tempo até detecção, tempo até resolução, taxa de falsos positivos. O conceito vai além da telemetria pura e entra em observability engineering como disciplina.
Desafios operacionais reais
Implementar os três pilares parece simples no papel. Em produção, a stack apresenta desafios que só aparecem em escala. Justamente esses problemas separam um programa de observabilidade saudável de uma coleção cara de dashboards inúteis.
Cardinalidade descontrolada
Cardinalidade é o problema número um de métricas em escala. Um único label mal escolhido (UUID de requisição, customer_id, container_id efêmero) pode multiplicar séries em ordens de magnitude. Como resultado, o Prometheus começa a falhar em consultas longas, alertas atrasam e o custo explode.
A defesa é técnica e cultural. Tecnicamente, o OTel Collector permite reescrever ou remover labels antes de exportar. Culturalmente, toda nova métrica passa por revisão de cardinalidade antes de ir para produção. Algumas equipes criam um “orçamento de cardinalidade” por serviço: número máximo de séries que aquele serviço pode produzir.
Sampling sem governança
Sampling de traces resolve o custo, mas introduz cegueira. Se a política descarta 99% dos traces aleatoriamente, o trace que você precisa investigar amanhã pode simplesmente não existir. Por isso, equipes maduras adotam tail-based sampling com regras explícitas: preservar 100% dos traces com erro, 100% dos traces acima de um threshold de latência. Amostrar agressivamente o restante.
A governança de sampling fica formalizada como código no Collector. Toda mudança passa por revisão. Auditar quanto sampling está ativo em cada serviço vira parte do checklist operacional.
Fadiga de alertas
Coletar logs, métricas e traces sem critério gera uma enxurrada de alertas: muitos repetidos, muitos sem ação clara. Fadiga de alertas é o sintoma. O remédio passa por aplicar metodologia (RED e USE para métricas, SLOs para resultado de serviço) e revisar regularmente quais alertas geraram ação real.
Equipes que tratam isso como disciplina de engenharia (não como ajuste pontual) alcançam reduções significativas no volume de alertas sem perder cobertura. A relação com práticas de SRE é direta. Programas maduros tratam alertas como hipóteses revisáveis, não como verdades estáticas.
Boas práticas e armadilhas comuns
Equipes que tiraram proveito real dos três pilares compartilham um conjunto de práticas que vale destacar:
Estruturar logs em JSON desde o primeiro serviço: fazer migração depois custa muito mais. Definir um conjunto mínimo de campos obrigatórios (trace_id, span_id, severity, service.name) garante que qualquer log futuro seja correlacionável.
Adotar OTel como padrão único de instrumentação. Stacks que misturam Prometheus client direto, Jaeger client direto e logging customizado pagam o preço quando precisam mudar de backend. Por outro lado, OTel desde o início desacopla código de fornecedor.
Tratar cardinalidade como um budget. Cada novo label de métrica passa por revisão. IDs de requisição, customer_id e container_id ficam fora de labels: são atributos de log ou tags de span.
Implementar sampling tail-based assim que o volume de traces preocupar. Head-based sampling joga fora dados úteis. Tail-based exige Collector central, mas preserva o que importa.
Por fim, definir SLOs antes de definir alertas. Métricas só ganham sentido operacional quando ligadas a um objetivo declarado. Alertas que não levam a uma ação clara são ruído: não cobertura.
Logs, métricas e traces unificados para diagnóstico em profundidade.
Instrumentamos aplicações corporativas com OpenTelemetry para correlacionar eventos e acelerar a análise de causa raiz em produção.
Conclusão
Os pilares da observabilidade não são um checklist a ser implementado uma vez e esquecido. Eles formam um conjunto coordenado de sinais que, quando coletados com OpenTelemetry, armazenados em backends adequados e correlacionados na interface de visualização, transformam a operação de TI em algo investigável de forma sistemática.
Logs respondem o que aconteceu. Métricas respondem quanto e quando. Traces respondem onde. Os três juntos permitem sair do alerta para a causa raiz em minutos (e não em horas). Para isso, a stack precisa ser pensada como sistema integrado desde o início: não como três projetos paralelos.
Cardinalidade, sampling e fadiga de alertas são os três problemas que separam programas maduros de coleções caras de dashboards. Resolvê-los exige disciplina técnica e cultural. Raramente acontece por acidente. Em contrapartida, o ganho operacional de uma stack bem desenhada se reflete diretamente em MTTR menor, SLA mais alto e equipes menos fatigadas.
Se a sua equipe está pensando em estruturar ou amadurecer um programa de observabilidade, conheça o nosso serviço de observabilidade gerenciada. Fale com um especialista da OpServices e veja como podemos ajudar a unificar logs, métricas e traces na sua operação.

