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

420 lines
11 KiB
Markdown

# 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