Ferramentas & Produtividade

O que Todo Dev Deve Saber sobre Observabilidade

7 min de leitura

O que Todo Dev Deve Saber sobre Observabilidade

O que é Observabilidade? Observabilidade é a capacidade de entender o estado interno de um sistema através de seus sinais externos: logs, métricas e traces. Diferente do monitoramento tradicional, que responde a alertas pré-definidos, observabilidade permite investigar problemas imprevistos sem saber previamente o que procurar. Em um ambiente de microsserviços distribuído, onde uma requisição passa por dezenas de serviços, observabilidade não é luxo — é sobrevivência. A observabilidade se baseia em três pilares fundamentais: logs (eventos discretos), métricas (medições numéricas agregadas) e traces distribuídos (rastreamento de requisições através do sistema). Esses três elementos trabalham juntos para dar visibilidade real do que está acontecendo em produção. Sem observabilidade adequada, você está dirigindo de olhos vendados em uma autoestrada. Pilares da Observabilidade Logs: Narrativa dos Eventos Logs são registros estruturados de eventos que ocorreram no sistema. O erro está em tratá-los como strings soltas — eles devem ser estruturados em JSON ou formato similar, permitindo busca e análise posterior. Métricas: Saúde Numérica

<h2>O que é Observabilidade?</h2>

<p>Observabilidade é a capacidade de entender o estado interno de um sistema através de seus sinais externos: logs, métricas e traces. Diferente do monitoramento tradicional, que responde a alertas pré-definidos, observabilidade permite investigar problemas imprevistos sem saber previamente o que procurar. Em um ambiente de microsserviços distribuído, onde uma requisição passa por dezenas de serviços, observabilidade não é luxo — é sobrevivência.</p>

<p>A observabilidade se baseia em três pilares fundamentais: <strong>logs</strong> (eventos discretos), <strong>métricas</strong> (medições numéricas agregadas) e <strong>traces distribuídos</strong> (rastreamento de requisições através do sistema). Esses três elementos trabalham juntos para dar visibilidade real do que está acontecendo em produção. Sem observabilidade adequada, você está dirigindo de olhos vendados em uma autoestrada.</p>

<h2>Pilares da Observabilidade</h2>

<h3>Logs: Narrativa dos Eventos</h3>

<p>Logs são registros estruturados de eventos que ocorreram no sistema. O erro está em tratá-los como strings soltas — eles devem ser estruturados em JSON ou formato similar, permitindo busca e análise posterior.</p>

<pre><code class="language-python">import json

import logging

from datetime import datetime

Configurar logging estruturado corretamente

class JSONFormatter(logging.Formatter):

def format(self, record):

log_data = {

&#039;timestamp&#039;: datetime.utcnow().isoformat(),

&#039;level&#039;: record.levelname,

&#039;logger&#039;: record.name,

&#039;message&#039;: record.getMessage(),

&#039;module&#039;: record.module,

&#039;function&#039;: record.funcName,

&#039;line&#039;: record.lineno

}

if record.exc_info:

log_data[&#039;exception&#039;] = self.formatException(record.exc_info)

return json.dumps(log_data)

logger = logging.getLogger(__name__)

handler = logging.StreamHandler()

handler.setFormatter(JSONFormatter())

logger.addHandler(handler)

logger.setLevel(logging.INFO)

Uso

try:

resultado = 10 / 0

except Exception as e:

logger.error(&quot;Divisão falhou&quot;, exc_info=True)</code></pre>

<h3>Métricas: Saúde Numérica</h3>

<p>Métricas são valores numéricos coletados continuamente. Evite criar uma métrica para cada detalhe — foque no que realmente importa: latência, taxa de erros, utilização de recursos.</p>

<pre><code class="language-python">from prometheus_client import Counter, Histogram, Gauge, start_http_server

import time

Definir métricas

requisicoes_total = Counter(

&#039;requisicoes_total&#039;,

&#039;Total de requisições processadas&#039;,

[&#039;metodo&#039;, &#039;endpoint&#039;]

)

latencia_requisicao = Histogram(

&#039;latencia_requisicao_segundos&#039;,

&#039;Latência das requisições&#039;,

[&#039;endpoint&#039;],

buckets=(0.1, 0.5, 1.0, 2.0, 5.0)

)

usuarios_ativos = Gauge(

&#039;usuarios_ativos&#039;,

&#039;Número de usuários ativos no momento&#039;

)

Iniciar servidor Prometheus na porta 8000

start_http_server(8000)

Usar as métricas

def processar_requisicao(endpoint):

usuarios_ativos.inc()

inicio = time.time()

Simular processamento

time.sleep(0.3)

duracao = time.time() - inicio

latencia_requisicao.labels(endpoint=endpoint).observe(duracao)

requisicoes_total.labels(metodo=&#039;GET&#039;, endpoint=endpoint).inc()

usuarios_ativos.dec()

Endpoint fica disponível em http://localhost:8000/metrics

processar_requisicao(&#039;/api/usuarios&#039;)</code></pre>

<h3>Traces Distribuídos: Mapa da Jornada</h3>

<p>Um trace mostra o caminho completo de uma requisição através de múltiplos serviços. Cada serviço adiciona spans (segmentos de tempo) que, unidos, formam o trace completo. Essa é a ferramenta mais poderosa para debugar problemas em sistemas distribuídos.</p>

<pre><code class="language-python">from opentelemetry import trace, metrics

from opentelemetry.exporter.jaeger.thrift import JaegerExporter

from opentelemetry.sdk.trace import TracerProvider

from opentelemetry.sdk.trace.export import BatchSpanProcessor

from opentelemetry.instrumentation.flask import FlaskInstrumentor

from opentelemetry.instrumentation.requests import RequestsInstrumentor

from flask import Flask

Configurar Jaeger como backend

jaeger_exporter = JaegerExporter(

agent_host_name=&quot;localhost&quot;,

agent_port=6831,

)

trace.set_tracer_provider(TracerProvider())

trace.get_tracer_provider().add_span_processor(

BatchSpanProcessor(jaeger_exporter)

)

app = Flask(__name__)

Instrumentar Flask e requests automaticamente

FlaskInstrumentor().instrument_app(app)

RequestsInstrumentor().instrument()

tracer = trace.get_tracer(__name__)

@app.route(&#039;/pedido/&lt;pedido_id&gt;&#039;)

def obter_pedido(pedido_id):

with tracer.start_as_current_span(&quot;buscar_pedido&quot;) as span:

span.set_attribute(&quot;pedido.id&quot;, pedido_id)

with tracer.start_as_current_span(&quot;validar_pedido&quot;):

Validação

pass

with tracer.start_as_current_span(&quot;buscar_usuario&quot;):

Query ao banco

pass

return {&quot;status&quot;: &quot;ok&quot;}

if __name__ == &#039;__main__&#039;:

app.run(port=5000)</code></pre>

<h2>Boas Práticas Essenciais</h2>

<h3>Contexto é Tudo</h3>

<p>Adicione contexto relevante a cada log e métrica. Um erro genérico &quot;Falha na requisição&quot; é inútil em produção. Inclua user_id, request_id, ambiente e qualquer dado que ajude na investigação. Use correlation IDs para rastrear uma requisição através de múltiplos serviços.</p>

<h3>Amostragem Inteligente</h3>

<p>Coletar tudo é impossível em alta escala. Implemente amostragem adaptativa: trace 100% dos erros, 10% de requisições lentas e 1% das normais. Ferramentas como Jaeger fazem isso nativamente. Métricas devem ter baixa cardinalidade — evite usar IDs de usuários como label, pois explode a quantidade de séries de tempo.</p>

<h3>Alertas Baseados em SLOs</h3>

<p>Não alerte sobre tudo. Defina Service Level Objectives (SLOs) realistas: &quot;99% das requisições devem responder em menos de 500ms&quot;. Alerte quando você viola seus SLOs, não quando uma métrica sobe um pouco. Isso reduz ruído e aumenta confiabilidade dos alertas.</p>

<h2>Conclusão</h2>

<p>A observabilidade moderna é construída sobre três pilares integrados: logs estruturados para investigação detalhada, métricas para visão agregada da saúde, e traces distribuídos para entender fluxos complexos. Implementar observabilidade desde o início do desenvolvimento é muito mais fácil que adicionar depois. A chave é coletar dados úteis com contexto adequado, evitar ruído e usar ferramentas que conectem esses dados. Todo dev que trabalha com sistemas em produção deve dominar esses conceitos — é o que diferencia profissionais capazes de resolver problemas rapidamente daqueles que ficam presos debugando no escuro.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://opentelemetry.io/docs/" target="_blank" rel="noopener noreferrer">OpenTelemetry Documentation</a></li>

<li><a href="https://prometheus.io/docs/concepts/metric_types/" target="_blank" rel="noopener noreferrer">Prometheus Metrics Types</a></li>

<li><a href="https://www.jaegertracing.io/" target="_blank" rel="noopener noreferrer">Jaeger: Open Source, End-to-End Distributed Tracing</a></li>

<li><a href="https://www.oreilly.com/library/view/distributed-systems-observability/9781492033431/" target="_blank" rel="noopener noreferrer">The Three Pillars of Observability - O&#039;Reilly</a></li>

<li><a href="https://sre.google/sre-book/monitoring-distributed-systems/" target="_blank" rel="noopener noreferrer">Google SRE Book - Monitoring Distributed Systems</a></li>

</ul>

Comentários

Mais em Ferramentas & Produtividade

CI/CD na Prática
CI/CD na Prática

O que é CI/CD e Por Que Importa CI/CD significa Integração Contínua (CI) e En...

Dominando Cache e Performance em Projetos Reais
Dominando Cache e Performance em Projetos Reais

Cache: Fundamentos e Estratégias Práticas Cache é um mecanismo de armazenamen...

Como Usar Docker e Kubernetes em Produção
Como Usar Docker e Kubernetes em Produção

Docker em Produção: Containerização Eficiente Docker é essencial para qualque...