Traces na Observabilidade: o que são, span, trace_id e OpenTelemetry
Em arquiteturas monolíticas, debugar uma requisição lenta era relativamente simples: um único stack trace, um único banco de dados, logs centralizados em um servidor. Em arquiteturas de microsserviços, a mesma requisição pode atravessar 15, 20 ou 30 serviços diferentes antes de retornar uma resposta ao usuário.
Quando algo dá errado nessa cadeia, descobrir onde sem as ferramentas certas pode levar horas.
Traces — ou rastreamento distribuído — são o pilar da observabilidade que resolve esse problema. Eles registram a jornada completa de uma requisição por todos os serviços que ela atravessa, tornando a cadeia de dependências visível e navegável.
Este guia técnico explica o que são traces e como a estrutura de span e trace_id funciona. Em seguida, mostra como eles se integram com logs e métricas e como o padrão OpenTelemetry padroniza a instrumentação.
O que são traces (rastreamento distribuído)?
Um trace é a representação completa e cronológica da jornada de uma requisição por um sistema distribuído. Ele cobre do ponto de entrada até o retorno da resposta, com todas as operações intermediárias em todos os serviços envolvidos.
Cada trace é composto por um conjunto de spans: unidades de trabalho que representam uma operação individual. Um span captura o nome da operação, o serviço que executou e os timestamps de início e fim. Ele traz ainda o status (sucesso ou falha), atributos de contexto e a referência ao span pai.
A estrutura hierárquica de spans forma uma árvore que representa o fluxo da requisição. O span raiz é a requisição original; os spans filhos são as operações que ela disparou em outros serviços ou internamente.
trace_id e span_id: o DNA de uma requisição
O elemento que torna o rastreamento distribuído possível é o trace_id: um identificador único gerado quando a requisição entra no sistema. Cada serviço o repassa adiante, via headers HTTP, mensagens de fila ou protocolos de RPC.
Cada serviço lê o trace_id do contexto, cria seu próprio span com um span_id único e registra o span_id do serviço anterior como parent_span_id. Esse encadeamento permite reconstruir a árvore completa de spans.
O trace_id é também o elo de correlação com os outros pilares. Quando injetado nos logs gerados durante a requisição, permite filtrar exatamente os logs daquele trace. Quando presente nas métricas de erro, permite navegar do alerta para o trace específico que falhou.
Esse encadeamento fica visível fora da documentação em um laboratório com cinco serviços Python instrumentados por OpenTelemetry, um Collector e o Jaeger. Versões testadas em 28 de agosto de 2026: Jaeger 2.11.0, OpenTelemetry Collector Contrib 0.139.0 e SDK Python 1.44.0 com instrumentação automática 0.65b0.
A API do Jaeger devolve os spans crus em GET /api/traces/{trace_id}. Estes são dois spans vizinhos do mesmo trace, com os campos que interessam:
O traceID é idêntico nos dois. Já o spanID do primeiro reaparece como CHILD_OF do segundo, e esse par é o que reconstrói a hierarquia. A duração vem em microssegundos: 40.955 no span HTTP e 40.009 no SELECT que ele disparou.
Anatomia de um trace real, span a span
A árvore completa do trace 90316b21da519f164ecfc94c1b21b760 tem 11 spans, cinco serviços e profundidade 4. Na captura, o span raiz é a requisição inteira; o span marcado logo abaixo é onde o tempo ficou.

A leitura é direta. Dos 72,97 ms da requisição, 40,01 ms couberam dentro de um único SELECT do product-service. São 55% do total, num span três níveis abaixo do ponto de entrada.
Os dois SELECT do mesmo trace dão a régua. O inventory-service busca pela chave indexada e responde em 148 µs; o product-service varre 180 mil linhas por uma coluna sem índice e responde em 40,01 ms. São 270 vezes mais, na mesma tabela e no mesmo banco.
Sem o trace, chegar a essa conclusão exigiria abrir o log de quatro serviços e correlacionar timestamp na mão.
Ebook: Como sobreviver à fatura cloud?
Nosso framework, Observability Maturity Index, mede a maturidade das operações em nuvem das empresas. Você encontrará: os quatro perfis de empresas, as métricas que você deveria estar medindo, um checklist de avaliação e um plano de ação para 90 dias.
Só o e-mail. Sem spam, e seus dados protegidos pela LGPD.
Sampling: não rastrear tudo
Em sistemas de alto tráfego, rastrear 100% das requisições seria proibitivo em volume de dados e overhead de performance. A solução é o sampling: a decisão de quais requisições serão rastreadas.
O head-based sampling decide no início da requisição: é simples, mas pode perder traces de erros raros. Já o tail-based sampling decide ao final, depois de conhecer o resultado, e prioriza erros e requisições lentas ao custo de mais infraestrutura.
Em produção, a estratégia comum é rastrear 100% dos erros, 100% das requisições lentas e uma amostra configurável (1–10%) das demais.
No Collector, essa política tem nome e forma. As três regras abaixo rodaram no laboratório e foram o que decidiu quais traces chegaram ao Jaeger:
O decision_wait é a parte cara. O Collector segura os spans em memória por cinco segundos, esperando o trace fechar, para só então decidir. Esse é o preço do tail-based, e explica por que ele exige mais infraestrutura que o head-based.
A conta de volume que a amostragem esconde
Cada requisição ao gateway do laboratório gerou 11 spans, e cada span ocupou 1.021 bytes na saída do Collector, em OTLP/JSON. Com 500 requisições e 10% de amostragem, chegaram ao backend 539 spans e 550.456 bytes.
Esses dois números resolvem a conta de capacidade sem chute. Tome uma API com 20 milhões de requisições por mês e este mesmo trace de 11 spans. A 1% de amostragem ela produz cerca de 2,2 GB de spans por mês; a 10%, 22 GB.
Subir a amostragem de 1% para 10%, portanto, é decisão de fatura antes de ser decisão de configuração. O ganho de cobertura é real, o custo cresce na mesma proporção, e a retenção escolhida multiplica os dois lados.
OpenTelemetry e a padronização de traces
O OpenTelemetry é o padrão aberto que unificou a instrumentação de traces — anteriormente fragmentada entre OpenTracing, OpenCensus, Zipkin e Jaeger.
Ele define uma API e um SDK agnósticos ao backend. Instrumentar com OpenTelemetry significa exportar os traces para Jaeger, Grafana Tempo, Datadog ou outro backend compatível, sem alterar o código.
A especificação inclui convenções semânticas que padronizam os atributos dos spans: http.method, http.status_code, db.system, db.statement, entre outros. Essa padronização garante que traces de diferentes serviços e linguagens sejam navegáveis em uma única plataforma de observabilidade.
No span HTTP do product-service, esses atributos chegam ao Jaeger já preenchidos pela instrumentação automática. O serviço em si não tem nenhuma linha de código de OpenTelemetry:

Compare http.route com http.target. O primeiro guarda o molde da rota, /api/produto/<sku>; o segundo guarda o caminho com o SKU dentro. No trace os dois convivem sem problema, porque cada span é um evento discreto que ninguém agrega.
Aí mora a armadilha de cardinalidade. Esse mesmo http.target, promovido a rótulo de métrica, cria uma série temporal por SKU. É assim que uma base de métricas sai do controle. O trace aceita o valor único; a métrica, não.
A documentação de referência é a especificação de Distributed Traces do OpenTelemetry, que cobre em detalhe a estrutura de spans, propagação de contexto e semântica de atributos.
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
Traces são o pilar de navegação da observabilidade. Eles tornam visível o caminho exato de uma requisição por um sistema distribuído e o tempo gasto em cada hop. Sem traces, diagnosticar gargalos de performance em arquiteturas de microsserviços é uma investigação manual e demorada.
A implementação começa pela instrumentação padronizada com OpenTelemetry e segue com uma estratégia de sampling que prioriza erros e requisições lentas. Ela amadurece na correlação automática com logs e métricas pelo trace_id. Para estruturar sua estratégia de rastreamento distribuído e observabilidade, fale com nossos especialistas.
Perguntas Frequentes
O que é um trace na observabilidade?
O que é trace_id e span_id?
Qual a diferença entre traces e logs?
trace_id injetado nos logs é o elo que conecta os dois.