Observabilidade Enterprise

Observability Stack

Sistema completo de observabilidade com métricas de negócio, tracing distribuído, monitoramento de custos de tokens, telemetria de decisões de IA e alertas em tempo real.

4
Pilares MELT
50+
Métricas Custom
100%
Trace Coverage
<5min
MTTR Debug

Por Que Observabilidade é Crítica

Em sistemas de IA conversacional, "não funcionou" não é um diagnóstico. Precisamos responder perguntas específicas:

  • ?Debug: Por que o AI não entendeu "quero marcar amanhã"?
  • ?Performance: Qual nó do LangGraph está lento?
  • ?Custos: Quanto estamos gastando em tokens por tenant?
  • ?Negócio: Qual % das conversas resolvemos sem humano?
  • ?Qualidade: O RAG está retornando preços corretos?

Stack Completo

📊 Business Metrics (Prometheus)

Métricas de negócio com ownership claro por serviço (evita double counting):

MétricaOwnerLabels
optimus_handover_requests_total Orchestratortenant_id, reason, outcome
optimus_ai_conversations_total AI Enginetenant_id, resolved_by
optimus_booking_attempts_total Memory Enginetenant_id, status
optimus_ai_first_response_seconds AI Enginetenant_id (histogram)

Ownership Table: Cada métrica tem um único serviço responsável por emiti-la, evitando contagem dupla em sistemas distribuídos.: Cada métrica tem um único serviço responsável por emiti-la, evitando contagem dupla em sistemas distribuídos.

🔍 Distributed Tracing (OpenTelemetry)

Tracing end-to-end com propagação de contexto entre serviços:

Request → Orchestrator → AI Engine → Memory Engine → PostgreSQL
   │           │             │            │
   │           │             │            └── db.query span
   │           │             └── langgraph.node spans (20+)
   │           └── chat.orchestration span
   └── http.request span

trace_id: a1b2c3d4... (propagado via headers)
              
Instrumentação Automática
  • • FastAPI requests/responses
  • • HTTPX client calls
  • • SQLAlchemy queries
  • • Redis operations
Spans Customizados
  • • LangGraph node execution
  • • RAG search decisions
  • • Booking FSM transitions
  • • LLM API calls + tokens

💰 Token Usage & Cost Tracking

Relatórios de uso de tokens via Jaeger traces para controle de custos:

GET /api/token-reports?tenant_id=clinic2&days=30

{
  "tenant_id": "clinic2",
  "total_input_tokens": 1_250_000,
  "total_output_tokens": 450_000,
  "total_cost": 42.50,  // USD estimated
  "models_breakdown": {
    "gpt-4o-mini": {"tokens": 1_500_000, "cost": 15.00},
    "gpt-4o": {"tokens": 200_000, "cost": 27.50}
  },
  "daily_usage": {
    "2025-01-15": {"tokens": 50_000, "cost": 1.50},
    ...
  }
}
              

Dados extraídos de spans OpenTelemetry com atributos llm.input_tokens, llm.output_tokens, llm.model.

📸 State Snapshot Telemetry

Cada response inclui snapshot do estado para debug de conversas:

response_metadata.state_snapshot = {
  "appointment_confirmed": true,
  "booking_id": "apt_12345",
  "booking_datetime": "2025-01-20T10:00:00",
  "pending_action": null,
  "user_intent": "schedule",
  "customer_name": "João Silva",
  "tool_budget_reached": false,
  "tool_calls_used": 3,
  "tool_budget_max": 6
}
              

🎯 RAG Decision Telemetry

Explicabilidade de decisões do pipeline de pricing/RAG:

{
  "total_entries": 10,
  "match_types": {
    "structured": 8,   // Direct catalog match
    "semantic": 2,     // Embeddings match
    "alias": 0,        // Synonym match
    "fallback": 0      // Generic fallback
  },
  "score_stats": {"avg": 0.89, "min": 0.82, "max": 0.95},
  "fallback_rate": 0.0,
  "reasoning_samples": [
    {"item": "hemograma", "reason": "exact_match", "score": 0.95}
  ]
}
              

Permite identificar: catálogo incompleto, aliases faltando, threshold de score inadequado.

📡 Usage Monitoring Middleware

Monitoramento de endpoints para decisões de deprecação:

  • Non-intrusive: Não bloqueia requests, apenas observa
  • Sample rate: Configurável por ambiente (prod: 1%, dev: 100%)
  • 30+ days data: Coleta dados antes de decisões de remoção
  • Endpoint tracking: Identifica endpoints legados ainda em uso

📈 Performance Thresholds

Thresholds automáticos para alertas:

⚠️ Warning
  • • memory_retrieval_latency > 100ms
  • • cache_hit_rate < 80%
  • • error_rate > 1%
🚨 Critical
  • • memory_retrieval_latency > 500ms
  • • cache_hit_rate < 60%
  • • error_rate > 5%

Arquitetura

┌─────────────────────────────────────────────────────────────┐
│                 OBSERVABILITY STACK                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│   ┌─────────────┐  ┌─────────────┐  ┌─────────────┐        │
│   │ Orchestrator│  │  AI Engine  │  │Memory Engine│        │
│   │  metrics    │  │  metrics    │  │  metrics    │        │
│   └──────┬──────┘  └──────┬──────┘  └──────┬──────┘        │
│          │                │                │                │
│          └────────────────┼────────────────┘                │
│                           │                                 │
│   ┌───────────────────────▼─────────────────────────────┐  │
│   │              PROMETHEUS                              │  │
│   │  - Business metrics (handover, booking, AI)         │  │
│   │  - System metrics (latency, errors, cache)          │  │
│   │  - Custom metrics (RAG, tool budget)                │  │
│   └───────────────────────┬─────────────────────────────┘  │
│                           │                                 │
│   ┌───────────────────────▼─────────────────────────────┐  │
│   │              GRAFANA DASHBOARDS                      │  │
│   │  - Real-time KPIs per tenant                        │  │
│   │  - Cost tracking & forecasting                      │  │
│   │  - Alert rules & notifications                      │  │
│   └─────────────────────────────────────────────────────┘  │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐  │
│   │              OPENTELEMETRY + JAEGER                  │  │
│   │  - Distributed traces across services               │  │
│   │  - Token usage extraction from spans                │  │
│   │  - Latency breakdown per operation                  │  │
│   └─────────────────────────────────────────────────────┘  │
│                                                             │
│   ┌─────────────────────────────────────────────────────┐  │
│   │              LOKI + JSON LOGS                        │  │
│   │  - Structured logging with trace correlation        │  │
│   │  - trace_id + span_id in every log entry            │  │
│   │  - Searchable by tenant, operation, error           │  │
│   └─────────────────────────────────────────────────────┘  │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Decisões Técnicas

Por que ownership table para métricas?

Em sistemas distribuídos, múltiplos serviços podem observar o mesmo evento. Sem ownership claro, métricas de handover seriam emitidas pelo Orchestrator E pelo AI Engine, causando double counting. Ownership table define um único emissor por métrica.

Por que extrair tokens de traces e não de logs?

Traces têm estrutura padronizada (span attributes) e contexto (trace_id liga request a response). Logs são texto livre que requer parsing. Jaeger já indexa spans por atributo, facilitando queries como "total tokens por modelo no último mês".

Por que state snapshot em response_metadata?

Debugging de conversas requer saber o estado exato após cada turno. Incluir snapshot no response permite reproduzir problemas sem acessar logs ou traces. Frontend pode mostrar "estado interno" em modo debug.

Por que sample rate configurável?

Em produção com milhões de requests, 100% sampling é caro (storage, processing). 1-10% sampling captura anomalias suficientes para debug. Em dev/staging, 100% permite debug completo de cada request.

Stack Técnica

PrometheusGrafanaOpenTelemetryJaegerLokistructlogpythonjsonloggerprometheus_client