← Voltar para publicações Monitoramento Proativo com Python: painel com gráficos, logs e alertas

Monitoramento Proativo com Python: Logs Inteligentes e Alertas Automatizados

Logo Cara Core Cara Core Informática 81 seguidores
11 de agosto de 2025

Você já esbarrou na sigla MTTR? Se ainda não, vale 2 minutos para entender por que ela virou o indicador nº 1 em times de operação e produto. No fim deste artigo deixei um adendo simples sobre MTTR — pode conferir depois ou pular direto agora.

O ponto crucial é: reduzir o MTTR exige não esperar o usuário reclamar. É aqui que entra o monitoramento proativo: logs inteligentes que dão contexto e alertas automatizados que acionam a equipe na hora certa.

Neste guia colaborativo, mostramos como implementar isso em Python com padrões prontos para produção: logs JSON estruturados, enriquecimento de contexto, rotação/retenção e um monitor simples com alerta via Slack.

Por que proativo?

Pilares e escopo

Observabilidade combina logs, métricas e traces. Aqui focamos em logs como base para alertas eficazes, sem lock-in de ferramenta.

Logs Inteligentes (JSON + contexto)

Padrões recomendados:

Setup rápido (logging JSON + rotação)

import json, logging, sys
from logging.handlers import RotatingFileHandler

class JsonFormatter(logging.Formatter):
    def format(self, record):
        base = {
            "timestamp": self.formatTime(record, "%Y-%m-%dT%H:%M:%S%z"),
            "level": record.levelname,
            "message": record.getMessage(),
            "logger": record.name,
            "service": getattr(record, "service", "app"),
            "env": getattr(record, "env", "prod"),
            "trace_id": getattr(record, "trace_id", None),
            "user_id": getattr(record, "user_id", None),
        }
        return json.dumps({k: v for k, v in base.items() if v is not None})

def get_logger(name: str = "app") -> logging.Logger:
    logger = logging.getLogger(name)
    logger.setLevel(logging.INFO)
    if logger.handlers:
        return logger  # evita handlers duplicados

    fmt = JsonFormatter()

    console = logging.StreamHandler(sys.stdout)
    console.setFormatter(fmt)

    file_handler = RotatingFileHandler("logs/app.log", maxBytes=2_000_000, backupCount=5)
    file_handler.setFormatter(fmt)

    logger.addHandler(console)
    logger.addHandler(file_handler)
    return logger

log = get_logger("orders")
log = logging.LoggerAdapter(log, {"service": "orders", "env": "prod"})

log.info("service_started", extra={"trace_id": "abc123"})

Enriquecimento de contexto

import logging

class ContextFilter(logging.Filter):
    def __init__(self, **base):
        super().__init__()
        self.base = base
    def filter(self, record):
        for k, v in self.base.items():
            setattr(record, k, v)
        return True

logger = get_logger("payments")
logger.addFilter(ContextFilter(service="payments", env="prod"))
logger.info("payment_approved", extra={"trace_id": "t-991", "user_id": "u-42", "amount": 129.90})

Alertas Automatizados (práticos e acionáveis)

Boas práticas:

Exemplo: alerta simples via Slack

import os, json, time, logging, requests
from collections import deque

SLACK_WEBHOOK = os.getenv("SLACK_WEBHOOK_URL")
LOGFILE = "logs/app.log"
WINDOW_SEC = 60
THRESHOLD = 5

def send_slack(text: str):
    if not SLACK_WEBHOOK:
        return
    requests.post(SLACK_WEBHOOK, json={"text": text}, timeout=5)

def tail_errors(path: str):
    with open(path, "r", encoding="utf-8") as f:
        f.seek(0, 2)
        while True:
            line = f.readline()
            if not line:
                time.sleep(0.5); continue
            try:
                evt = json.loads(line)
                if evt.get("level") in {"ERROR", "CRITICAL"}:
                    yield evt
            except Exception:
                continue

def monitor():
    window = deque()
    for evt in tail_errors(LOGFILE):
        now = time.time()
        window.append(now)
        while window and now - window[0] > WINDOW_SEC:
            window.popleft()
        if len(window) >= THRESHOLD:
            sample = evt.get("message")
            send_slack(f"Alerta: {len(window)} erros em {WINDOW_SEC}s no serviço {evt.get('service')}. Ex.: {sample}")
            window.clear()

# monitor()

Checklists rápidas

Privacidade e Compliance

Integrações comuns

Seção Colaborativa

Este artigo é colaborativo. Envie melhorias, exemplos e playbooks reais que funcionaram para você. Podemos incluir:

Para contribuir: envie um e-mail, compartilhe via LinkedIn ou proponha um snippet pronto para inclusão.

ROI e próximos passos


Contato


Adendo: o que é MTTR? (explicação simples)

MTTR é a sigla para Mean Time To Repair/Recover/Resolve — em português, tempo médio para recuperar ou resolver um incidente. É uma métrica que mostra quanto tempo, em média, um serviço fica indisponível até voltar ao normal após um problema.

Como calcular (bem simples):

MTTR = (tempo total de indisponibilidade no período) ÷ (número de incidentes)

Por que importa:

Exemplo rápido: se, em um mês, seu sistema ficou 2 horas indisponível somando 4 incidentes, o MTTR foi 30 minutos por incidente (2h ÷ 4 = 0,5h).

Como reduzir o MTTR na prática: