OpenTelemetry: traces distribuídos
Objetivos desta aula
- Instrumentar traces com OTel
- Entender contexto e propagação
- Usar amostragem com critério
Trace mostra a jornada de uma requisição como uma árvore de spans, com duração e atributos de cada etapa. É o sinal que responde imediatamente 'o tempo está no banco, na chamada externa ou no nosso código' — pergunta que métricas agregadas não respondem.
OpenTelemetry é o padrão vendor-neutral: SDK instrumenta a aplicação, o Collector recebe, processa e exporta para o backend escolhido (Tempo, Jaeger, ou serviço gerenciado). Trocar de backend deixa de ser reescrita de instrumentação.
Propagação de contexto é o que costura os serviços: o traceparent viaja nos headers HTTP. E amostragem controla custo — 100% em ambiente de estudo, taxa menor em produção, sempre com política que preserve traces de erro e de alta latência.
1. Trace e span
Um trace é a história de uma requisição; cada etapa (chamada HTTP, query SQL) é um span com início, duração e atributos. O contexto viaja entre serviços no cabeçalho traceparent (W3C).
2. OpenTelemetry
Padrão aberto com SDKs e auto-instrumentação para Node, Java, Python, Go. Você instrumenta uma vez e envia para qualquer backend (Tempo, Jaeger, Datadog).
3. O Collector
Recebe dados via OTLP, processa (batch, remoção de dados sensíveis, sampling) e exporta. Rode como DaemonSet ou sidecar para desacoplar a app do fornecedor.
4. Sampling
Guardar 100% dos traces custa caro. Head sampling decide no início (ex.: 10%); tail sampling no Collector guarda todos os com erro ou lentos e uma amostra do resto.
Na prática
Instrumentação OTel na API
javascript
// otel.js — carregado antes do app: node --require ./otel.js src/server.js
import { NodeSDK } from "@opentelemetry/sdk-node";
import { getNodeAutoInstrumentations } from "@opentelemetry/auto-instrumentations-node";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
import { TraceIdRatioBasedSampler } from "@opentelemetry/sdk-trace-base";
const sdk = new NodeSDK({
serviceName: "cloudshop-api",
traceExporter: new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT }),
sampler: new TraceIdRatioBasedSampler(Number(process.env.OTEL_SAMPLE_RATIO ?? 0.1)),
instrumentations: [getNodeAutoInstrumentations()],
});
sdk.start();
process.on("SIGTERM", () => sdk.shutdown());Nota de segurança: Atributos de span podem vazar dado sensível (corpo da requisição, e-mail). Configure redaction no Collector.
Collector com processamento
yaml
receivers:
otlp:
protocols: { http: {}, grpc: {} }
processors:
batch: { timeout: 5s }
attributes/limpeza:
actions:
- key: http.request.header.authorization
action: delete
- key: user.email
action: delete
tail_sampling:
policies:
- name: manter-erros
type: status_code
status_code: { status_codes: [ERROR] }
- name: manter-lentos
type: latency
latency: { threshold_ms: 1000 }
exporters:
otlphttp/tempo: { endpoint: http://tempo:4318 }
service:
pipelines:
traces:
receivers: [otlp]
processors: [attributes/limpeza, tail_sampling, batch]
exporters: [otlphttp/tempo]Auto-instrumentação da API Node
bash
npm install @opentelemetry/auto-instrumentations-node
export OTEL_SERVICE_NAME=cloudshop-api
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
export NODE_OPTIONS="--require @opentelemetry/auto-instrumentations-node/register"
node server.js # HTTP, Express e pg passam a gerar spansCollector com tail sampling
yaml
receivers: { otlp: { protocols: { http: {}, grpc: {} } } }
processors:
batch: {}
tail_sampling:
policies:
- { name: erros, type: status_code, status_code: { status_codes: [ERROR] } }
- { name: lentos, type: latency, latency: { threshold_ms: 1000 } }
- { name: amostra, type: probabilistic, probabilistic: { sampling_percentage: 10 } }
exporters: { otlp: { endpoint: tempo:4317, tls: { insecure: true } } }
service:
pipelines:
traces: { receivers: [otlp], processors: [tail_sampling, batch], exporters: [otlp] }Por que isso importa
Em arquitetura distribuída, sem trace a investigação de latência é chute educado.
Erro comum
Instrumentar apenas um serviço e perder a propagação — o trace fica quebrado.
Dica de produção
Tail sampling preservando erros e requisições lentas dá o melhor custo-benefício.
Alerta de segurança
Nunca envie corpo completo de requisição para o backend de traces.
Pergunta de entrevista
O que é propagação de contexto e como ela funciona em HTTP?
Glossário
- span
- Unidade de trabalho dentro de um trace, com início, fim e atributos.
- Collector
- Processo que recebe, transforma e exporta telemetria para backends.
- Span
- Uma etapa de um trace, com nome, duração e atributos.
- OTLP
- Protocolo do OpenTelemetry para enviar telemetria.
- Tail sampling
- Decidir guardar o trace depois de vê-lo completo.
Conexão com o CloudShop
Rastrear a jornada de criação de pedido do CloudShop do frontend ao banco.
Quiz da aula
1. Qual sinal indica melhor onde o tempo de uma requisição foi gasto?
2. Como o contexto do trace passa de um serviço para outro?
3. Qual sampling garante guardar todos os traces com erro?
Minhas anotações
Salvo automaticamente neste navegador.