Implémentation complète de la stack d'observabilité pour le monitoring de la plateforme multi-tenant Classeo. ## Error Tracking (GlitchTip) - Intégration Sentry SDK avec GlitchTip auto-hébergé - Scrubber PII avant envoi (RGPD: emails, tokens JWT, NIR français) - Contexte enrichi: tenant_id, user_id, correlation_id - Configuration backend (sentry.yaml) et frontend (sentry.ts) ## Metrics (Prometheus) - Endpoint /metrics avec restriction IP en production - Métriques HTTP: requests_total, request_duration_seconds (histogramme) - Métriques sécurité: login_failures_total par tenant - Métriques santé: health_check_status (postgres, redis, rabbitmq) - Storage Redis pour persistance entre requêtes ## Logs (Loki) - Processors Monolog: CorrelationIdLogProcessor, PiiScrubberLogProcessor - Détection PII: emails, téléphones FR, tokens JWT, NIR français - Labels structurés: tenant_id, correlation_id, level ## Dashboards (Grafana) - Dashboard principal: latence P50/P95/P99, error rate, RPS - Dashboard par tenant: métriques isolées par sous-domaine - Dashboard infrastructure: santé postgres/redis/rabbitmq - Datasources avec UIDs fixes pour portabilité ## Alertes (Alertmanager) - HighApiLatencyP95/P99: SLA monitoring (200ms/500ms) - HighErrorRate: error rate > 1% pendant 2 min - ExcessiveLoginFailures: détection brute force - ApplicationUnhealthy: health check failures ## Infrastructure - InfrastructureHealthChecker: service partagé (DRY) - HealthCheckController: endpoint /health pour load balancers - Pre-push hook: make ci && make e2e avant push
345 lines
9.7 KiB
Plaintext
345 lines
9.7 KiB
Plaintext
{
|
|
"api-platform/core": {
|
|
"version": "4.2",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "4.0",
|
|
"ref": "cb9e6b8ceb9b62f32d41fc8ad72a25d5bd674c6d"
|
|
},
|
|
"files": [
|
|
"config/packages/api_platform.yaml",
|
|
"config/routes/api_platform.yaml",
|
|
"src/ApiResource/.gitignore"
|
|
]
|
|
},
|
|
"doctrine/deprecations": {
|
|
"version": "1.1",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "1.0",
|
|
"ref": "87424683adc81d7dc305eefec1fced883084aab9"
|
|
}
|
|
},
|
|
"doctrine/doctrine-bundle": {
|
|
"version": "3.2",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "3.0",
|
|
"ref": "18ee08e513ba0303fd09a01fc1c934870af06ffa"
|
|
},
|
|
"files": [
|
|
"config/packages/doctrine.yaml",
|
|
"src/Entity/.gitignore",
|
|
"src/Repository/.gitignore"
|
|
]
|
|
},
|
|
"doctrine/doctrine-fixtures-bundle": {
|
|
"version": "4.3",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "3.0",
|
|
"ref": "1f5514cfa15b947298df4d771e694e578d4c204d"
|
|
},
|
|
"files": [
|
|
"src/DataFixtures/AppFixtures.php"
|
|
]
|
|
},
|
|
"doctrine/doctrine-migrations-bundle": {
|
|
"version": "3.7",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "3.1",
|
|
"ref": "1d01ec03c6ecbd67c3375c5478c9a423ae5d6a33"
|
|
},
|
|
"files": [
|
|
"config/packages/doctrine_migrations.yaml",
|
|
"migrations/.gitignore"
|
|
]
|
|
},
|
|
"friendsofphp/php-cs-fixer": {
|
|
"version": "3.93",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "3.0",
|
|
"ref": "be2103eb4a20942e28a6dd87736669b757132435"
|
|
},
|
|
"files": [
|
|
".php-cs-fixer.dist.php"
|
|
]
|
|
},
|
|
"lexik/jwt-authentication-bundle": {
|
|
"version": "3.2",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "2.5",
|
|
"ref": "e9481b233a11ef7e15fe055a2b21fd3ac1aa2bb7"
|
|
},
|
|
"files": [
|
|
"config/packages/lexik_jwt_authentication.yaml"
|
|
]
|
|
},
|
|
"nelmio/cors-bundle": {
|
|
"version": "2.6",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "1.5",
|
|
"ref": "6bea22e6c564fba3a1391615cada1437d0bde39c"
|
|
},
|
|
"files": [
|
|
"config/packages/nelmio_cors.yaml"
|
|
]
|
|
},
|
|
"phpstan/phpstan": {
|
|
"version": "2.1",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes-contrib",
|
|
"branch": "main",
|
|
"version": "1.0",
|
|
"ref": "5e490cc197fb6bb1ae22e5abbc531ddc633b6767"
|
|
}
|
|
},
|
|
"phpunit/phpunit": {
|
|
"version": "11.5",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "11.1",
|
|
"ref": "1117deb12541f35793eec9fff7494d7aa12283fc"
|
|
},
|
|
"files": [
|
|
".env.test",
|
|
"phpunit.dist.xml",
|
|
"tests/bootstrap.php",
|
|
"bin/phpunit"
|
|
]
|
|
},
|
|
"sentry/sentry-symfony": {
|
|
"version": "5.8",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes-contrib",
|
|
"branch": "main",
|
|
"version": "5.0",
|
|
"ref": "12f504985eb24e3b20a9e41e0ec7e398798d18f0"
|
|
},
|
|
"files": [
|
|
"config/packages/sentry.yaml"
|
|
]
|
|
},
|
|
"symfony/console": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "5.3",
|
|
"ref": "1781ff40d8a17d87cf53f8d4cf0c8346ed2bb461"
|
|
},
|
|
"files": [
|
|
"bin/console"
|
|
]
|
|
},
|
|
"symfony/debug-bundle": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "5.3",
|
|
"ref": "5aa8aa48234c8eb6dbdd7b3cd5d791485d2cec4b"
|
|
},
|
|
"files": [
|
|
"config/packages/debug.yaml"
|
|
]
|
|
},
|
|
"symfony/flex": {
|
|
"version": "2.10",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "2.4",
|
|
"ref": "52e9754527a15e2b79d9a610f98185a1fe46622a"
|
|
},
|
|
"files": [
|
|
".env",
|
|
".env.dev"
|
|
]
|
|
},
|
|
"symfony/framework-bundle": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "7.4",
|
|
"ref": "09f6e081c763a206802674ce0cb34a022f0ffc6d"
|
|
},
|
|
"files": [
|
|
"config/packages/cache.yaml",
|
|
"config/packages/framework.yaml",
|
|
"config/preload.php",
|
|
"config/routes/framework.yaml",
|
|
"config/services.yaml",
|
|
"public/index.php",
|
|
"src/Controller/.gitignore",
|
|
"src/Kernel.php",
|
|
".editorconfig"
|
|
]
|
|
},
|
|
"symfony/lock": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "5.2",
|
|
"ref": "8e937ff2b4735d110af1770f242c1107fdab4c8e"
|
|
},
|
|
"files": [
|
|
"config/packages/lock.yaml"
|
|
]
|
|
},
|
|
"symfony/mailer": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "4.3",
|
|
"ref": "09051cfde49476e3c12cd3a0e44289ace1c75a4f"
|
|
},
|
|
"files": [
|
|
"config/packages/mailer.yaml"
|
|
]
|
|
},
|
|
"symfony/maker-bundle": {
|
|
"version": "1.65",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "1.0",
|
|
"ref": "fadbfe33303a76e25cb63401050439aa9b1a9c7f"
|
|
}
|
|
},
|
|
"symfony/messenger": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "6.0",
|
|
"ref": "d8936e2e2230637ef97e5eecc0eea074eecae58b"
|
|
},
|
|
"files": [
|
|
"config/packages/messenger.yaml"
|
|
]
|
|
},
|
|
"symfony/monolog-bundle": {
|
|
"version": "4.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "3.7",
|
|
"ref": "1b9efb10c54cb51c713a9391c9300ff8bceda459"
|
|
},
|
|
"files": [
|
|
"config/packages/monolog.yaml"
|
|
]
|
|
},
|
|
"symfony/phpunit-bridge": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "7.3",
|
|
"ref": "dc13fec96bd527bd399c3c01f0aab915c67fd544"
|
|
}
|
|
},
|
|
"symfony/property-info": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "7.3",
|
|
"ref": "dae70df71978ae9226ae915ffd5fad817f5ca1f7"
|
|
},
|
|
"files": [
|
|
"config/packages/property_info.yaml"
|
|
]
|
|
},
|
|
"symfony/routing": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "7.4",
|
|
"ref": "bc94c4fd86f393f3ab3947c18b830ea343e51ded"
|
|
},
|
|
"files": [
|
|
"config/packages/routing.yaml",
|
|
"config/routes.yaml"
|
|
]
|
|
},
|
|
"symfony/security-bundle": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "7.4",
|
|
"ref": "c42fee7802181cdd50f61b8622715829f5d2335c"
|
|
},
|
|
"files": [
|
|
"config/packages/security.yaml",
|
|
"config/routes/security.yaml"
|
|
]
|
|
},
|
|
"symfony/twig-bundle": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "6.4",
|
|
"ref": "cab5fd2a13a45c266d45a7d9337e28dee6272877"
|
|
},
|
|
"files": [
|
|
"config/packages/twig.yaml",
|
|
"templates/base.html.twig"
|
|
]
|
|
},
|
|
"symfony/uid": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "7.0",
|
|
"ref": "0df5844274d871b37fc3816c57a768ffc60a43a5"
|
|
}
|
|
},
|
|
"symfony/validator": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "7.0",
|
|
"ref": "8c1c4e28d26a124b0bb273f537ca8ce443472bfd"
|
|
},
|
|
"files": [
|
|
"config/packages/validator.yaml"
|
|
]
|
|
},
|
|
"symfony/web-profiler-bundle": {
|
|
"version": "8.0",
|
|
"recipe": {
|
|
"repo": "github.com/symfony/recipes",
|
|
"branch": "main",
|
|
"version": "7.3",
|
|
"ref": "a363460c1b0b4a4d0242f2ce1a843ca0f6ac9026"
|
|
},
|
|
"files": [
|
|
"config/packages/web_profiler.yaml",
|
|
"config/routes/web_profiler.yaml"
|
|
]
|
|
}
|
|
}
|