# Runbook: Circuit Breaker Open ## Signal **Alerte déclenchée**: - `VezaCircuitBreakerOpen` - Circuit breaker en état OPEN depuis > 5 minutes **Symptômes observables**: - Métrique: `veza_circuit_breaker_state == 2` (2 = OPEN) - Logs: `circuit breaker opened for [service_name]` - Erreurs: Toutes les requêtes vers le service externe sont rejetées immédiatement - Endpoints affectés: OAuth, Stream service, autres dépendances externes ## Hypothèses 1. **Service externe down** - OAuth provider, Stream server, etc. ne répond plus 2. **Service externe lent** - Timeouts répétés, service surchargé 3. **Réseau** - Problème de connectivité vers service externe 4. **Configuration circuit breaker** - Seuils trop stricts (peu probable) ## Vérifications ### 1. Identifier le circuit breaker affecté ```bash # Vérifier métriques Prometheus curl -s "http://localhost:9090/api/v1/query?query=veza_circuit_breaker_state" | jq # Exemple de réponse: # { # "metric": { # "circuit_breaker_name": "oauth_service" # }, # "value": [1234567890, "2"] # } # 2 = OPEN, 1 = HALF_OPEN, 0 = CLOSED ``` ### 2. Vérifier logs application ```bash # Chercher ouverture circuit breaker grep -i "circuit breaker opened\|circuit breaker open" /var/log/veza-backend-api/*.log | tail -20 # Chercher erreurs service externe grep -i "oauth\|stream.*error\|timeout" /var/log/veza-backend-api/*.log | tail -50 ``` ### 3. Tester service externe directement ```bash # Pour OAuth service (exemple) curl -v https://oauth-provider.example.com/health # Pour Stream service (exemple) curl -v http://stream-server:8082/health # Vérifier timeout timeout 5 curl http:///health ``` ### 4. Vérifier métriques circuit breaker ```bash # Échecs consécutifs curl -s "http://localhost:9090/api/v1/query?query=veza_circuit_breaker_consecutive_failures" | jq # Total échecs curl -s "http://localhost:9090/api/v1/query?query=veza_circuit_breaker_failures_total" | jq # Requêtes rejetées curl -s "http://localhost:9090/api/v1/query?query=veza_circuit_breaker_requests_total{result=\"rejected\"}" | jq ``` ## Actions Correctives ### Si service externe down 1. **Vérifier santé service externe**: - Consulter dashboard/monitoring du service externe - Vérifier logs du service externe - Contacter équipe responsable du service 2. **En attendant réparation**: - **Option A**: Service peut fonctionner en mode dégradé (fonctionnalités optionnelles désactivées) - **Option B**: Si critique, mettre service en maintenance 3. **Documenter impact**: - Quelles fonctionnalités sont affectées? - Combien d'utilisateurs impactés? ### Si service externe lent 1. **Vérifier charge service externe**: ```bash # Si accès monitoring curl http:///metrics | grep cpu\|memory\|requests ``` 2. **Augmenter timeout temporairement** (si configurable): - Modifier timeout dans `internal/services/circuit_breaker.go` - **⚠️ Attention**: Augmenter timeout peut masquer le problème 3. **Contacter équipe service externe**: - Signaler latence élevée - Demander investigation ### Si réseau 1. **Tester connectivité**: ```bash telnet # ou nc -zv ``` 2. **Vérifier firewall/routing**: ```bash traceroute ``` 3. **Vérifier DNS**: ```bash nslookup dig ``` ### Forcer réouverture circuit breaker (si nécessaire) **⚠️ DANGER**: Ne forcer la réouverture que si le service externe est confirmé opérationnel. Le circuit breaker se rouvrira automatiquement après le timeout configuré (généralement 60s). Pour forcer manuellement: 1. **Redémarrer application** (force reset circuit breaker): ```bash sudo systemctl restart veza-backend-api # ou docker restart veza-backend-api ``` 2. **Attendre timeout automatique**: - Circuit breaker passe en HALF_OPEN après timeout - Si prochaine requête réussit → CLOSED - Si prochaine requête échoue → re-OPEN ## Post-Mortem Notes ### À documenter après résolution - **Circuit breaker affecté**: `oauth_service` / `stream_service` / autre - **Cause racine**: Service externe down / Lent / Réseau / Autre - **Durée de l'incident**: De [heure début] à [heure fin] - **Impact**: Fonctionnalités affectées, utilisateurs impactés - **Actions prises**: Liste des actions correctives - **Actions préventives**: - [ ] Améliorer monitoring service externe - [ ] Ajouter alertes côté service externe - [ ] Revoir configuration circuit breaker (seuils, timeout) - [ ] Implémenter fallback/retry logic ### Métriques à surveiller post-incident - `veza_circuit_breaker_state` - Doit revenir à 0 (CLOSED) - `veza_circuit_breaker_consecutive_failures` - Doit revenir à 0 - `veza_circuit_breaker_requests_total{result="success"}` - Doit augmenter - `veza_circuit_breaker_requests_total{result="rejected"}` - Doit s'arrêter d'augmenter ## Configuration Circuit Breaker **Fichier**: `internal/services/circuit_breaker.go` **Paramètres par défaut** (sony/gobreaker): - **MaxRequests**: 3 (half-open state) - **Interval**: 60s (timeout avant réouverture) - **Timeout**: 60s (durée état OPEN) - **ReadyToTrip**: 5 échecs consécutifs → OPEN **Modification** (si nécessaire): ```go cb := gobreaker.NewCircuitBreaker(gobreaker.Settings{ MaxRequests: 3, Interval: 60 * time.Second, Timeout: 60 * time.Second, ReadyToTrip: func(counts gobreaker.Counts) bool { return counts.ConsecutiveFailures > 5 }, }) ``` ## Références - Métriques circuit breaker: `internal/metrics/circuit_breaker.go` - Service circuit breaker: `internal/services/circuit_breaker.go` - Documentation gobreaker: https://github.com/sony/gobreaker