In-app Bug Report¶
Every page in BamDude carries a floating red Bug button at the bottom-right corner. Click it to file a bug report against kainpl/bamdude without leaving the UI — BamDude collects sanitized debug logs + a screenshot + a structured support snapshot, posts them to the bamdude.top relay, and returns the freshly-created GitHub issue number on success.
Shipped in BamDude 0.4.4. Adapted from upstream Bambuddy 058f74a7 + dc4d77b9 + 57092822.
Why a relay?
BamDude itself never holds a GitHub PAT. The PAT is on the bamdude.top side, where the relay creates the issue against the upstream repo on your behalf. That asymmetry is the whole point — shipping a PAT in the BamDude image would mean every self-hoster gets one, with no way to revoke selectively.
The flow¶
The bubble is a small floating action button — Bug icon, red circle, bottom-right. It does not block any page content. Clicking opens a slide-in panel that walks through five states:
stateDiagram-v2
[*] --> form
form --> logging: Start Debug Logging
logging --> stopping: Stop & Submit (or 5-min auto-stop)
stopping --> submitting
submitting --> success
submitting --> error
error --> form: Retry
success --> [*]
form --> [*]: Cancel
Step 1 — Form¶
Three inputs:
- Description (required) — what went wrong. Plain text, free-form.
- Email (optional) — your email. If you fill this in, it gets included in a collapsed section of the GitHub issue body so the maintainer can follow up directly. Otherwise, GitHub-issue replies don't reach you.
- Screenshot (optional) — paste from clipboard, drag-and-drop, or click to file-pick. The image is canvas-compressed to 1920px max dimension at JPEG quality 0.7 before upload, so even a 4K screenshot ends up well under 1 MB.
A <details> block below the inputs shows exactly what data the report includes — and what it never includes (printer names, serials, IPs, access codes, passwords, IPs, emails, API keys, tokens, webhook URLs, hostnames, usernames). Read it before submitting if privacy is a concern.
Step 2 — Logging¶
Click Start Debug Logging and BamDude:
- Flips the global debug-log level to DEBUG (recording the previous value as
was_debugfor restoration). - Sends a fresh status push to every connected printer over MQTT, so the logs catch a current snapshot of every printer's state right at the start.
- Renders a 3-step progress indicator + a
MM:SSmono lap timer.
Now reproduce the bug in another tab. Detailed logs are captured continuously. The session auto-stops at 5 minutes as a safety cap — you can also click Stop & Submit earlier when you've reproduced what you need.
Step 3 — Stop & Submit¶
Hitting Stop:
- Pulls the last 200 sanitized log lines (printer names / serials / IPs / access codes / cloud emails / usernames are redacted on the server before they leave your install).
- Restores the previous log level (so DEBUG mode doesn't stick around if you didn't have it on).
- Hands the sanitized logs + form fields + screenshot off to
POST /bug-report/submit, which calls the configured relay.
Step 4 — Success¶
The relay creates a GitHub issue and returns the issue number + URL. The panel shows a Thank-You + a clickable View Issue #N link. Done — you can close the panel and keep working.
Step 5 — Error¶
If the relay is unreachable, returns 5xx, or rejects the payload, the panel surfaces a generic error message with a Retry button (which goes back to the form so you can adjust description/screenshot and try again). Every failed attempt is also logged in BamDude's bug_reports audit table for diagnosis.
What's sanitized¶
The support_info payload is built server-side by _collect_support_info() and _get_recent_sanitized_logs() — both intentionally narrow:
| Included | Never included |
|---|---|
| App version | Printer names |
| OS / architecture / Python version | Serial numbers |
| Database row counts (only counts, not data) | IP addresses |
| Printer models, nozzle counts, firmware versions | Access codes |
| Connectivity status booleans | Passwords |
| Integration status (Spoolman, MQTT, Home Assistant) | Email addresses |
| Non-sensitive settings (e.g. log retention, theme) | API keys / tokens |
| Network interface count (no IPs) | Webhook URLs |
| Docker details (memory limit, network mode hint) | Hostnames |
| Dependency versions | Usernames |
Sensitive strings are pulled from the live database at sanitization time and replaced with placeholders like [PRINTER], [SERIAL], [IP], [ACCESS_CODE], [USER], [EMAIL] in the logs. The replacement happens in BamDude before the payload leaves your install — neither the relay nor GitHub ever sees the originals.
One redaction does not work that way: if you sign in through LDAP, Distinguished Names become [DN]. A DN is per-user and comes from your directory, so there is nothing in the database to look it up by — it is recognised by its shape instead, and removed wherever it turns up. That matters because the leading CN= is the user's real name. The same rule applies to the support bundle.
Rate limiting¶
Two layers:
- Client-side, per BamDude install — 5 reports per hour. The counter is in-memory and resets on backend restart.
- Relay-side, per IP — 10 reports per hour by default (configurable on the relay). Behind Cloudflare, the relay reads the original IP from
CF-Connecting-IP, so it's per real client even if many BamDude installs share an outbound NAT.
If you hit the limit, the panel shows a Rate limit exceeded message; wait an hour and try again.
Configuration¶
One environment variable on the BamDude side:
| Variable | Default | What it does |
|---|---|---|
BUG_REPORT_RELAY_URL |
https://bamdude.top/api/bug-report |
Where the bubble POSTs submissions. Set to empty string to disable the bubble entirely. Override to point at your own relay if you self-host one. |
No other config — gating is via permissions: start-logging requires settings:update, stop-logging and submit require settings:read. Both default Operator and Admin groups have these.
Self-hosting the relay¶
If you don't want to use the public bamdude.top relay (offline farm, air-gapped LAN, distrust of a third party), you can run your own. The relay is a ~150 LOC Fastify service that's open source under the kainpl/bamdude.top repository. The relay/README.md walks through:
- Issue body shape (what gets sent to GitHub).
- Schema validation.
- Rate-limit knobs.
- Screenshot upload directory + nginx routing.
- systemd unit + hardening (NoNewPrivileges, ProtectSystem=strict, etc.).
- How to generate a fine-grained GitHub PAT scoped to a single repo's Issues only.
To use your own relay, set BUG_REPORT_RELAY_URL=https://your-relay.example.com/api/bug-report on the BamDude side and redeploy. The bubble will post there instead.
My reports¶
The form view of the dialog carries a collapsible My reports list — every report submitted from this install, newest first (up to 50), each with its current status and a link to the GitHub issue.
Statuses refresh the moment the list is expanded, through the relay's POST /api/bug-report/status proxy — the relay holds the GitHub token, so your install never needs one. Closed reports show as fixed or not planned (GitHub's state_reason); once a report reaches either terminal state it is never asked about again.
If the relay cannot be reached, the list still renders from the local table with a "showing last known statuses" notice — only the statuses can go stale, the list itself is always local.
Self-hosted relay
A self-hosted relay needs the status endpoint too (POST /status beside the submit route) — without it the list works, but statuses stay at submitted.
Audit table¶
Every submission attempt — successful or failed — writes one row to the bug_reports table:
| Column | Notes |
|---|---|
id |
PK. |
description |
What the operator typed. |
reporter_email |
Optional. |
github_issue_number / github_issue_url |
Set on success. |
status |
submitted / failed locally; refreshed from the GitHub issue to open, closed (fixed) or not_planned whenever the My reports list is opened. |
error_message |
Set on failed — relay error code, network exception, etc. |
email_sent |
True when the GitHub issue was created (the email_sent column name is a legacy from upstream — currently always tracks issue-creation success, not literal email delivery). |
created_at |
UTC timestamp. |
Useful for diagnosis when an operator says "I submitted a bug report and got an error" — query the table by created_at desc + status='failed' to see the captured error message.
Troubleshooting¶
Bubble doesn't appear
- Check that
BUG_REPORT_RELAY_URLis set (default fires at runtime; the bubble won't render if the env var is explicitly empty). - The bubble lives inside
<Layout>so it needs the user to be on a regular authenticated page. The setup-required gate (/setup) and login pages don't render Layout.
Submission fails with "Bug report relay is not available"
- Relay-side issue. Either bamdude.top is down, your network can't reach it, or the relay is rate-limiting your IP. Check via
curl -fsS https://bamdude.top/api/bug-report/health— should return{ok:true,repo:"kainpl/bamdude"}. - If you're behind a strict outbound proxy, allow
bamdude.top:443.
Submission fails with "Rate limit exceeded"
- Hit the per-instance 5/hour limit. Wait an hour, or restart the backend (the limit is in-memory and resets on restart — useful for testing).
Issue created but maintainer never replies
- Add your email to the next report. Without a contact channel, the issue is anonymous and follow-ups can only happen on the GitHub issue itself.
The relay implementation lives at
kainpl/bamdude.top→relay/.