Saltar al contenido
# 🚨 Alerting — SLO-driven monitoring ## 🤔 ¿Qué hago? ¿Cómo lo hago? ¿Y para qué lo hago? **¿Qué hago?** Defino reglas de alertas en Prometheus basadas en violaciones de SLOs — disponibilidad, latencia y cache hit rate. **¿Cómo lo hago?** PrometheusRule CRD (Custom Resource Definition) en Kubernetes con alertas preconfiguradas que evalúan métricas cada 30s. **¿Para qué lo hago?** Sin alertas, los problemas pasan desapercibidos. Con alertas SLO-driven, oncall reacciona antes de que se queme el error budget. --- ## 📋 Alertas de SLO ### 🔵 SLO-1: Disponibilidad < 99.5% **Métrica:** Error rate (5xx) en ventana rolling 5m ```yaml alert: SLOAvailabilityViolation expr: (sum(rate(requests_total{status=~"5.."}[5m])) / sum(rate(requests_total[5m]))) > 0.005 for: 10m severity: critical ``` **Dispara cuando:** - > 0.5% de requests fallan con 5xx durante 10 minutos consecutivos **Error budget:** 3.6 horas/mes **Acción inmediata:** 1. Revisar logs: `kubectl logs -l app=klaus-proxy | grep ERROR` 2. Check Anthropic status page 3. Revisar Qdrant pod metrics 4. Si persiste > 20 min: escalada a SRE lead **Dashboard:** Grafana panel "Error Rate (5m rolling)" --- ### 🟠 SLO-2: Latencia p99 > 2s **Métrica:** Percentil 99 de request_duration_seconds ```yaml alert: SLOLatencyViolation expr: histogram_quantile(0.99, rate(request_duration_seconds_bucket[5m])) > 2 for: 10m severity: warning ``` **Dispara cuando:** - 99% de requests toman > 2 segundos **Error budget:** 7.2 minutos de violaciones/mes **Posibles causas:** - Qdrant saturado (búsquedas lentas) - Anthropic sobrecargado - Network congestion cliente ↔ Anthropic - Embeddings model latente **Acción:** 1. Revisar métricas de Qdrant: `kubectl exec -it qdrant-0 -- qdrant-cli stats` 2. Revisar CPU/memory de Klaus-proxy pods 3. Revisar Anthropic latency en su dashboard 4. Considerar escalado de Qdrant replicas si es necesario **Tuning futuro:** - Fase 2: p99 < 1.5s - Fase 3: p99 < 1s --- ### 🟡 SLO-3: Cache hit rate < 70% **Métrica:** Cache hits / total hits ```yaml alert: SLOCacheHitRateViolation expr: | (sum(rate(cache_hits_total[5m])) / (sum(rate(cache_hits_total[5m])) + sum(rate(cache_misses_total[5m])))) < 0.70 for: 15m severity: info ``` **Dispara cuando:** - Cache hit rate < 70% durante 15 minutos **Error budget:** 9 días/mes con cache disabled **Posibles causas:** - Cache corrupto (flush necesario) - Queries no-cacheables (ej: por fecha/usuario) - Colección llena (evictions) - Bajo hit rate es normal early morning (queries frescas) **Acción:** 1. Revisar cache stats: `curl localhost:8000/cache/stats` 2. Si > 50% evictions: aumentar Qdrant memory o limpiar datos antiguos 3. Analizar query patterns: ¿hay patrones no-cacheables? --- ## 🚨 Emergency Alerts ### 🔴 High Error Rate (> 10%/min) ```yaml alert: HighErrorRate expr: sum(rate(requests_total{status=~"5.."}[1m])) > 0.1 for: 1m severity: critical ``` **Dispara en:** Emergencia total (> 10% de requests con 5xx) **Acción:** Rollback inmediato o escalada a VP Eng --- ### 🔴 Qdrant Connection Failure (> 5% fallos) ```yaml alert: QdrantConnectionFailure expr: (sum(rate(requests_failed_total{error_type=~".*Qdrant.*"}[1m])) / sum(rate(requests_total[1m]))) > 0.05 for: 2m severity: critical ``` **Acción:** - Check Qdrant pod status: `kubectl get pods -l app=qdrant` - Revisar logs: `kubectl logs qdrant-0` - Reiniciar pod si está hung: `kubectl restart pods qdrant-0` --- ### ⚠️ Anthropic Timeout Rate (> 10%) ```yaml alert: AnthropicTimeoutRate expr: (sum(rate(requests_failed_total{error_type=~".*Timeout.*"}[1m])) / sum(rate(requests_total[1m]))) > 0.10 for: 2m severity: warning ``` **Acción:** - Revisar Anthropic status - Increase client-side timeouts si es necesario - Circuit breaker pasará a OPEN automáticamente --- ## ⚙️ Integración con Prometheus ### PrometheusRule en Helm ```yaml # helm/prometheus-rules.yaml apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: klaude-proxy-slo-alerts namespace: klaude spec: groups: - name: slo.availability interval: 30s rules: - alert: SLOAvailabilityViolation expr: ... for: 10m annotations: ... ``` ### Instalación en cluster ```bash # Helm despliega la PrometheusRule helm install klaude ./helm \ --namespace klaude \ --set prometheusRule.enabled=true \ --set prometheusRule.namespace=klaude # Verificar PrometheusRule kubectl get prometheusrules -A kubectl describe prometheusrule klaude-proxy-slo-alerts -n klaude ``` --- ## 📲 Notificación al oncall ### Integración con OpsGenie / Slack / PagerDuty En Prometheus alertmanager.yml: ```yaml # prometheus/alertmanager.yml route: receiver: 'klaude-team' group_by: ['alertname', 'severity'] receivers: - name: 'klaude-team' slack_configs: - api_url: 'https://hooks.slack.com/...' channel: '#klaude-alerts' title: '{{ .GroupLabels.alertname }}' text: '{{ .CommonAnnotations.description }}' pagerduty_configs: - service_key: 'YOUR_SERVICE_KEY' severity: '{{ .GroupLabels.severity }}' ``` --- ## 📊 Recording Rules — Métricas derivadas ```yaml - name: derived_metrics interval: 30s rules: - record: slo:availability:30d expr: | sum(rate(requests_total{status=~"2..|3..|4.."}[30d])) / sum(rate(requests_total[30d])) - record: slo:latency_p99:5m expr: histogram_quantile(0.99, rate(request_duration_seconds_bucket[5m])) - record: slo:cache_hit_rate:5m expr: | sum(rate(cache_hits_total[5m])) / (sum(rate(cache_hits_total[5m])) + sum(rate(cache_misses_total[5m]))) ``` --- ## 🎯 Error Budget Management ### Tracking error budget ```promql # Error budget quemado en 30 días slo:error_budget_used:30d = (1 - slo:availability:30d) / (1 - 0.995) * 100 # Si > 100%, SLO violado ``` ### Tabla de decisiones | Error budget | Decisión | | --- | --- | | **> 90% usado** | 🟡 Freeze de cambios no-críticos. Solo hotfixes. | | **> 75% usado** | 🟡 Desacelerar PRs. Extra testing antes de merge. | | **< 50% usado** | 🟢 Velocidad normal. Experi mentación permitida. | | **< 25% usado** | 🟢 Abierto para innovación. Cambios arriesgados OK. | --- ## 🧪 Testing de alertas ### Test de sintaxis ```bash promtool check rules helm/prometheus-rules.yaml ``` ### Simular violación (en desarrollo) ```bash # Inyectar métrica fake que cause alert curl -X POST http://localhost:9091/metrics/job/test \ -d 'requests_total{status="500"} 1000' # Verificar alert en Prometheus UI # http://localhost:9090/alerts ``` --- ## 📈 Dashboard recomendado (Grafana) ``` ┌─────────────────────────────────────────────────────────┐ │ Klaus-proxy SLO Dashboard │ ├─────────────────────────────────────────────────────────┤ │ 📊 Availability (30d) │ 🕐 Latency p99 (5m) │ │ 99.52% (SLO: 99.5%) │ 1.8s (SLO: < 2s) │ ├──────────────────────────────────────────────────────────┤ │ 💾 Cache Hit Rate (5m) │ 🚨 Error Rate (1m) │ │ 73% (SLO: > 70%) │ 0.3% (SLO: < 0.5%) │ ├──────────────────────────────────────────────────────────┤ │ 📈 Request Volume (rate/s) │ 🔌 Circuit Breaker Status │ │ 250 req/s │ Forward: CLOSED │ │ │ Stream: CLOSED │ └──────────────────────────────────────────────────────────┘ ``` --- ## 🚀 Mejoras futuras - [ ] Alerting por percentil dinámico (p95, p50) - [ ] Correlación de eventos (alert cuando múltiples SLOs violan) - [ ] Runbook automático (botón para ejecutar diagnostic) - [ ] Predictive alerting (ML en anomalías de tráfico) - [ ] SLO burn rate alerts (% de error budget quemado por hora) --- ## 📚 Referencias - [Prometheus Alerting Docs](https://prometheus.io/docs/alerting/latest/overview/) - [Google SRE — Monitoring Distributed Systems](https://sre.google/sre-book/monitoring-distributed-systems/) - [Prometheus AlertManager](https://github.com/prometheus/alertmanager)