# GlitchTip — Fehlerprotokoll mivita.care **Stand:** 08.10.2026 · Hintergrund und Regeln: [`dev/git-deploy-monitoring/02-fehlerprotokoll-glitchtip.md`](../git-deploy-monitoring/02-fehlerprotokoll-glitchtip.md) | | Wert | |---|---| | Instanz | `https://errors.adametz.media` (selbst gehostet, gemeinsam mit anderen Projekten) | | Organisation | `adametz-media` | | Projekt Server (PHP/Laravel) | `server-mivitacare`, ID **4** → `SENTRY_LARAVEL_DSN` | | Projekt Browser (JavaScript) | `browser-mivitacare`, ID **3** → `SENTRY_BROWSER_DSN` | | Umgebungen | `production` (Live), `local` (Entwicklung, nur zum Testen) | | Push (ntfy) | `https://push.adametz.media`, Topic in `MONITORING_NTFY_TOPIC` | ## Was gemeldet wird | Quelle | Wie | |---|---| | Exceptions (Request, Job, Command) | `App\Exceptions\Handler::report()` → `Integration::captureUnhandledException()`; Laravels `dontReport` gilt (404, Validierung, Auth), zusätzlich `PayoneTransportException`, `CommandNotFoundException` | | Fehler ohne Exception | `App\Http\Middleware\ReportErrorSignals` (global): 404 mit eigenem Referrer (nach **Pfad**, nicht Route — wegen der Catch-all-Route), 403/429 für Angemeldete, 419; höchstens 5 je 10 Min. und Ort | | Browserfehler | `public/js/error-reporting/error-reporting.js` über `` in 7 Layouts (`crm`, `crm-auth`, `portal`, `portal-auth`, `portal-public`, `web`, `shop`) | | Betriebs-Alarme | `App\Support\OperationalAlert` → Log, Mail, ntfy (siehe `dev/betrieb/README.md`, Abschnitt G) | Datenschutz: `App\Support\Monitoring\ErrorReportScrubber` (Server) und dieselben Regeln in `error-reporting.js` (Browser): nur User-ID, keine Request-Bodys/Cookies, Tokens und nicht erlaubte Query-Parameter als `[Filtered]`, E-Mail-Adressen als `[email]`. Erlaubte Query-Parameter: `page, q, tab, sort, lang, month, year` (+ `utm_*`) — Liste an beiden Stellen gleich halten. Tests melden nie an das echte GlitchTip/ntfy (`phpunit.xml`, Wächtertest in `ErrorReportingTest`). ## Browser-SDK (selbst gehostet) Kein Drittanbieter-CDN (sonst ginge die IP jedes Besuchers an Sentry). `public/js/error-reporting/`: - `error-reporting.js` — Listener, lädt das SDK erst beim ersten Fehler; ES2018, **ohne Regex-Lookbehind** (ältere Safari-Versionen brechen sonst beim Parsen ab — Test prüft das) - `sentry-browser-.min.js` — Version in `config('monitoring.browser.sdk_version')` Neu bauen (z. B. Update auf eine neue SDK-Version), außerhalb des Projekts: ```bash mkdir /tmp/sentry-build && cd /tmp/sentry-build && npm init -y >/dev/null npm install --ignore-scripts --save-exact @sentry/browser@ esbuild echo "export { captureException, init, setTag, setUser } from '@sentry/browser';" > entry.js npx esbuild entry.js --bundle --minify --format=iife --global-name=MivitaSentry --target=es2018 \ --legal-comments=none --outfile=sentry-browser-.min.js ``` Datei nach `public/js/error-reporting/` kopieren, `sdk_version` in `config/monitoring.php` anpassen, alte Datei löschen. ## Auswerten per API Lese-Token (`project:read`, `event:read`) liegt lokal als `GLITCHTIP_API_TOKEN` in der `.env` — nie ausgeben, nie committen. ```bash T=$(grep -E "^GLITCHTIP_API_TOKEN=" .env | cut -d= -f2- | tr -d "'\"") B=https://errors.adametz.media/api/0 # Offene Einträge, nur Live (project=4 Server, project=3 Browser) curl -s -H "Authorization: Bearer $T" \ "$B/organizations/adametz-media/issues/?project=4&query=is:unresolved&environment=production&limit=100" \ | python3 -c " import json,sys for i in json.load(sys.stdin): print(i['id'], i['count'], i['firstSeen'][:16], i['lastSeen'][:16], '|', (i['title'] or '')[:100])" # Letztes Ereignis eines Eintrags (Umgebung, Release, Bereich, Stacktrace) curl -s -H "Authorization: Bearer $T" "$B/issues//events/latest/" ``` Einordnen und Vorgehen: Abschnitt 7 in `02-fehlerprotokoll-glitchtip.md`. Auflösen in GlitchTip von Hand (Token ist nur lesend). ## Testen ```bash # Server (Umgebung laut SENTRY_ENVIRONMENT) php artisan tinker --execute 'report(new RuntimeException("GlitchTip-Test"));' # Alarm (Mail + ntfy) php artisan tinker --execute 'App\Support\OperationalAlert::send("Test-Alarm");' ``` Browser (Konsole auf einer Seite der App, z. B. CRM): ```js setTimeout(() => { throw new Error('Browser-Test test@example.com') }); ``` → erscheint im Projekt `browser-mivitacare`, E-Mail als `[email]`.