Tracing com OpenTelemetry: métricas, logs e alertas no Grafana

Tracing com OpenTelemetry: métricas, logs e alertas no Grafana
Resumo – Este artigo mostra, passo a passo, como construir uma camada de observabilidade unificada usando OpenTelemetry, Prometheus, Grafana Loki e Alertmanager. Você vai entender a coleta de métricas, o armazenamento de logs estruturados, a geração de traces distribuídos e a configuração de alertas inteligentes, tudo integrado a painéis interativos no Grafana.
Introdução
Em ambientes de produção modernos, saber o que está acontecendo dentro de uma aplicação é tão importante quanto garantir que ela continue disponível. A observabilidade – a capacidade de inferir o estado interno de um sistema a partir de seus sinais externos – combina três pilares:
| Pilar | O que representa |
|---|---|
| Métricas | Valores numéricos ao longo do tempo (CPU, latência, contadores) |
| Logs | Eventos textuais ou estruturados que descrevem ocorrências |
| Traces | Jornada de uma requisição através de múltiplos serviços |
Quando esses três são coletados, correlacionados e visualizados em um único lugar, equipes de SRE e desenvolvedores ganham visibilidade total, reduzindo MTTR (Mean Time to Recovery) e aumentando a confiança nas entregas.
Neste guia, vamos montar essa pilha usando ferramentas open source:
Prometheus – coleta e armazena métricas. Grafana Loki – ingestão e consulta de logs via LogQL. OpenTelemetry – SDK e Collector para gerar métricas, logs e traces. Alertmanager – roteamento e silenciamento de alertas. Grafana – visualização, dashboards e painéis de alertas.
Ao final, você terá um ambiente pronto para monitorar aplicações containerizadas (Docker/Kubernetes) ou serviços tradicionais.
1. Coletando métricas com Prometheus
1.1 Por que Prometheus?
Prometheus foi projetado para scrape de endpoints HTTP que expõem métricas no formato exposition. Ele armazena séries temporais em um banco de dados de alta compressão e oferece a linguagem de consulta PromQL, ideal para criar alertas e dashboards.
1.2 Configurando o Exporter
Suponha que sua aplicação seja escrita em Python. Vamos usar o cliente oficial prometheus_client para expor um endpoint /metrics.
# app_metrics.py
from prometheus_client import Counter, Histogram, start_http_server
import time
import random
Métricas
REQUEST_COUNT = Counter('http_requests_total', 'Total HTTP requests', ['method', 'endpoint'])
REQUEST_LATENCY = Histogram('http_request_duration_seconds', 'Latency of HTTP requests', ['endpoint'])
def handle_request(endpoint: str):
REQUEST_COUNT.labels(method='GET', endpoint=endpoint).inc()
with REQUEST_LATENCY.labels(endpoint=endpoint).time():
# Simula processamento
time.sleep(random.uniform(0.05, 0.3))
if __name__ == '__main__':
# Inicia servidor de métricas na porta 8000
start_http_server(8000)
while True:
handle_request('/api/v1/items')
time.sleep(1)
Execute o script:
python app_metrics.py
Agora, http://localhost:8000/metrics exibe algo como:
# HELP http_requests_total Total HTTP requests
TYPE http_requests_total counter
http_requests_total{method="GET",endpoint="/api/v1/items"} 42.0
HELP http_request_duration_seconds Latency of HTTP requests
TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{endpoint="/api/v1/items",le="0.1"} 30.0
...
1.3 Scrape no Prometheus
Crie o arquivo prometheus.yml:
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'python_app'
static_configs:
- targets: ['host.docker.internal:8000'] # ajuste para seu host/Docker
Inicie o Prometheus:
docker run -d \
-p 9090:9090 \
-v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
Acesse http://localhost:9090 e teste a query:
rate(http_requests_total[1m])
1.4 Exportando métricas customizadas
Para serviços críticos, você pode criar gauges e summary. Exemplo de gauge que indica o número de jobs pendentes:
from prometheus_client import Gauge
PENDING_JOBS = Gauge('jobs_pending', 'Número de jobs em fila')
PENDING_JOBS.set(7) # Atualiza dinamicamente conforme sua fila
2. Centralizando logs com Grafana Loki
2.1 O que é Loki?
Loki é um log aggregation system que funciona como o “Prometheus dos logs”. Em vez de indexar todo o conteúdo, ele indexa apenas rótulos (labels), reduzindo custos e facilitando a correlação com métricas.
2.2 Instalando Loki e Promtail
docker run -d --name=loki -p 3100:3100 grafana/loki:2.9.2
docker run -d --name=promtail \
-v /var/log:/var/log \
-v $(pwd)/promtail-config.yml:/etc/promtail/config.yml \
grafana/promtail:2.9.2 -config.file=/etc/promtail/config.yml
promtail-config.yml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log//.log
2.3 Enviando logs estruturados da aplicação
Modifique o script Python para usar structlog e enviar logs para Loki via promtail (ou via HTTP push). Exemplo simplificado usando requests:
# app_logging.py
import structlog, time, random, requests, json
logger = structlog.get_logger()
LOKI_ENDPOINT = "http://localhost:3100/loki/api/v1/push"
def push_to_loki(entry: dict):
payload = {
"streams": [
{
"stream": {"job": "python_app"},
"values": [[str(int(time.time()1e9)), json.dumps(entry)]]
}
]
}
requests.post(LOKI_ENDPOINT, json=payload)
def process():
logger.info("process_start", item_id=random.randint(1, 100))
# Simula trabalho
time.sleep(random.uniform(0.1, 0.4))
logger.info("process_end", status="ok")
if __name__ == "__main__":
while True:
process()
# Também envia para Loki
push_to_loki({"msg": "heartbeat", "ts": time.time()})
time.sleep(2)
Os logs aparecerão em Loki com rótulo job="python_app". No Grafana, você pode consultar usando LogQL:
{job="python_app"} |= "process_end"
2.4 Visualizando logs no Grafana
http://localhost:3100).3. Distribuindo traces com OpenTelemetry
3.1 Conceitos básicos
Tracer – cria spans que representam unidades de trabalho. Span – contém início, fim, atributos e eventos. Exporter – envia spans para um backend (ex.: Jaeger, Tempo).
3.2 Configurando o Collector
O OpenTelemetry Collector pode receber dados via OTLP (gRPC/HTTP) e enviá‑los ao Grafana Tempo, um backend de traces otimizado para alta escala.
```yaml
otel-collector-config.yaml
receivers: otlp: protocols: grpc:


