# Error tracking (GlitchTip) Les erreurs **backend** (Symfony) sont remontées vers **GlitchTip** (instance interne MALIO, compatible SDK Sentry), org `malio`, projet `sirh-api`. **Prod uniquement**, **inerte sans DSN**. > Frontend hors périmètre (les erreurs front partent du navigateur RH ; ajout futur possible via > un proxy nginx `/ingest`). ## Contrainte réseau & transport GlitchTip est sur le réseau interne (bloqué par Sophos), servi en **HTTPS sur `logs.malio-dev.fr`** (cert auto-signé par la CA interne « MALIO-DEV Local Root CA »). SIRH tourne sur un **VPS OVH** public. Le lien passe par un **tunnel Tailscale** entre les deux hôtes. **Topologie retenue (Option A — HTTPS + hostname mappé sur le tailnet) :** - Tailscale est installé **sur l'hôte GlitchTip** (IP tailnet `100.111.223.34`) **et sur le VPS OVH** (IP tailnet `100.93.52.45`). - Le **DSN reste inchangé** : `https://@logs.malio-dev.fr/` (même endpoint que le navigateur → pas de souci `ALLOWED_HOSTS`, Host header et cert cohérents). - Côté SIRH, le nom `logs.malio-dev.fr` est résolu vers l'**IP tailnet de GlitchTip** via `extra_hosts` dans le `docker-compose` du serveur. - La **CA racine MALIO** est bakée dans l'image SIRH (`deploy/docker/Dockerfile.prod`) pour que le SDK accepte le TLS auto-signé. > Pré-requis : le nginx qui sert `logs.malio-dev.fr` en 443 doit écouter sur une interface > joignable via le tailnet (typiquement `0.0.0.0:443` → joignable sur `100.111.223.34:443`). ## Fichiers concernés | Fichier | Rôle | |---|---| | `config/packages/sentry.yaml` | conf backend (prod-only, DSN runtime, 4xx ignorés, release = `app.version`, handler Monolog ERROR+) | | `config/bundles.php` | `SentryBundle` enregistré `['prod' => true]` | | `config/packages/monolog.yaml` | handler `sentry` (service) en `when@prod` | | `.env` | bloc documenté `SENTRY_DSN` (vide → inerte) | | `deploy/docker/Dockerfile.prod` | bake la CA racine MALIO (`update-ca-certificates`) pour le TLS interne | | `deploy/docker/malio-dev-root-ca.crt` | certificat **public** de la CA interne (aucune clé privée) | ## Activation (runbook) 1. **Tailscale sur les deux hôtes** (GlitchTip **et** VPS OVH) : ```bash curl -fsSL https://tailscale.com/install.sh | sh sudo tailscale up # ou --authkey tskey-auth-XXXX (headless) tailscale ip -4 # GlitchTip → 100.111.223.34 ; OVH → 100.93.52.45 ``` 2. **Vérifier l'accès** depuis le VPS OVH (tunnel + nginx 443 de GlitchTip) : ```bash tailscale ping 100.111.223.34 curl -sSk -o /dev/null -w "%{http_code}\n" https://100.111.223.34/ # réponse HTTP = tunnel OK ``` 3. **Mapper le hostname vers l'IP tailnet** dans le `docker-compose` du serveur OVH (service `php`), pour que le container résolve `logs.malio-dev.fr` : ```yaml extra_hosts: - "logs.malio-dev.fr:100.111.223.34" ``` 4. **Projet GlitchTip** : déjà créé (org `malio`, projet `sirh-api`, id `3`). DSN de base affiché dans *Settings → Client Keys* : `https://@logs.malio-dev.fr/3`. 5. **Injecter le DSN tel quel** (hostname conservé) dans l'env_file serveur (pas dans l'image), puis rebuild/redéployer l'image (la CA est bakée au build) : ```env SENTRY_DSN=https://@logs.malio-dev.fr/3 ``` ```bash docker compose up -d docker compose exec php php bin/console cache:clear --env=prod ``` ## Tester l'envoi Le bundle `sentry/sentry-symfony` fournit une commande qui envoie un événement de test et confirme s'il est bien parti vers GlitchTip. Elle n'existe qu'en **prod** (bundle prod-only) et nécessite `SENTRY_DSN` défini. ```bash # Sur le serveur, dans le container PHP (SENTRY_DSN doit être dans l'env) : docker compose exec php sh -lc "APP_ENV=prod php bin/console sentry:test" ``` Sortie attendue : `Sending test message... done.` → une **Issue de test** apparaît dans le projet `sirh-api` côté GlitchTip. Si l'envoi échoue (`Message not sent`), le problème est réseau (Tailscale/route/port) ou DSN, pas applicatif. Pré-check connectivité depuis le VPS OVH (`-k` ignore le cert juste pour ce test) : ```bash tailscale ping 100.111.223.34 curl -sSk -o /dev/null -w "%{http_code}\n" https://100.111.223.34/ # réponse HTTP = tunnel OK # Avec résolution du hostname (comme le container) + validation par la CA : curl --resolve logs.malio-dev.fr:443:100.111.223.34 \ --cacert deploy/docker/malio-dev-root-ca.crt \ -sS -o /dev/null -w "%{http_code}\n" https://logs.malio-dev.fr/ ``` Alternative sans commande dédiée : déclencher un `throw new \RuntimeException('glitchtip test')` temporaire dans un endpoint, ou un `$logger->error('glitchtip test')` (niveau ERROR+ → Issue). ## CA HTTPS interne (bakée dans l'image) GlitchTip est en HTTPS avec un cert auto-signé par la **CA interne MALIO**. Le SDK refuse un TLS non approuvé (« Message not sent »). La CA publique (`deploy/docker/malio-dev-root-ca.crt`, aucune clé privée) est donc installée dans le trust store de l'image au build (`deploy/docker/Dockerfile.prod`, stage production) : ```dockerfile COPY deploy/docker/malio-dev-root-ca.crt /usr/local/share/ca-certificates/malio-dev-root-ca.crt RUN update-ca-certificates ``` Combinée à l'`extra_hosts` (hostname → IP tailnet), le container fait confiance à `logs.malio-dev.fr` et l'atteint via le tunnel. Design détaillé : `docs/superpowers/specs/2026-06-28-glitchtip-backend-error-tracking-design.md`.