feat(observability) : error tracking GlitchTip back + front (INFRA #146)
Backend : sentry/sentry-symfony branché en prod uniquement (bundle prod-only, exceptions seules, 4xx ignorés, release = app.version), DSN via SENTRY_DSN (runtime, infra/prod/.env). Frontend : @sentry/nuxt chargé seulement si NUXT_PUBLIC_SENTRY_DSN présent (donc au build prod), upload des source maps gated sur les secrets. DSN front et secrets passés en build-args (Dockerfile) depuis les secrets Gitea (CI). Doc README (section Error tracking) + .env.example. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@ Application de gestion de projet avec suivi du temps et portail client.
|
||||
- Intégration Gitea (issues, repos)
|
||||
- Intégration Mail IMAP (boîte partagée OVH, voir `docs/mail-integration.md`)
|
||||
- Serveur MCP pour assistants IA
|
||||
- Error tracking centralisé back + front (GlitchTip / SDK Sentry, prod uniquement — voir « Error tracking »)
|
||||
- Multi-langue (i18n)
|
||||
|
||||
## Prérequis
|
||||
@@ -74,6 +75,7 @@ peuvent être surchargées dans `.env.local` (jamais committé). En prod, elles
|
||||
| `CORS_ALLOW_ORIGIN` | Origines CORS autorisées | localhost | ✅ (domaine prod) |
|
||||
| **`ENCRYPTION_KEY`** | **Clé hex 32 bytes chiffrant les credentials IMAP/SMTP (feature mail)** | placeholder | ✅ — doit rester **stable**, sinon les credentials mail stockés deviennent illisibles |
|
||||
| **`LOCK_DSN`** | **Store de verrous Symfony pour la sync mail (anti-chevauchement)** | `flock` | `flock` suffit |
|
||||
| `SENTRY_DSN` | Error tracking **backend** → GlitchTip (projet `lesstime-api`) | _(vide)_ | ⚪ optionnel — active le tracking (voir « Error tracking ») |
|
||||
|
||||
> **Messagerie** : `ENCRYPTION_KEY` et `LOCK_DSN` sont introduites par l'intégration mail.
|
||||
> Détails de config et cron de synchronisation : `docs/mail-integration.md` et `docs/mail-cron-setup.md`.
|
||||
@@ -255,6 +257,65 @@ Le script active la maintenance, pull l'image, redémarre le container, lance le
|
||||
et vide le cache. Guide complet (première installation, BDD, Nginx, JWT, rollback) :
|
||||
**`doc/deployment-docker.md`**.
|
||||
|
||||
## Error tracking (GlitchTip)
|
||||
|
||||
Les erreurs **backend** et **frontend** sont remontées vers **GlitchTip** (instance auto-hébergée
|
||||
interne, compatible SDK Sentry) qui les **groupe par projet** et compte les occurrences. Activé
|
||||
**uniquement en prod** : en dev, sans DSN, le SDK est inerte (zéro impact). Ticket de référence :
|
||||
INFRA #146.
|
||||
|
||||
### Pourquoi back et front se configurent différemment
|
||||
|
||||
| | Backend (Symfony) | Frontend (Nuxt SPA) |
|
||||
|---|---|---|
|
||||
| Nature | process PHP qui tourne en continu | fichiers JS/HTML **statiques** (`nuxt generate`) |
|
||||
| Quand le DSN est lu | au **runtime** | **figé au build** (baké dans le JS) |
|
||||
| Où mettre le DSN | `infra/prod/.env` (runtime) | **secrets Gitea** → build-args de la CI |
|
||||
|
||||
> Les erreurs partent **toujours vers GlitchTip**, jamais vers la CI. La CI ne sert qu'à *écrire*
|
||||
> le DSN front dans le bundle au moment du build (il n'y a aucun process front en prod qui
|
||||
> pourrait lire une variable d'environnement).
|
||||
|
||||
### Variables
|
||||
|
||||
**Backend — fichier `infra/prod/.env` du serveur** (chargé via `env_file`) :
|
||||
```env
|
||||
SENTRY_DSN=http://<clé>@glitchtip.interne:<port>/<id-projet-api>
|
||||
```
|
||||
|
||||
**Frontend — secrets Gitea** (repo → Settings → Actions → Secrets), consommés par
|
||||
`.gitea/workflows/build-docker.yml` :
|
||||
|
||||
| Secret Gitea | Rôle |
|
||||
|---|---|
|
||||
| `SENTRY_FRONT_DSN` | DSN du projet `lesstime-front` (public, baké dans le JS) |
|
||||
| `SENTRY_URL` | URL de l'instance GlitchTip |
|
||||
| `SENTRY_ORG` | slug de l'organisation GlitchTip |
|
||||
| `SENTRY_FRONT_PROJECT` | slug du projet front |
|
||||
| `SENTRY_AUTH_TOKEN` | token d'upload des **source maps** (vrai secret) |
|
||||
|
||||
> Sans source maps, seul `SENTRY_FRONT_DSN` est requis (les stacktraces front seront sur du JS
|
||||
> minifié). Le build n'échoue pas si les autres secrets sont absents.
|
||||
|
||||
### Fichiers concernés
|
||||
|
||||
| Fichier | Rôle |
|
||||
|---|---|
|
||||
| `config/packages/sentry.yaml` | conf backend (prod-only, exceptions, 4xx ignorés, release = `app.version`) |
|
||||
| `config/bundles.php` | `SentryBundle` enregistré `['prod' => true]` |
|
||||
| `frontend/nuxt.config.ts` | module Sentry chargé **uniquement si DSN présent** + upload source maps |
|
||||
| `frontend/sentry.client.config.ts` | init du SDK client (no-op si DSN vide) |
|
||||
| `infra/prod/Dockerfile` | build-args front (`NUXT_PUBLIC_SENTRY_DSN`, `SENTRY_*`) |
|
||||
| `.gitea/workflows/build-docker.yml` | injection des secrets Gitea en build-args |
|
||||
|
||||
### Activation (résumé)
|
||||
|
||||
1. Dans GlitchTip : créer les projets `lesstime-api` et `lesstime-front`, récupérer les 2 DSN
|
||||
(+ un auth token pour les source maps).
|
||||
2. Backend : ajouter `SENTRY_DSN` dans `infra/prod/.env` du serveur.
|
||||
3. Frontend : ajouter les secrets Gitea ci-dessus.
|
||||
4. Tagger une version (`v*`) → la CI build l'image avec le DSN front baké → `deploy.sh`.
|
||||
|
||||
## Licence
|
||||
|
||||
Propriétaire — Tous droits réservés.
|
||||
|
||||
Reference in New Issue
Block a user