4.5 KiB
GlitchTip — Fehlerprotokoll mivita.care
Stand: 08.10.2026 · Hintergrund und Regeln: dev/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 inconfig('monitoring.browser.sdk_version')
Neu bauen (z. B. Update auf eine neue SDK-Version), außerhalb des Projekts:
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.
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
# 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):
setTimeout(() => { throw new Error('Browser-Test test@example.com') });
→ erscheint im Projekt browser-mivitacare, E-Mail als [email].