diff --git a/docs/ops/deploy.md b/docs/ops/deploy.md index 6700f779e..68106fe17 100644 --- a/docs/ops/deploy.md +++ b/docs/ops/deploy.md @@ -143,6 +143,18 @@ itself still works: it walks the journey against an in-process instance once per leg with that leg broken, and fails if any of them comes back green. +## Error reporting + +HealthLog ships no default error-reporting target and never will: an +operator's crash reports must not leave their host because nobody told them +not to. Reporting starts only when someone types a DSN into **Admin → +Integrations → GlitchTip**, and that card states plainly whether reports are +going anywhere and which host they go to. + +For a maintainer-operated instance, set the DSN there after the first deploy — +it lives in the database, not in the environment, so it survives an image +upgrade and does not need a compose change. + ## Verify the image signature Every release image (the multi-arch manifest **index**, covering both diff --git a/messages/de.json b/messages/de.json index 84d2a27b9..d2b1c9cbb 100644 --- a/messages/de.json +++ b/messages/de.json @@ -6597,6 +6597,9 @@ "glitchtipDsnPlaceholder": "https://@glitchtip.example.com/", "glitchtipEnvironment": "GlitchTip Environment", "glitchtipEnvironmentPlaceholder": "production", + "glitchtipTargetOn": "Fehlerberichte gehen an {host}.", + "glitchtipTargetOff": "Fehlerberichte bleiben auf diesem Host. Es wird nichts verschickt.", + "glitchtipTargetNoTarget": "Fehler-Tracking ist an, aber kein Ziel gesetzt, also wird nichts verschickt.", "webPushVapidDescription": "Konfiguriere VAPID-Schlüssel und Subject direkt hier, damit Browser-Push ohne ENV-Variablen funktioniert.", "webPushVapidPublicKey": "VAPID Public Key", "webPushVapidPublicKeyPlaceholder": "BElx... (Base64URL)", diff --git a/messages/en.json b/messages/en.json index dcd603d32..2f4a06eb6 100644 --- a/messages/en.json +++ b/messages/en.json @@ -6597,6 +6597,9 @@ "glitchtipDsnPlaceholder": "https://@glitchtip.example.com/", "glitchtipEnvironment": "GlitchTip environment", "glitchtipEnvironmentPlaceholder": "production", + "glitchtipTargetOn": "Error reports go to {host}.", + "glitchtipTargetOff": "Error reports stay on this host. Nothing is sent anywhere.", + "glitchtipTargetNoTarget": "Error tracking is on, but no target is set, so nothing is sent.", "webPushVapidDescription": "Configure VAPID keys and subject here so browser push works without environment variables.", "webPushVapidPublicKey": "VAPID public key", "webPushVapidPublicKeyPlaceholder": "BElx... (Base64URL)", diff --git a/messages/es.json b/messages/es.json index 0188dd089..28aab6313 100644 --- a/messages/es.json +++ b/messages/es.json @@ -6597,6 +6597,9 @@ "glitchtipDsnPlaceholder": "https://@glitchtip.example.com/", "glitchtipEnvironment": "Entorno de GlitchTip", "glitchtipEnvironmentPlaceholder": "production", + "glitchtipTargetOn": "Los informes de errores van a {host}.", + "glitchtipTargetOff": "Los informes de errores se quedan en este host. No se envía nada.", + "glitchtipTargetNoTarget": "El seguimiento de errores está activado, pero no hay destino, así que no se envía nada.", "webPushVapidDescription": "Configura aquí las claves VAPID y el subject para que el push del navegador funcione sin variables de entorno.", "webPushVapidPublicKey": "Clave pública VAPID", "webPushVapidPublicKeyPlaceholder": "BElx... (Base64URL)", diff --git a/messages/fr.json b/messages/fr.json index 38dc08eb9..2e40628d5 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -6597,6 +6597,9 @@ "glitchtipDsnPlaceholder": "https://@glitchtip.example.com/", "glitchtipEnvironment": "Environnement GlitchTip", "glitchtipEnvironmentPlaceholder": "production", + "glitchtipTargetOn": "Les rapports d'erreur vont vers {host}.", + "glitchtipTargetOff": "Les rapports d'erreur restent sur cet hôte. Rien n'est envoyé.", + "glitchtipTargetNoTarget": "Le suivi des erreurs est activé, mais aucune cible n'est définie, donc rien n'est envoyé.", "webPushVapidDescription": "Configurez ici les clés VAPID et le subject pour que le push du navigateur fonctionne sans variables d'environnement.", "webPushVapidPublicKey": "Clé publique VAPID", "webPushVapidPublicKeyPlaceholder": "BElx... (Base64URL)", diff --git a/messages/it.json b/messages/it.json index 973619366..d883b2f5d 100644 --- a/messages/it.json +++ b/messages/it.json @@ -6597,6 +6597,9 @@ "glitchtipDsnPlaceholder": "https://@glitchtip.example.com/", "glitchtipEnvironment": "Ambiente GlitchTip", "glitchtipEnvironmentPlaceholder": "production", + "glitchtipTargetOn": "Le segnalazioni di errore vanno a {host}.", + "glitchtipTargetOff": "Le segnalazioni di errore restano su questo host. Non viene inviato nulla.", + "glitchtipTargetNoTarget": "Il tracciamento degli errori è attivo, ma non c'è una destinazione, quindi non viene inviato nulla.", "webPushVapidDescription": "Configura qui le chiavi VAPID e il subject affinché il push del browser funzioni senza variabili d'ambiente.", "webPushVapidPublicKey": "Chiave pubblica VAPID", "webPushVapidPublicKeyPlaceholder": "BElx... (Base64URL)", diff --git a/messages/ko.json b/messages/ko.json index 800afd943..549935a1a 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -6577,6 +6577,9 @@ "glitchtipDsnPlaceholder": "https://@glitchtip.example.com/", "glitchtipEnvironment": "GlitchTip 환경", "glitchtipEnvironmentPlaceholder": "production", + "glitchtipTargetOn": "오류 보고서는 {host}(으)로 전송됩니다.", + "glitchtipTargetOff": "오류 보고서는 이 호스트에 남습니다. 아무것도 전송되지 않습니다.", + "glitchtipTargetNoTarget": "오류 추적은 켜져 있지만 대상이 없어 아무것도 전송되지 않습니다.", "webPushVapidDescription": "환경 변수 없이 브라우저 푸시가 동작하도록 VAPID 키와 subject를 여기서 설정하세요.", "webPushVapidPublicKey": "VAPID 공개 키", "webPushVapidPublicKeyPlaceholder": "BElx... (Base64URL)", diff --git a/messages/pl.json b/messages/pl.json index 698a2e2c5..6bd2d6b15 100644 --- a/messages/pl.json +++ b/messages/pl.json @@ -6597,6 +6597,9 @@ "glitchtipDsnPlaceholder": "https://@glitchtip.example.com/", "glitchtipEnvironment": "Środowisko GlitchTip", "glitchtipEnvironmentPlaceholder": "production", + "glitchtipTargetOn": "Zgłoszenia błędów trafiają do {host}.", + "glitchtipTargetOff": "Zgłoszenia błędów zostają na tym hoście. Nic nie jest wysyłane.", + "glitchtipTargetNoTarget": "Śledzenie błędów jest włączone, ale nie ustawiono celu, więc nic nie jest wysyłane.", "webPushVapidDescription": "Skonfiguruj tutaj klucze VAPID i subject, aby push przeglądarki działał bez zmiennych środowiskowych.", "webPushVapidPublicKey": "Klucz publiczny VAPID", "webPushVapidPublicKeyPlaceholder": "BElx... (Base64URL)", diff --git a/src/components/admin/glitchtip-section.tsx b/src/components/admin/glitchtip-section.tsx index 746c8059e..1a7bdfc93 100644 --- a/src/components/admin/glitchtip-section.tsx +++ b/src/components/admin/glitchtip-section.tsx @@ -34,7 +34,30 @@ export function GlitchtipSection() { const glitchtipEnvironmentValue = glitchtipEnvironmentDraft ?? settings?.glitchtipEnvironment ?? "production"; - const configured = Boolean(settings?.glitchtipDsn); + /** + * The host the DSN addresses, and nothing else from it. An operator asking + * "where do my errors go" is asking for a hostname; the public key in the + * DSN answers a different question and does not belong in a status line. + * + * There is deliberately no default here and none anywhere else in the tree: + * a self-hoster's crash reports must not leave their host because nobody + * told them not to. Reporting starts when this operator types a target. + */ + const targetHost = ((): string | null => { + const dsn = settings?.glitchtipDsn; + if (!dsn) return null; + try { + return new URL(dsn).host || null; + } catch { + return null; + } + })(); + + // "Configured" has to mean reports are actually going somewhere. A DSN with + // the switch off sends nothing, and a green badge over that is the kind of + // reassurance an operator only discovers was wrong when they go looking for + // a crash that was never reported. + const reporting = Boolean(settings?.glitchtipEnabled && targetHost); const testGlitchtip = useMutation({ mutationFn: async () => { @@ -76,7 +99,7 @@ export function GlitchtipSection() { icon={AlertTriangle} title={t("admin.glitchtipTitle")} description={t("admin.glitchtipDescription")} - status={configured ? : null} + status={reporting ? : null} />
@@ -89,6 +112,13 @@ export function GlitchtipSection() { } disabled={updateSettings.isPending} /> +

+ {reporting && targetHost + ? t("admin.glitchtipTargetOn", { host: targetHost }) + : settings?.glitchtipEnabled + ? t("admin.glitchtipTargetNoTarget") + : t("admin.glitchtipTargetOff")} +