11 KiB
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
- Alerting Prometheus - 8 alertes critiques configurées
- Runbooks - 3 runbooks incident-ready (DB down, circuit breaker, upload stuck)
- Contrat Erreurs - Test de contrat ajouté, endpoints critiques standardisés
- 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 Prometheusops/prometheus/README.md- Documentation activation et configuration
Alertes Configurées
Critiques (Critical)
-
VezaCircuitBreakerOpen
- Condition: Circuit breaker OPEN > 5 minutes
- Métrique:
veza_circuit_breaker_state == 2 - Action: Vérifier service externe (OAuth/Stream), consulter runbook
-
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
-
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
-
VezaReadinessFailed
- Condition: Service down (up == 0) > 1 min
- Métrique:
up{job="veza-backend-api"} == 0 - Action: Redémarrer service, vérifier health
Warnings
-
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
-
VezaHigh5xxRate
- Condition: Taux erreurs 5xx > 5% pendant 5 min
- Métrique:
(sum(rate(5xx)) / sum(rate(all))) > 0.05 - Action: Investigation, vérifier logs
-
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
-
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é:
- Copier
alerts.ymldans/etc/prometheus/rules/ - Ajouter dans
prometheus.yml:rule_files: ["/etc/prometheus/rules/veza-backend-api.yml"] - Redémarrer Prometheus
- Vérifier:
http://localhost:9090/alerts
2. Runbooks
Fichiers Créés
docs/runbooks/db_down.md- Runbook DB down / pool exhausteddocs/runbooks/circuit_breaker_open.md- Runbook circuit breaker opendocs/runbooks/upload_stuck.md- Runbook upload stuck in "uploading"
Structure des Runbooks
Chaque runbook suit le format:
- Signal - Alertes/symptômes déclencheurs
- Hypothèses - Causes possibles
- Vérifications - Commandes de diagnostic
- Actions Correctives - Solutions par scénario
- 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é:
{
"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/*- Utiliseresponse.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
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 testingscripts/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:
GET /health- Health checkGET /readyz- Readiness checkPOST /api/v1/auth/login- Auth endpoint (credentials invalides)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
# 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:
- Vérifier logs application
- Vérifier métriques Prometheus
- Vérifier ressources système
- 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< 20veza_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
- Identifier alerte déclenchée → Consulter runbook correspondant
- Suivre runbook → Signal → Hypothèses → Vérifications → Actions
- Documenter → Post-mortem notes dans runbook
- Ajuster → Alertes/seuils si nécessaire
Intégration CI/CD
Optionnel: Ajouter load test dans pipeline
# .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)
-
Convertir
internal/core/auth/handler.goversRespondWithAppError- Impact: Standardisation complète
- Effort: 2-3h
-
Ajouter métriques upload processing
- Alerte: Uploads stuck > 10 min
- Effort: 1-2h
-
Dashboard Grafana
- Visualisation métriques clés
- Effort: 2-3h
Moyen Terme (Mois 2-3)
-
Tests d'intégration end-to-end
- Scénarios utilisateur complets
- Effort: 1 semaine
-
Chaos Engineering
- Tests résilience (DB down, dépendances down)
- Effort: 2-3 jours
-
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
# 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
- Alertes Prometheus syntaxiquement correctes
- Runbooks complets et actionnables
- Load test exécutable et reproductible
- 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:
- Activer alertes Prometheus en staging/prod
- Former équipe sur runbooks
- Monitorer métriques première semaine
- 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