Logging

Logging Centralizado - C-Suite

Visão Geral

Este documento descreve o padrão de logging centralizado para o ecossistema C-Suite. O objetivo é padronizar logs em formato JSON estruturado, facilitar correlação de requests através de trace IDs, e integrar com sistemas de log centralizados (ELK, CloudWatch, etc.).

Módulo de Logging

Localização

O módulo principal está em: common_logging.py (raiz do projeto)

Características

Uso Básico

1. Configurar Logging no Início da Aplicação

from fastapi import FastAPI
from common_logging import setup_logging, create_logging_middleware

app = FastAPI()

# Configurar logging
setup_logging(
    app_name="4c-decision-api",
    log_level="INFO",
    log_format="json",  # ou "text" para desenvolvimento
    structured=True
)

# Adicionar middleware de logging
app.middleware("http")(create_logging_middleware("4c-decision-api"))

2. Usar Logger em Módulos

from common_logging import get_logger

logger = get_logger(__name__)

# Log simples
logger.info("Processando decisão")

# Log com dados extras
logger.info(
    "Decisão criada",
    extra={
        "customer_id": 123,
        "decision_id": "abc-123",
        "intent_score": 0.85
    }
)

# Log de erro
try:
    # código que pode falhar
    pass
except Exception as e:
    logger.error("Erro ao processar decisão", exc_info=True)

3. Usar Trace IDs Manualmente

from common_logging import set_trace_id, get_logger

# Definir trace ID (geralmente feito pelo middleware)
set_trace_id("abc-123-def")

logger = get_logger(__name__)
logger.info("Mensagem")  # Trace ID será incluído automaticamente

Formato de Log

JSON Estruturado (Produção)

{
  "timestamp": "2024-12-01T14:30:00.123Z",
  "level": "INFO",
  "app": "4c-decision-api",
  "message": "Decisão criada",
  "module": "api.decision",
  "function": "create_decision",
  "line": 42,
  "trace_id": "abc-123-def",
  "org_id": 1,
  "user_id": "user-456",
  "customer_id": 123,
  "decision_id": "dec-789"
}

Formato Texto (Desenvolvimento)

2024-12-01 14:30:00 | INFO     | api.decision:create_decision:42 | Decisão criada

Trace IDs

O que são Trace IDs?

Trace IDs são identificadores únicos que permitem rastrear um request através de múltiplos serviços. Isso é essencial em arquiteturas de microserviços.

Como Funciona

  1. Geração: O middleware gera um trace ID único para cada request (ou usa X-Trace-Id do header se presente)
  2. Propagação: O trace ID é incluído automaticamente em todos os logs
  3. Correlação: Todos os logs relacionados ao mesmo request compartilham o mesmo trace ID

Exemplo de Fluxo

Request → Service A (trace_id: abc-123)
  ├─ Log: "Request recebido" (trace_id: abc-123)
  └─ Chama Service B com header X-Trace-Id: abc-123
      ├─ Log: "Processando" (trace_id: abc-123)
      └─ Chama Service C com header X-Trace-Id: abc-123
          └─ Log: "Finalizado" (trace_id: abc-123)

Propagação Manual

Se você fizer chamadas HTTP para outros serviços, inclua o trace ID:

from common_logging import get_trace_id
import httpx

trace_id = get_trace_id()
headers = {"X-Trace-Id": trace_id} if trace_id else {}
response = httpx.get("http://other-service/api", headers=headers)

Context Variables

O módulo usa context variables (thread-safe) para armazenar:

Esses valores são automaticamente incluídos em todos os logs.

Middleware FastAPI

O middleware create_logging_middleware automaticamente:

  1. Gera ou extrai trace ID do header X-Trace-Id
  2. Extrai org_id do path (se presente)
  3. Extrai user_id do header X-User-Id
  4. Loga request (método, path, query params, IP, user-agent)
  5. Loga response (status code, tempo de processamento)
  6. Loga erros com stack trace completo
  7. Adiciona trace ID no header da resposta
  8. Limpa contexto após request

Exemplo de Uso

from fastapi import FastAPI
from common_logging import setup_logging, create_logging_middleware

app = FastAPI()

setup_logging(app_name="my-app")
app.middleware("http")(create_logging_middleware("my-app"))

@app.get("/api/endpoint")
async def my_endpoint():
    # Logs automáticos já configurados!
    return {"status": "ok"}

Integração com Sistemas Centralizados

ELK Stack (Elasticsearch, Logstash, Kibana)

  1. Configurar Logstash para receber logs JSON:
input {
  file {
    path => "/var/log/my-app/*.log"
    codec => "json"
  }
}

filter {
  json {
    source => "message"
  }
}

output {
  elasticsearch {
    hosts => ["localhost:9200"]
    index => "csuite-logs-%{+YYYY.MM.dd}"
  }
}
  1. Logs serão indexados automaticamente com todos os campos estruturados

AWS CloudWatch

  1. Instalar CloudWatch Logs Agent:
wget https://s3.amazonaws.com/aws-cloudwatch/downloads/latest/awslogs-agent-setup.py
sudo python3 awslogs-agent-setup.py --region us-east-1
  1. Configurar /etc/awslogs/awslogs.conf:
[/var/log/my-app/app.log]
datetime_format = %Y-%m-%d %H:%M:%S
file = /var/log/my-app/app.log
log_group_name = /csuite/my-app
log_stream_name = {instance_id}

Docker Logs

Se usando Docker, logs JSON podem ser coletados diretamente:

docker logs my-container | jq '.'

Níveis de Log

Boas Práticas

  1. Use JSON em produção: Facilita parsing e análise
  2. Use texto em desenvolvimento: Mais legível para humanos
  3. Inclua contexto relevante: customer_id, org_id, decision_id, etc.
  4. Não logue dados sensíveis: Senhas, tokens, PII sem mascaramento
  5. Use trace IDs: Sempre propague trace IDs entre serviços
  6. Logue erros com exc_info=True: Inclui stack trace completo
  7. Configure rotação de logs: Evite arquivos muito grandes
  8. Monitore logs: Configure alertas para erros críticos

Exemplos por App

4c Decision API

from common_logging import setup_logging, create_logging_middleware

app = FastAPI()

setup_logging(
    app_name="4c-decision-api",
    log_level=os.getenv("LOG_LEVEL", "INFO"),
    log_format="json" if os.getenv("ENV") == "production" else "text"
)

app.middleware("http")(create_logging_middleware("4c-decision-api"))

csuite-executive

from common_logging import setup_logging, create_logging_middleware

app = FastAPI()

setup_logging(
    app_name="csuite-executive",
    log_level="INFO",
    log_file="/var/log/csuite-executive/app.log"
)

app.middleware("http")(create_logging_middleware("csuite-executive"))

4c-suite

from common_logging import setup_logging, create_logging_middleware

app = FastAPI()

setup_logging(app_name="4c-suite")
app.middleware("http")(create_logging_middleware("4c-suite"))

Variáveis de Ambiente

# Nível de log
LOG_LEVEL=INFO  # DEBUG, INFO, WARNING, ERROR, CRITICAL

# Formato de log
LOG_FORMAT=json  # json ou text

# Arquivo de log (opcional)
LOG_FILE=/var/log/my-app/app.log

# Ambiente
ENV=production  # production, staging, development

Troubleshooting

Logs não aparecem

  1. Verifique se setup_logging() foi chamado
  2. Verifique nível de log (pode estar muito alto)
  3. Verifique permissões de arquivo (se usando log_file)

Trace IDs não funcionam

  1. Verifique se middleware foi adicionado
  2. Verifique se está usando get_logger() e não logging.getLogger()
  3. Verifique se contexto não foi limpo prematuramente

Logs muito verbosos

  1. Aumente nível de log: log_level="WARNING"
  2. Filtre logs por módulo no sistema de log centralizado
  3. Use logger.debug() apenas para debugging

Próximos Passos

  1. ✅ Módulo de logging criado
  2. ⏳ Migrar apps existentes para usar common_logging
  3. ⏳ Configurar coleta de logs centralizada (ELK/CloudWatch)
  4. ⏳ Criar dashboards no Kibana/Grafana
  5. ⏳ Configurar alertas baseados em logs

🔊 Text-to-Speech

1.0x
1.0
Pronto para reproduzir