mivita/dev/glitch-tip/README.md
2026-10-08 12:35:04 +00:00

92 lines
4.5 KiB
Markdown

# 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` |
| Alert-Regeln | beide Projekte: Mail bei neuem Fehlertyp, nur `production` |
| Live seit | `v1.3.0` (08.10.2026) |
## 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 `<x-monitoring.browser-errors area="…" />` 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-<version>.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@<version> 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-<version>.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/<ID>/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]`.