presseportale/dev/glitch-tip
2026-10-06 13:12:41 +00:00
..
README.md dev: GlitchTip-Dokumentation (dev/glitch-tip) — Überblick, Meldewege, API-Abruf, Ablauf zur Fehlerbehebung, Regeln, Protokoll der Einträge; Verweis in CLAUDE.md 2026-10-06 13:12:41 +00:00

GlitchTip — Fehlerprotokoll von Pressekonto

Stand: 06.10.2026 · Gilt ab: v1.1.0 (live seit 05.10.2026) Für: KI-Chats und Entwickler, die Fehler aus GlitchTip auswerten und beheben.

Dieses Dokument beschreibt, was GlitchTip hier ist, wie Fehler dorthin gelangen, was zu tun ist, wenn jemand sagt „schau mal in GlitchTip“, und welche Regeln dabei nicht verletzt werden dürfen. Hintergrund und Entscheidungen: ../betrieb/monitoring-plan.md (Phase 1, Entscheidungen M1–M9).


1. Überblick

Was Wert
Instanz https://errors.adametz.media (selbst gehostet, Sentry-kompatibel)
Organisation (Slug) adametz-media
Projekt 1 server-pressekonto — PHP/Laravel: Exceptions und Fehlersignale
Projekt 2 browser-pressekonto — JavaScript-Fehler aus dem Browser
Umgebungen production (Live), local (Entwicklung). Nur production ist Betrieb
Release Git-Tag aus der Datei RELEASE (z. B. v1.1.0), siehe Abschnitt 6
Aufbewahrung 90 Tage (GLITCHTIP_MAX_EVENT_LIFE_DAYS auf dem GlitchTip-Server)
Alarmierung GlitchTip-Alert-Regel: Mail bei neuem Fehlertyp. Betriebs-Alerts der App (fehlgeschlagene Jobs/Tasks) laufen getrennt über Mail + ntfy (push.adametz.media, Topic pressekonto-ops)

GlitchTip ist nicht das einzige Signal. Daneben: /health (externer Monitor), Admin ▸ Reports ▸ Betriebsüberwachung, storage/logs/*.log.


2. Wie Fehler nach GlitchTip gelangen

Server (Projekt 1)

Weg Datei Was
Gemeldete Exceptions bootstrap/app.php → Integration::handles($exceptions) Alles, was Laravel über report() meldet — unbehandelte Exceptions in Requests, Jobs, Commands
Fehlersignale ohne Exception app/Http/Middleware/ReportErrorSignals.php, app/Support/Monitoring/ErrorSignal.php Warnungen: 404 mit eigenem Referrer („Toter interner Link“), 403/429 für Angemeldete, 419 („Seite abgelaufen“). Je Signal und Ort höchstens 5 Meldungen in 10 Minuten
Konfiguration config/sentry.php DSN, Release, Datenschutz-Optionen
Datenschutzfilter app/Support/Monitoring/ErrorReportScrubber.php (before_send) Nur User-ID, Tokens/Signaturen aus URL/Query/Referer, E-Mails aus Meldungen

Bewusst nicht gemeldet:

  • Laravels Standard-dontReport: 404, Validierung, Authentifizierung, 419 als Exception (419 kommt als Fehlersignal).
  • CommandNotFoundException — vertippte artisan-Befehle (bootstrap/app.php).
  • App\Services\SearchConsole\SearchConsoleUnavailable — Google hängt vorübergehend; nur Log::warning, der Lauf alarmiert erst bei Abbruch oder ≥ 50 % Fehlern.

Browser (Projekt 2)

Datei Was
resources/js/error-reporting.js Hört auf error und unhandledrejection; lädt das SDK erst beim ersten Fehler; filtert URLs/E-Mails; Ablehnungen ohne Error werden mit Typ und Inhalt beschrieben
resources/js/error-reporting-sdk.js Re-Export der benötigten SDK-Funktionen (Tree-Shaking)
resources/views/components/monitoring/browser-errors.blade.php <meta name="pk-error-reporting"> mit DSN, Release, User-ID, Bereich; nur mit SENTRY_BROWSER_DSN
Eingebunden in partials/head (Portal, area: portal), web/layouts/web-master (area: web), components/layouts/auth/pressekonto (area: auth)

Fehlgeschlagene Livewire-Requests (5xx, 419) meldet der Server, nicht der Browser.

Tests melden nie an GlitchTip

phpunit.xml leert SENTRY_LARAVEL_DSN, SENTRY_DSN, SENTRY_BROWSER_DSN. Wächtertest: tests/Feature/Monitoring/ErrorReportingTest.php („the test suite never reports to the real glitchtip“). Tests, die Sentry-Ereignisse prüfen, benutzen Tests\Support\FakeGlitchTip::install().

Erkennungszeichen für Test-Rauschen in GlitchTip: Umgebung local und Texte wie „Queue weg“, „Datenbank nicht erreichbar“, SQLite-Fehler („General error: 1 no such table“ — Live ist MySQL), „no role named customer“. Bis 06.10.2026 kamen solche Einträge aus Testläufen mit lokaler DSN.


3. Zugriff per API (lesend)

Token: GLITCHTIP_API_TOKEN in der lokalen .env — nur lesen (project:read, event:read). Kein org:read (Organisationsliste → 403), kein Schreiben (Auflösen → 403). Den Token nie ausgeben, nie committen.

Alle Befehle aus dem Projektverzeichnis:

T=$(grep -E "^GLITCHTIP_API_TOKEN=" .env | cut -d= -f2- | tr -d "'\"")
B=https://errors.adametz.media/api/0

Offene Einträge eines Projekts (Projekt 1 = Server, 2 = Browser; environment=production für Live, weglassen für alle):

curl -s -H "Authorization: Bearer $T" \
  "$B/organizations/adametz-media/issues/?project=1&query=is:unresolved&environment=production&limit=100" \
| python3 -c "
import json,sys
for i in json.load(sys.stdin):
    print(i['id'], i['level'], i['count'], i['firstSeen'][:16], i['lastSeen'][:16], '|', (i['title'] or '')[:100])"

Letztes Ereignis eines Eintrags mit Umgebung, Release, URL und Stacktrace:

curl -s -H "Authorization: Bearer $T" "$B/issues/<ID>/events/latest/" | python3 -c "
import json,sys
e=json.load(sys.stdin); tags={t['key']:t['value'] for t in e.get('tags',[])}
print('env:',tags.get('environment'),'| release:',tags.get('release'),'| area:',tags.get('area'),'| browser:',tags.get('browser'))
for en in e.get('entries',[]):
    if en['type']=='exception':
        for v in en['data'].get('values',[]):
            print('EXC',v.get('type'),':',(v.get('value') or '')[:300])
            for f in ((v.get('stacktrace') or {}).get('frames') or [])[-8:]:
                print('   ',f.get('filename') or f.get('absPath'),f.get('function'),f.get('lineNo'),f.get('colNo'))
    if en['type']=='request': print('REQ',en['data'].get('url'))"

Mehrere Ereignisse eines Eintrags: $B/issues/<ID>/events/?limit=10. Projekte: $B/projects/.

Weboberfläche: https://errors.adametz.media/adametz-media/issues?project=1.


4. Aufgabe: GlitchTip auswerten und Fehler beheben

Wenn der Auftrag lautet „schau in GlitchTip“, „was sagt GlitchTip“ o. Ä.:

  1. Abrufen. Offene Einträge beider Projekte, zuerst environment=production, dann ohne Filter.

  2. Einordnen — jeder Eintrag in genau eine Klasse:

    Klasse Erkennen Vorgehen
    Test-/Entwicklungsrauschen Umgebung local, Texte aus Tests (Abschnitt 2) Nichts am Code; Betreiber markiert „Resolved“. Taucht es mit production auf → echter Fehler
    Bedienfehler am Server z. B. CommandNotFoundException In dontReport aufnehmen, falls wiederkehrend
    Externer Dienst vorübergehend Timeouts/5xx von Google, OpenAI, Stripe … Retry + Warnung statt report(), Abbruch- und Zeitbudget; Muster: SearchConsoleClient + SearchConsoleUnavailable
    Echter Bug Stacktrace in app/, resources/, Browserfehler mit eigener Datei/URL Schritte 3–6
    Unklar z. B. Error: [object Object] Erfassung verbessern (mehr Kontext, keine personenbezogenen Daten), auf das nächste Auftreten warten
  3. Code finden. Stacktrace (filename, function, lineNo), culprit, URL (REQ), Bereich (area). Bei Browserfehlern zeigen die Frames oft nur livewire.min.js — der Hinweis steckt dann im Funktionsnamen (z. B. [Alpine] __('…') = Alpine-Ausdruck) → in resources/views nach dem Ausdruck suchen.

  4. Reproduzieren mit rotem Test, dann Fix (Projektregel: jede Änderung mit Test). Ist der Fehler ein Muster, das wieder auftreten kann, einen Wächtertest über alle Dateien schreiben (Beispiele: BladePhpBlockGuardTest, BladeAlpineTranslationGuardTest).

  5. Qualitätsgates: betroffene Tests, dann php artisan test --compact --parallel, vendor/bin/phpstan analyse --memory-limit=2G, vendor/bin/pint --dirty --format agent; bei JS npm run build.

  6. Dokumentieren: Eintrag in Abschnitt 7 (ID, Klasse, Ursache, Fix, Commit). Commit-Nachricht nennt die GlitchTip-ID.

  7. Ausliefern über den nächsten Deploy (Hotfix: letzte Versionsstelle, z. B. v1.1.1; Ablauf wie ../betrieb/deploy-v1.1.0.md).

  8. Auflösen in GlitchTip macht der Betreiber (Token ist nur lesend) — erst nach dem Deploy. Kommt der Fehler mit neuem Release wieder, öffnet GlitchTip den Eintrag erneut.


5. Regeln, die nicht verletzt werden dürfen

  • Datenschutz (M4): send_default_pii bleibt false, max_request_body_size bleibt never, Log- und Cache-Breadcrumbs bleiben aus, ErrorReportScrubber bleibt in before_send. Kein Name, keine E-Mail, keine IP an GlitchTip — nur die interne User-ID. Neue Query-Parameter, die mitgehen sollen, nur über ErrorReportScrubber::AllowedQueryParameters (und dieselbe Liste in error-reporting.js / Umami-Filter).
  • Keine variablen Zahlen in Fehlermeldungen, wenn sie gruppiert werden sollen: GlitchTip gruppiert nach Text. …after 20002 ms und …after 20001 ms wurden drei getrennte Einträge (Issues 11, 13, 14). Variable Werte in den Kontext, nicht in die Meldung — oder einen Fingerprint setzen wie ErrorSignal.
  • Vorübergehende Fremdfehler nicht einzeln melden. Sonst flutet ein Google-Ausfall GlitchTip und verdeckt echte Fehler.
  • Tests melden nie an GlitchTip (Abschnitt 2). Neue Sentry-Tests nur mit FakeGlitchTip.
  • Token nur lesend. Für Schreibrechte (Auflösen per API) erst mit dem Betreiber sprechen.

6. Konfiguration

Variable Wo Wert
SENTRY_LARAVEL_DSN .env DSN Projekt 1
SENTRY_BROWSER_DSN .env DSN Projekt 2 (öffentlich, steht im HTML)
SENTRY_ENVIRONMENT .env production (Live) bzw. local
SENTRY_RELEASE / APP_VERSION .env leer lassen — kommt aus der Datei RELEASE
GLITCHTIP_API_TOKEN nur lokale .env Lese-Token für Abschnitt 3

Release: App\Support\Monitoring\Release::current() liest APP_VERSION bzw. SENTRY_RELEASE, sonst die Datei RELEASE im Projektwurzelverzeichnis. Die Datei entsteht beim Paketbau auf dem Tag (git describe --tags --always > RELEASE) und wird mit ausgeliefert. Nicht später auf einem anderen Stand neu erzeugen: dann steht z. B. v1.1.0-3-gb1cec16 statt v1.1.0 (so am 05./06.10. auf Live). Nach Änderung: php artisan config:cache.


7. Protokoll der Einträge

Stand 06.10.2026 (Abruf per API). „Fix“ = im Code behoben; ausgeliefert mit dem nächsten Deploy.

ID Projekt Umgebung Eintrag Klasse Ursache / Maßnahme Stand
1 Server local GlitchTip-Test Server Test Anbindungstest 05.10. auflösen
8 Server production Deploy-Test v1.1.0 Test Deploy-Prüfung 05.10. auflösen
3, 16 Server local Queue weg Test-Rauschen ExpireGrandfatheringTest meldete an echte DSN Fix 2f02acc, auflösen
5, 17 Server local Datenbank nicht erreichbar Test-Rauschen PressReleaseSchedulingTest Fix 2f02acc, auflösen
4 Server local no such table: conversion_events Test-Rauschen SQLite im Test Fix 2f02acc, auflösen
6 Server local Wasserstandsmarke steht auf 1 statt 0 Test-Rauschen Konkurrenztest der Aufruf-Aggregation Fix 2f02acc, auflösen
7 Server local no role named customer Test-Rauschen Tests ohne Rollen-Seeder Fix 2f02acc, auflösen
9 Server production Command "config:cachels" is not defined Bedienfehler Tippfehler auf dem Server dontReport (16af374); auflösen
11, 13, 14 Server production cURL error 28 … searchconsole.googleapis.com Extern Google URL Inspection hing; jeder Timeout einzeln gemeldet, Lauf 1¾ h Fix a90f24a: Retry, Warnung statt Meldung, Abbruch nach 5 in Folge, 40-min-Budget; nach Deploy auflösen
12 Server production URL Inspection API antwortet mit 500 Extern Google-interner Fehler wie 11
15 Browser production ReferenceError: __ is not defined Bug /register: :placeholder="__('…')" an <input> → Alpine wertet PHP-Helfer im Browser aus Fix 16af374: placeholder="{{ __('…') }}", Wächtertest BladeAlpineTranslationGuardTest; nach Deploy auflösen
10 Browser production Error: [object Object] Unklar Promise-Ablehnung mit Objekt auf businessportal24.com/de Erfassung verbessert (16af374, Typ + Inhalt); nach Deploy neues Auftreten abwarten