veza/veza-backend-api/docs/PROD_WEEK1_HARDENING_REPORT.md
2025-12-16 11:23:49 -05:00

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

  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

  1. 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
  2. VezaHigh5xxRate

    • Condition: Taux erreurs 5xx > 5% pendant 5 min
    • Métrique: (sum(rate(5xx)) / sum(rate(all))) > 0.05
    • Action: Investigation, vérifier logs
  3. 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
  4. 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é:

{
  "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

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

# 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

# .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

# 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:

  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