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
- Formato JSON estruturado: Facilita parsing e análise
- Trace IDs: Correlação de requests através de múltiplos serviços
- Context variables: Thread-safe para trace_id, org_id, user_id
- Middleware FastAPI: Logging automático de requests/responses
- Integração com loguru: Biblioteca de logging moderna e poderosa
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
- Geração: O middleware gera um trace ID único para cada request (ou usa
X-Trace-Iddo header se presente) - Propagação: O trace ID é incluído automaticamente em todos os logs
- 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:
- trace_id: ID único do request
- org_id: ID da organização (extraído do path ou header)
- user_id: ID do usuário (extraído do header
X-User-Id)
Esses valores são automaticamente incluídos em todos os logs.
Middleware FastAPI
O middleware create_logging_middleware automaticamente:
- Gera ou extrai trace ID do header
X-Trace-Id - Extrai
org_iddo path (se presente) - Extrai
user_iddo headerX-User-Id - Loga request (método, path, query params, IP, user-agent)
- Loga response (status code, tempo de processamento)
- Loga erros com stack trace completo
- Adiciona trace ID no header da resposta
- 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)
- 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}"
}
}
- Logs serão indexados automaticamente com todos os campos estruturados
AWS CloudWatch
- 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
- 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
- DEBUG: Informações detalhadas para debugging
- INFO: Informações gerais sobre operações
- WARNING: Avisos sobre situações anômalas
- ERROR: Erros que não impedem a operação
- CRITICAL: Erros críticos que impedem a operação
Boas Práticas
- Use JSON em produção: Facilita parsing e análise
- Use texto em desenvolvimento: Mais legível para humanos
- Inclua contexto relevante: customer_id, org_id, decision_id, etc.
- Não logue dados sensíveis: Senhas, tokens, PII sem mascaramento
- Use trace IDs: Sempre propague trace IDs entre serviços
- Logue erros com exc_info=True: Inclui stack trace completo
- Configure rotação de logs: Evite arquivos muito grandes
- 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
- Verifique se
setup_logging()foi chamado - Verifique nível de log (pode estar muito alto)
- Verifique permissões de arquivo (se usando log_file)
Trace IDs não funcionam
- Verifique se middleware foi adicionado
- Verifique se está usando
get_logger()e nãologging.getLogger() - Verifique se contexto não foi limpo prematuramente
Logs muito verbosos
- Aumente nível de log:
log_level="WARNING" - Filtre logs por módulo no sistema de log centralizado
- Use
logger.debug()apenas para debugging
Próximos Passos
- ✅ Módulo de logging criado
- ⏳ Migrar apps existentes para usar
common_logging - ⏳ Configurar coleta de logs centralizada (ELK/CloudWatch)
- ⏳ Criar dashboards no Kibana/Grafana
- ⏳ Configurar alertas baseados em logs