veza/veza-backend-api/PR5_P1_004_005_006_TIMEOUTS_OBSERVABILITY_REPORT.md

211 lines
7.2 KiB
Markdown
Raw Normal View History

2025-12-13 02:34:34 +00:00
# PR5 — Timeouts & Observabilité (handlers + stack traces + readyz)
## Résumé
Cette PR corrige les problèmes **MOD-P1-004**, **MOD-P1-005**, et **MOD-P1-006** :
- **MOD-P1-004**: Timeouts context systématiques dans handlers
- **MOD-P1-005**: Stack traces conditionnels (dev/DEBUG seulement)
- **MOD-P1-006**: /readyz tolérance Redis/RabbitMQ (degraded mode)
## Items Corrigés
### MOD-P1-004: Pas de Timeout Context dans Tous Handlers
**Fichiers**:
- `internal/api/router.go:83` (déjà implémenté)
2025-12-16 16:23:49 +00:00
- `internal/middleware/timeout.go` (déjà implémenté)
2025-12-13 02:34:34 +00:00
**Problème**:
- Handlers peuvent bloquer indéfiniment sans timeout
**Fix**:
-**Déjà implémenté**: Le router utilise `middleware.Timeout(r.config.HandlerTimeout)` globalement
-**Validation**: Tous les handlers passent par le middleware timeout (30s par défaut)
**Validation**:
```bash
# Vérifier que le middleware timeout est appliqué
grep -n "middleware.Timeout" internal/api/router.go
# → ligne 83: router.Use(middleware.Timeout(r.config.HandlerTimeout))
```
### MOD-P1-005: Stack Traces dans Logs Prod
**Fichiers**:
- `internal/api/router.go:62-64` (modifié)
- `internal/middleware/error_handler.go:148-151` (déjà implémenté)
**Problème**:
- Stack traces toujours loggés même en production (peut exposer info sensible)
**Fix**:
1. **Amélioration de la logique**: Modifié `includeStackTrace` pour vérifier `APP_ENV=development` OU `LOG_LEVEL=DEBUG`
- Avant: `includeStackTrace := r.config.Env != config.EnvProduction` (incluait staging)
- Après: `includeStackTrace := r.config.Env == config.EnvDevelopment || r.config.LogLevel == "DEBUG"`
2. **Error Handler**: Déjà implémenté avec condition `if includeStackTrace`
**Validation**:
```bash
# Test existant
go test ./internal/middleware -v -count=1 -run TestErrorHandler_StackTrace
# ✅ PASS (2 tests: avec et sans stack trace)
```
### MOD-P1-006: /readyz Échoue si Redis/RabbitMQ Down
**Fichiers**:
- `internal/handlers/health.go:142-184` (déjà implémenté)
**Problème**:
- `/readyz` peut échouer si Redis/RabbitMQ down (même si DB OK)
**Fix**:
-**Déjà implémenté**: `/readyz` retourne status "degraded" si Redis/RabbitMQ down, mais reste 200 OK
-**DB critique**: Si DB down → 503 "not_ready"
-**Services optionnels**: Si Redis/RabbitMQ down → 200 "degraded"
**Validation**:
```bash
# Tests ajoutés
go test ./internal/handlers -v -count=1 -run TestHealthHandler_Readiness
# ✅ PASS (2 tests: degraded mode et database critical)
```
## Fichiers Modifiés
1. `internal/api/router.go`
- Ligne 62-64: Amélioration de la logique `includeStackTrace` pour MOD-P1-005
- Commentaire MOD-P1-005 ajouté
2. `internal/handlers/health_p1_test.go` (nouveau)
- Test `TestHealthHandler_Readiness_DegradedMode`: Valide que /readyz retourne "degraded" si Redis/RabbitMQ down
- Test `TestHealthHandler_Readiness_DatabaseCritical`: Valide que /readyz retourne "not_ready" si DB down
## Commandes de Validation
### Build
```bash
# Compilation
go build ./internal/api ./internal/middleware ./internal/handlers
# ✅ Succès
# Build complet
go build ./cmd/api/main.go
# ✅ Succès
```
### Tests
```bash
# Tests stack traces (MOD-P1-005)
go test ./internal/middleware -v -count=1 -run TestErrorHandler_StackTrace
# ✅ PASS (2 tests: IncludeStackTrace_True, IncludeStackTrace_False)
# Tests health readiness (MOD-P1-006)
go test ./internal/handlers -v -count=1 -run TestHealthHandler_Readiness
# ✅ PASS (2 tests: DegradedMode, DatabaseCritical)
# Tous les tests
go test ./... -count=1 -short
# ✅ Tests unitaires passent
```
### Validation Manuelle
**MOD-P1-004 (Timeouts)**:
- ✅ Middleware timeout appliqué globalement dans `router.go:83`
- ✅ Timeout par défaut: 30s (configurable via `HANDLER_TIMEOUT`)
- ✅ Tous les handlers passent par le middleware timeout
**MOD-P1-005 (Stack Traces)**:
```bash
# En production (APP_ENV=production, LOG_LEVEL=INFO)
# → Stack traces NE sont PAS loggés ✅
# En development (APP_ENV=development)
# → Stack traces SONT loggés ✅
# En DEBUG (LOG_LEVEL=DEBUG)
# → Stack traces SONT loggés ✅
```
**MOD-P1-006 (Health Readiness)**:
```bash
# DB OK, Redis/RabbitMQ down
curl http://localhost:8080/api/v1/readyz
# → Status: 200 OK, body: {"status": "degraded", ...} ✅
# DB down
# → Status: 503 Service Unavailable, body: {"status": "not_ready", ...} ✅
```
## Détails Techniques
### Corrections Apportées
1. **MOD-P1-004 (Timeouts)**:
-**Déjà implémenté**: Middleware timeout global dans `router.go:83`
-**Timeout par défaut**: 30s (configurable via `HANDLER_TIMEOUT`)
-**Comportement**: Handlers timeout après 30s, retourne 504 Gateway Timeout
2. **MOD-P1-005 (Stack Traces)**:
- **Avant**: `includeStackTrace := r.config.Env != config.EnvProduction` (incluait staging)
- **Après**: `includeStackTrace := r.config.Env == config.EnvDevelopment || r.config.LogLevel == "DEBUG"`
- **Comportement**: Stack traces seulement en development ou si LOG_LEVEL=DEBUG
3. **MOD-P1-006 (Health Readiness)**:
-**Déjà implémenté**: `/readyz` retourne "degraded" si Redis/RabbitMQ down
-**DB critique**: Si DB down → 503 "not_ready"
-**Services optionnels**: Si Redis/RabbitMQ down → 200 "degraded"
### Endpoints Vérifiés
-**Tous les handlers**: Passent par `middleware.Timeout()` global
-`/api/v1/readyz`: Retourne "degraded" si Redis/RabbitMQ down, "not_ready" si DB down
-**Error Handler**: Stack traces conditionnels selon env/LOG_LEVEL
## Risques / Limitations
1. **Timeouts globaux**: Le middleware timeout est appliqué globalement
- **Impact**: Tous les handlers ont le même timeout (30s)
- **Mitigation**: Timeout configurable via `HANDLER_TIMEOUT` env var
2. **Stack traces en staging**: Stack traces ne sont plus loggés en staging (seulement dev/DEBUG)
- **Impact**: Debugging plus difficile en staging
- **Mitigation**: Utiliser Sentry pour les erreurs en staging/prod
3. **Health checks**: Tests utilisent SQLite en mémoire
- **Impact**: Tests ne reflètent pas exactement le comportement avec PostgreSQL
- **Mitigation**: Tests d'intégration avec PostgreSQL pourraient valider le comportement réel
## Tests Ajoutés/Modifiés
-`TestErrorHandler_StackTrace` (existant): Valide stack traces conditionnels
-`TestHealthHandler_Readiness_DegradedMode` (nouveau): Valide degraded mode
-`TestHealthHandler_Readiness_DatabaseCritical` (nouveau): Valide DB critique
## Documentation
**Comportement attendu**:
- **Timeouts**: Tous les handlers timeout après 30s (configurable)
- **Stack traces**: Loggés seulement si `APP_ENV=development` OU `LOG_LEVEL=DEBUG`
- **Health readiness**:
- DB down → 503 "not_ready"
- Redis/RabbitMQ down → 200 "degraded"
- Tout OK → 200 "ready"
**Configuration**:
- `HANDLER_TIMEOUT`: Timeout pour handlers (défaut: 30s)
- `APP_ENV`: Environnement (development, staging, production)
- `LOG_LEVEL`: Niveau de log (DEBUG, INFO, WARN, ERROR)
## Prochaines Étapes
- ✅ PR5 complétée
- ⏭️ PR6: Quick wins (MOD-P2-004, MOD-P2-010, MOD-P3-001, MOD-P3-002)
---
**Statut**: ✅ **READY FOR REVIEW**
**Effort**: ~6h (comme estimé dans audit: 4h + 1h + 1h)
**Breaking Changes**: Aucun