docs(support): document error ids, the support info and the support report, and ask for them in bug reports

This commit is contained in:
Marc-André Bombeck committed 2026-10-15 22:37:18 +02:00
1 parent 6979928d73
commit 703689069f
4 files changed
+133 -4

No files matched your search

+19 -3
View File
@@ -15,7 +15,7 @@ body:
id: version
attributes:
label: HealthLog version
description: Output of `/api/version` or the tag of the GHCR image you're running.
description: Settings, About shows it, as does `/api/version`, or the tag of the GHCR image you're running.
placeholder: "1.4.19"
validations:
required: true
@@ -55,11 +55,27 @@ body:
3. See error
validations:
required: true
- type: input
id: error-id
attributes:
label: Error ID
description: If the failure showed an error ID (eight characters, e.g. `3f9a2c1b`), paste it here. The operator finds the event with it under Admin, App logs.
placeholder: "3f9a2c1b"
- type: textarea
id: support-info
attributes:
label: Support info / support report
description: |
Everyone: Settings, About, "Copy support info".
Operators: Admin, System status, "Support report", then Copy.
Both are redacted (no names, emails, values or tokens); read them before you paste.
See https://github.com/MBombeck/HealthLog/blob/main/docs/self-hosting/support.md
render: text
- type: textarea
id: logs
attributes:
label: Relevant logs / screenshots
description: Paste any relevant log output (redact secrets) or attach screenshots. Wide-event logs from `/admin/app-logs` are useful.
label: Screenshots / other logs
description: Attach screenshots, or paste other log output if you have it. Redact secrets and personal data first.
render: shell
- type: input
id: browser
+4 -1
View File
@@ -33,7 +33,10 @@ notes, and machine-readable specs that ship alongside the source:
three access levels, the eight sections a grant can be narrowed to,
managed profiles for somebody with no login and the guardians who look
after them, what revocation does and does not undo, and which trust
properties of the instance are unchanged by any of it.
properties of the instance are unchanged by any of it. And
[`self-hosting/support.md`](./self-hosting/support.md) — reporting a
problem: error ids, the support info every account can copy, the
operator's redacted support report, and finding an error in the admin log.
- [`using/`](./using/) — notes on using the app that sit close to the
code. [`using/search.md`](./using/search.md) covers the command palette's
record search: opening it, what it finds, how matching works, and its
+5
View File
@@ -218,6 +218,11 @@ NEXT_PUBLIC_DASHBOARD_SNAPSHOT=false pnpm build
## Troubleshooting
- **Where to look.** For a bug report, copy the support report (Admin,
System status) and the support info (Settings, About), and note the error
id the failure showed. Admin, App logs finds the event behind an error id.
What each contains, and what it never contains, is in
[`support.md`](./support.md).
- **`app` container exits with a Prisma migration error.** The
Postgres healthcheck races the migration on slow disks. Run
`docker compose restart app` once the database has stabilised —
+105
View File
@@ -0,0 +1,105 @@
# Reporting a problem
HealthLog does not send anything home, and nobody but the operator can read
an instance's logs. So a bug report has to carry what is needed to find the
fault. Two texts do that, and both are redacted before you see them.
| Who | Where | What it is |
| -------- | ---------------------------------------- | ------------------------------------------ |
| Everyone | Settings, About, **Copy support info** | Your app version, settings and connections |
| Operator | Admin, System status, **Support report** | The whole instance, accounts as numbers |
Add the **error id** of the failure if you have one, and paste both texts into
the [bug report](https://github.com/MBombeck/HealthLog/issues/new?template=bug_report.yml).
Read them before you post. They are built to contain nothing personal, but
you are the one publishing them.
## Error ids
When the server fails (a 5xx answer), the message shows **Error ID** and
eight characters, for example `3f9a2c1b`, with a copy button that copies the
full id. A page that fails to render shows one too when the server has one
to give: the request id of the failed call, or the digest the server printed
beside the stack in its log.
The id is the request id of the failing call. Every error answer of the API
carries it in `meta.requestId` and in the `x-request-id` header. An incoming
`x-request-id` is only adopted when it consists of letters, digits and hyphens
(8 to 64 characters); anything else is replaced with a fresh id.
The operator finds the event under **Admin, App logs** by typing the id (or
its first 8 characters) into **Error ID**. A search by id reads the second log
buffer, which keeps the last 1,000 warnings and errors of the process. Ordinary
traffic cannot push them out, so an error stays findable for much longer than
in the main buffer of 500 events. Both buffers live in memory: a restart
empties them, and a split `web` / `worker` deployment has one per process.
The same search works on the API:
```
GET /api/admin/app-logs?requestId=3f9a2c1b&ring=problems
```
A 4xx answer (a refused input, a missing permission) shows no id. Its message
says what to change.
## Support info (everyone)
**Settings, About, Copy support info** puts together, in your browser:
- server version and build, and your browser;
- language, time zone and the modules you have switched on;
- the AI state: whether a provider is set up, your usage level, and which AI
features are available and why not;
- for each connected source (Withings, Oura, and so on), its health state,
reason, last success, newest data and the last recorded sync attempts;
- the last five error ids of this browser session.
It never contains your username, email address, name, server address,
tokens, recorded values or record ids. Nothing is sent anywhere; the text
goes to your clipboard.
## Support report (operator)
**Admin, System status, Support report** creates a text with **Copy** and
**Download**. It is created when you press a button, not on page load, and
shown above the buttons so you can read it first. It contains:
- **Build:** version, build SHA, build time, Node, process type, heap limit,
uptime.
- **Database:** PostgreSQL version, server time zone, size, last applied
migration, unfinished migrations.
- **Configuration**, as yes or no only: secure cookie flag, OIDC, OIDC only,
Loki, GlitchTip, off-host backup, APNs, Web Push, SMTP, GeoLite2, the number
of `NOTIFICATION_PRIVATE_ORIGINS` entries, operator AI key, central Codex,
the AI provider types accounts chose, demo mode.
- **Jobs:** whether the worker runs in this process and when it last
reported, the newest finished job, and every queue with failures in the
last 72 hours with an error class (`timeout`, `TypeError`, `P2002`,
`ECONNREFUSED`, an HTTP status), never the message.
- **Connections:** per source, how many accounts are in each health state and
reason, which accounts are not `ok`, and open watchdog incidents.
- **AI:** the usage level default and ceiling, accounts per usage level, and
the provider ledger per provider type (working, failing, credential
refused, paused).
- **Notifications:** per channel, delivered, failed and skipped in the last 7
days, with the most frequent failure reasons.
- **Backups:** newest in-database copy, the last weekly run, off-host
freshness, and the last restore drill.
- **Recent warnings and errors:** the 20 most frequent action names in the
warning and error buffer of this process, with count, last seen and error
class.
Accounts appear as `Account 1`, `Account 2` and so on, numbered by creation.
The report never contains an email address, a username, an account id, a
recorded value, a token, or the host name of another service. As a second
layer, the finished text is scrubbed for the instance's own usernames,
emails, names and ids, for tokens, URLs, email addresses, ids, IP addresses
and host names before it is shown.
## Logs beyond the report
`docker compose logs app` prints every wide event as one JSON line;
`LOG_LEVEL=debug` adds debug events. With `LOKI_ENDPOINT` set the same events
go to Loki, and GlitchTip (Admin, General) receives unexpected server errors.
Each line carries `request_id`, so an error id finds its line there too.