Problema
Logs sem requestId, métricas só de CPU e alertas que disparam depois que o cliente já migrou. Debug em produção vira adivinhação.
Solução
Três pilares integrados: logs estruturados (JSON), métricas de negócio e RED/USE, traces distribuídos com propagação W3C Trace Context. Definir SLIs (latência p95, taxa de erro) antes de escolher Grafana vs CloudWatch.
Arquitetura
App → OpenTelemetry SDK → OTLP collector → (Prometheus + Tempo + Grafana) ou CloudWatch
↘ logs JSON com trace_id + span_id
- Sentry (ou similar) para erros com breadcrumbs e release tracking.
- Dashboards por serviço + um “golden signal” global.
Código
import pino from "pino";
export const logger = pino({
level: process.env.LOG_LEVEL ?? "info",
base: { service: "billing-api" },
});
// middleware pseudo
app.use((req, res, next) => {
req.log = logger.child({ requestId: req.id });
next();
});Correlacione spans de HTTP client (undici/fetch instrumentado) com handlers.
Performance
Sampling de traces em alto volume; async logging; evitar cardinalidade infinita em labels de métricas.
Melhorias futuras
SLOs com error budget; profiling contínuo; runbooks linkados nos alertas.
Conclusão
Observabilidade é produto interno. Artigo assim mostra mentalidade de plataforma — comum em perfis sênior e staff adjacentes.