# Rapport: Hardening Production Semaine 1 - veza-backend-api **Date**: 2025-12-15 **Objectif**: Transformer veza-backend-api en service exploitable sereinement la 1ère semaine de prod **Approche**: Améliorations incrémentales, testées, directement actionnables --- ## Résumé Exécutif ### ✅ Livrables Complétés 1. **Alerting Prometheus** - 8 alertes critiques configurées 2. **Runbooks** - 3 runbooks incident-ready (DB down, circuit breaker, upload stuck) 3. **Contrat Erreurs** - Test de contrat ajouté, endpoints critiques standardisés 4. **Load Tests** - Script k6 reproductible avec seuils définis ### 📊 État Actuel - **Alertes**: ✅ Configurées et documentées - **Runbooks**: ✅ Prêts pour incidents - **Tests**: ✅ Contrat erreurs + load tests - **Documentation**: ✅ Complète et actionnable --- ## 1. Alerting Prometheus ### Fichiers Créés - `ops/prometheus/alerts.yml` - Règles d'alerte Prometheus - `ops/prometheus/README.md` - Documentation activation et configuration ### Alertes Configurées #### Critiques (Critical) 1. **VezaCircuitBreakerOpen** - **Condition**: Circuit breaker OPEN > 5 minutes - **Métrique**: `veza_circuit_breaker_state == 2` - **Action**: Vérifier service externe (OAuth/Stream), consulter runbook 2. **VezaDBPoolExhausted** - **Condition**: Taux d'attente DB pool > 0.1/s pendant 2 min - **Métrique**: `rate(veza_db_pool_wait_count_total[5m]) > 0.1` - **Action**: Vérifier DB, connexions bloquantes, consulter runbook 3. **VezaHigh5xxAbsolute** - **Condition**: > 10 erreurs 5xx/seconde pendant 2 min - **Métrique**: `sum(rate(veza_gin_http_requests_total{status=~"5.."}[5m])) > 10` - **Action**: Investigation immédiate, vérifier logs 4. **VezaReadinessFailed** - **Condition**: Service down (up == 0) > 1 min - **Métrique**: `up{job="veza-backend-api"} == 0` - **Action**: Redémarrer service, vérifier health #### Warnings 5. **VezaDBPoolHighUsage** - **Condition**: DB pool > 80% (20/25 connexions) pendant 5 min - **Métrique**: `veza_db_pool_open_connections > 20` - **Action**: Surveiller, vérifier requêtes lentes 6. **VezaHigh5xxRate** - **Condition**: Taux erreurs 5xx > 5% pendant 5 min - **Métrique**: `(sum(rate(5xx)) / sum(rate(all))) > 0.05` - **Action**: Investigation, vérifier logs 7. **VezaHighLatencyCriticalEndpoints** - **Condition**: Latence P95 > 1s sur endpoints critiques pendant 5 min - **Métrique**: `histogram_quantile(0.95, veza_gin_http_request_duration_seconds) > 1.0` - **Action**: Vérifier performance, DB, dépendances 8. **VezaHealthDegraded** - **Condition**: Service en mode dégradé > 10 min - **Métrique**: `veza_health_check_status < 1` - **Action**: Vérifier services optionnels (Redis/RabbitMQ) ### Activation Voir `ops/prometheus/README.md` pour instructions détaillées. **Résumé**: 1. Copier `alerts.yml` dans `/etc/prometheus/rules/` 2. Ajouter dans `prometheus.yml`: `rule_files: ["/etc/prometheus/rules/veza-backend-api.yml"]` 3. Redémarrer Prometheus 4. Vérifier: `http://localhost:9090/alerts` --- ## 2. Runbooks ### Fichiers Créés - `docs/runbooks/db_down.md` - Runbook DB down / pool exhausted - `docs/runbooks/circuit_breaker_open.md` - Runbook circuit breaker open - `docs/runbooks/upload_stuck.md` - Runbook upload stuck in "uploading" ### Structure des Runbooks Chaque runbook suit le format: 1. **Signal** - Alertes/symptômes déclencheurs 2. **Hypothèses** - Causes possibles 3. **Vérifications** - Commandes de diagnostic 4. **Actions Correctives** - Solutions par scénario 5. **Post-Mortem Notes** - Template pour documentation post-incident ### Runbook: DB Down **Scénarios couverts**: - DB PostgreSQL down - DB pool saturé (> 20/25 connexions) - Réseau/connectivité - Requêtes bloquantes **Actions clés**: - Redémarrer PostgreSQL - Identifier et tuer requêtes bloquantes - Vérifier espace disque/mémoire - Augmenter pool temporairement (si nécessaire) ### Runbook: Circuit Breaker Open **Scénarios couverts**: - Service externe down (OAuth, Stream) - Service externe lent (timeouts) - Problème réseau - Configuration circuit breaker **Actions clés**: - Identifier circuit breaker affecté - Tester service externe directement - Vérifier métriques (échecs consécutifs, requêtes rejetées) - Forcer réouverture (si service confirmé OK) ### Runbook: Upload Stuck **Scénarios couverts**: - Job worker down - Queue bloquée (RabbitMQ) - Storage problème (fichier manquant, permissions) - Processing échoué silencieusement - Timeout processing **Actions clés**: - Vérifier statut upload en DB - Redémarrer job worker - Vérifier queue RabbitMQ - Forcer re-processing si nécessaire --- ## 3. Contrat Erreurs Unifié ### Fichiers Créés - `internal/handlers/error_contract_test.go` - Test de contrat pour format erreurs ### Test de Contrat Le test `TestErrorContract` vérifie que les endpoints critiques retournent des erreurs au format standardisé: ```json { "success": false, "error": { "code": 2000, "message": "error message", "timestamp": "2025-12-15T10:00:00Z", "request_id": "...", "details": [...] } } ``` ### Endpoints Testés - ✅ BitrateHandler - Validation erreurs - ✅ BitrateHandler - Unauthorized - ✅ PlaybackAnalyticsHandler - Not Found - ✅ Validation errors avec détails ### État Standardisation **Endpoints standardisés** (utilisent `RespondWithAppError`): - ✅ `/api/v1/tracks/:id/bitrate/adapt` - BitrateHandler - ✅ `/api/v1/playback/analytics/*` - PlaybackAnalyticsHandler - ✅ `/health`, `/readyz`, `/live` - HealthHandler **Endpoints partiellement standardisés**: - ⚠️ `/api/v1/auth/*` - Utilise `response.Error()` (format similaire mais non AppError) - **Impact**: Format compatible mais pas de code d'erreur standardisé - **Action**: Documenté comme acceptable pour l'instant (conversion future possible) ### Exécution ```bash go test ./internal/handlers -run TestErrorContract -v ``` **Résultat**: ✅ Tous les tests passent --- ## 4. Micro Load Test ### Fichiers Créés - `scripts/loadtest/k6_load_test.js` - Script k6 pour load testing - `scripts/loadtest/README.md` - Documentation utilisation ### Configuration **Stages** (par défaut): - Ramp-up: 0 → 10 VUs en 30s - Stabilité: 10 VUs pendant 1m - Ramp-down: 10 → 0 VUs en 30s **Endpoints testés**: 1. `GET /health` - Health check 2. `GET /readyz` - Readiness check 3. `POST /api/v1/auth/login` - Auth endpoint (credentials invalides) 4. `GET /api/v1/tracks` - Track list ### Seuils Attendus - **HTTP Request Duration**: P95 < 500ms, P99 < 1s - **Error Rate**: < 5% - **Health Check**: P95 < 100ms - **Readyz Check**: P95 < 200ms ### Utilisation ```bash # Test basique k6 run scripts/loadtest/k6_load_test.js # Avec URL personnalisée BASE_URL=http://staging.example.com:8080 k6 run scripts/loadtest/k6_load_test.js # Avec token auth AUTH_TOKEN=your_token k6 run scripts/loadtest/k6_load_test.js ``` ### Résultats Le script génère: - **stdout**: Résumé textuel - `scripts/loadtest/k6_summary.json`: Résultats détaillés JSON ### Détection Régressions **Signaux d'alerte**: - Latence P95 > 500ms → Performance dégradée - Error rate > 5% → Problèmes stabilité - Health check > 100ms → Problème DB/dépendances **Actions si seuils dépassés**: 1. Vérifier logs application 2. Vérifier métriques Prometheus 3. Vérifier ressources système 4. Consulter runbooks --- ## Utilisation en Production ### Semaine 1 - Checklist Quotidienne #### Matin (9h) - [ ] Vérifier alertes Prometheus: `http://prometheus:9090/alerts` - [ ] Vérifier métriques clés: - `veza_db_pool_open_connections` < 20 - `veza_circuit_breaker_state == 0` (closed) - `rate(veza_gin_http_requests_total{status=~"5.."}[5m]) < 0.05` - [ ] Vérifier logs erreurs: `grep -i error /var/log/veza-backend-api/*.log | tail -20` #### Après-midi (14h) - [ ] Re-vérifier alertes - [ ] Vérifier latence: `histogram_quantile(0.95, veza_gin_http_request_duration_seconds)` - [ ] Run load test (optionnel): `k6 run scripts/loadtest/k6_load_test.js` #### Soir (18h) - [ ] Résumé incidents de la journée - [ ] Documenter dans runbooks si nouveaux patterns ### En Cas d'Incident 1. **Identifier alerte déclenchée** → Consulter runbook correspondant 2. **Suivre runbook** → Signal → Hypothèses → Vérifications → Actions 3. **Documenter** → Post-mortem notes dans runbook 4. **Ajuster** → Alertes/seuils si nécessaire ### Intégration CI/CD **Optionnel**: Ajouter load test dans pipeline ```yaml # .github/workflows/load-test.yml - name: Run load tests run: | k6 run scripts/loadtest/k6_load_test.js env: BASE_URL: http://staging.example.com:8080 ``` --- ## Améliorations Futures (Non-Bloquantes) ### Court Terme (Semaine 2-4) 1. **Convertir `internal/core/auth/handler.go`** vers `RespondWithAppError` - Impact: Standardisation complète - Effort: 2-3h 2. **Ajouter métriques upload processing** - Alerte: Uploads stuck > 10 min - Effort: 1-2h 3. **Dashboard Grafana** - Visualisation métriques clés - Effort: 2-3h ### Moyen Terme (Mois 2-3) 1. **Tests d'intégration end-to-end** - Scénarios utilisateur complets - Effort: 1 semaine 2. **Chaos Engineering** - Tests résilience (DB down, dépendances down) - Effort: 2-3 jours 3. **Performance profiling** - Identifier bottlenecks - Effort: 1 semaine --- ## Fichiers Modifiés/Créés ### Nouveaux Fichiers ``` ops/prometheus/ ├── alerts.yml └── README.md docs/runbooks/ ├── db_down.md ├── circuit_breaker_open.md └── upload_stuck.md scripts/loadtest/ ├── k6_load_test.js └── README.md internal/handlers/ └── error_contract_test.go docs/ └── PROD_WEEK1_HARDENING_REPORT.md (ce fichier) ``` ### Fichiers Modifiés Aucun fichier de code modifié (approche non-invasive). --- ## Validation ### Tests Exécutés ```bash # Test contrat erreurs go test ./internal/handlers -run TestErrorContract -v # ✅ PASS # Load test (exemple) k6 run scripts/loadtest/k6_load_test.js # ✅ Seuils respectés ``` ### Vérifications Manuelles - [x] Alertes Prometheus syntaxiquement correctes - [x] Runbooks complets et actionnables - [x] Load test exécutable et reproductible - [x] Test contrat erreurs passe --- ## Conclusion Le module **veza-backend-api** est maintenant **prêt pour la semaine 1 de production** avec: ✅ **Alerting** - 8 alertes critiques configurées ✅ **Runbooks** - 3 runbooks incident-ready ✅ **Tests** - Contrat erreurs + load tests ✅ **Documentation** - Complète et actionnable **Prochaines étapes**: 1. Activer alertes Prometheus en staging/prod 2. Former équipe sur runbooks 3. Monitorer métriques première semaine 4. Ajuster seuils selon observations réelles **Support**: Consulter runbooks en cas d'incident, ajuster alertes selon besoins. --- **Date de création**: 2025-12-15 **Auteur**: SRE Team **Version**: 1.0