GlitchTip: Fehlerprotokoll fuer Server, Fehlersignale und Browser
- sentry/sentry-laravel 4.28; config/sentry.php gehaertet (keine PII, keine Request-Bodys, before_send ErrorReportScrubber) - Handler: Integration::captureUnhandledException, CommandNotFoundException nicht melden - ReportErrorSignals (global): toter interner Link (nach Pfad wegen Catch-all-Route), 403/429 fuer Angemeldete, 419; gedrosselt - Browser: selbst gehostetes SDK (esbuild-Bundle 11.5.0), Loader ohne Build-Schritt und ohne Regex-Lookbehind, in 7 Layouts mit area-Tag - phpunit.xml: DSNs und ntfy-URL leer, CACHE_DRIVER=array (Tests schrieben bisher in den lokalen Datei-Cache) - dev/glitch-tip/README.md mit Instanz, Org, Projekt-IDs, API-Auswertung Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
36feed6324
commit
0b02b1b15c
28 changed files with 1453 additions and 61 deletions
90
dev/glitch-tip/README.md
Normal file
90
dev/glitch-tip/README.md
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# 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 `<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]`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue