trilha

System Design/03 - Qualidade/Monitoring2 min

Instrumentation

Perguntas-guia
  • 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

Buscar

Busca por título, seção e texto das notas