System Design/03 - Qualidade/Monitoring2 min
Instrumentation
- Que problema isso resolve?
- Quando usar / quando NÃO usar?
- Qual o principal trade-off?
- Como isso falha em produção?
Conceito
Instrumentação é o código que emite os sinais. Sem ela, não há o que monitorar.
Os três tipos de sinal
| Sinal | Estrutura | Custo | Bom para |
|---|---|---|---|
| Métrica | Número + dimensões, agregado | Baixo | Dashboards, alertas, tendência |
| Log | Evento textual/estruturado | Alto | Contexto detalhado, investigação |
| Trace | Span com pai e duração | Médio | Onde o tempo foi gasto |
Tipos de métrica
| Tipo | Uso |
|---|---|
| Counter | Só cresce: requisições, erros |
| Gauge | Sobe e desce: conexões ativas, memória |
| Histogram | Distribuição: latência — permite percentis |
| Summary | Percentis calculados no cliente |
Latência precisa de histogram. Com gauge ou média, os percentis se perdem — e são eles que descrevem a experiência real.
Boas práticas
Log estruturado (JSON) em vez de texto livre — consultável, agregável, sem regex frágil:
{"nivel":"erro","msg":"falha ao cobrar","pedido_id":42,
"trace_id":"a3f9","duracao_ms":2340}
Correlation ID / trace ID propagado por todo o caminho é o que permite juntar log, métrica e trace da mesma requisição. É o item de maior retorno em observabilidade distribuída.
OpenTelemetry virou o padrão de fato: uma instrumentação, qualquer backend.
Trade-offs
Instrumentação custa CPU, memória, banda e dinheiro. Os excessos mais comuns:
Alta cardinalidade é o mais caro. Uma métrica com dimensão user_id em um sistema com milhões de usuários cria milhões de séries temporais — e derruba o sistema de métricas. Dimensões devem ter cardinalidade limitada e previsível.
Log em caminho quente — registrar cada iteração de um laço de milhões de ciclos gera gigabytes e domina o tempo de execução.
Log síncrono bloqueia a requisição. Emissão deve ser assíncrona, com buffer, e o sistema deve continuar funcionando se o backend de telemetria cair.
E a regra de segurança que não admite exceção: nunca registrar segredo — senha, token, cartão, chave. O log costuma ir para sistemas com controle de acesso mais frouxo que o do banco.
Exemplo prático
with tracer.start_span("processar_pedido") as span:
span.set_attribute("pedido.id", pedido_id) # atributo do span: ok
metricas.contador("pedidos_processados").inc(
status="sucesso", regiao=regiao) # dimensões de baixa cardinalidade
metricas.histograma("pedido_duracao_ms").obs(duracao)
log.info("pedido processado",
pedido_id=pedido_id, trace_id=span.trace_id)
Note a divisão: pedido.id vai no span (cardinalidade alta é aceitável em trace, que é amostrado) e nunca como dimensão de métrica. status e regiao têm poucos valores possíveis — servem como dimensão.
O trace_id no log é o que permite, a partir de um alerta de latência, saltar direto para o trace e para os logs daquela requisição específica.
Relacionado
Parte de Monitoring · roadmap.sh/system-design