dashboard-blipburst
v0.2.4
Published
Local live dashboard for BlipBurst — fault feed, experiment run history, endpoint/tenant chaos heatmap, and MTTR per fault type. Install globally, point BlipBurst's logger/webhook at it.
Downloads
449
Maintainers
Readme
dashboard-blipburst
A local, zero-dependency live dashboard for BlipBurst — see fault injection happen in real time, browse a history of past experiment runs, spot which endpoints get chaos-tested (and which never do), and track MTTR per fault type.
It's a standalone package: installing or running it never touches your blipburst install, and blipburst has no dependency on it either. Wire the two together with a couple of lines in your own app config.
Install
npm install -g dashboard-blipburstRun it
blipburst-dashboard- Binds to port
4477by default. If that's taken, it auto-increments (4478,4479, …) and prints the port it actually bound. - Writes the resolved port to
.blipburst/portin the current directory, so the SDK-side adapter (below) can find it automatically without you hardcoding a port anywhere. - Open the printed URL in a browser for the live dashboard.
Override the preferred port with --port / -p, or the BLIPBURST_DASHBOARD_PORT env var:
blipburst-dashboard --port 5000Hosted environments
Locally, the SDK-side adapter finds the dashboard automatically via the .blipburst/port file written to the current directory — that only works because both processes share a filesystem. In a hosted setup (the dashboard deployed somewhere, the BlipBurst-instrumented app deployed somewhere else), there's no shared file, so use env vars on both sides instead:
On the dashboard's deployment, set PORT (the convention Render/Railway/Fly/Heroku-style platforms already inject) or BLIPBURST_DASHBOARD_PORT. Either one makes the server bind exactly there and fail loudly instead of silently drifting to another port on conflict — unlike a bare local run, which auto-increments for dev convenience, a hosted deployment can only be reached on the port its platform is routing to, so drifting silently would just make it unreachable:
# most hosting platforms set PORT for you automatically — nothing else needed
blipburst-dashboardOn the app reporting events, set BLIPBURST_DASHBOARD_URL to the dashboard's public URL — every adapter function (toDashboardTransport, toDashboardWebhookUrl, wrapForDashboard) picks it up automatically, no code change needed:
BLIPBURST_DASHBOARD_URL=https://blipburst-dashboard.internal.example.com node server.jsWire it up to BlipBurst
No changes to blipburst itself are needed — everything below plugs into config options blipburst already supports.
Option A — logger transport (recommended, covers everything)
import { BlipBurst } from 'blipburst';
import { toDashboardTransport } from 'dashboard-blipburst';
const sim = new BlipBurst({
profile: 'flaky',
logger: { transport: toDashboardTransport() },
});If the dashboard isn't running when an event fires, toDashboardTransport buffers it to .blipburst/log.jsonl instead of throwing — nothing is lost, and the backlog flushes automatically the next time a transport is created (e.g. your app restarts with the dashboard now up), or on demand:
import { flushBuffer } from 'dashboard-blipburst';
await flushBuffer();Option B — webhook (uses BlipBurst's existing webhook emitter)
import { BlipBurst } from 'blipburst';
import { toDashboardWebhookUrl } from 'dashboard-blipburst';
const sim = new BlipBurst({
profile: 'cascade',
webhook: { url: toDashboardWebhookUrl() },
});Option C — full request coverage (for the "untested endpoints" heatmap)
BlipBurst only logs when a fault actually fires, so log/webhook wiring alone can't tell "endpoint gets hit constantly but never chaos-tested" apart from "endpoint isn't hit at all." wrapForDashboard wraps makeRequest() so every call is reported, faulted or not:
import { BlipBurst } from 'blipburst';
import { wrapForDashboard, toDashboardTransport } from 'dashboard-blipburst';
const sim = wrapForDashboard(
new BlipBurst({ profile: 'flaky', logger: { transport: toDashboardTransport() } })
);
await sim.makeRequest(); // now tracked whether or not a fault firedThis also unlocks exact MTTR (measured time from a failed call to the next success on that endpoint) instead of the log-only estimate (duration of consecutive fault bursts).
A quiet dashboard in production is expected, not broken
BlipBurst's enabled: false option (or BLIPBURST_ENABLED=false) is a global kill switch — when it's off, no faults ever fire, so nothing reaches any of the ingest endpoints above regardless of how the transport/webhook/wrapper is wired. If you point the dashboard at a production deployment that correctly disables chaos there, an empty live feed and heatmap is the dashboard working correctly, not a wiring bug. Point it at a dev/staging deployment (where chaos is actually enabled) to see live data.
What the dashboard shows
- Live fault feed — streamed over SSE as
fault.injected/request.failedevents arrive. - Chaos coverage heatmap — per endpoint: total requests and how many were faulted. Rows tagged
untestedwere exercised but never fault-injected (only available when usingwrapForDashboard). - MTTR per fault type — mean time from a fault firing to recovery, per
Fault['kind']. - Experiment run history — events grouped by run (one per adapter instance / process), with start/end time, event and failure counts, and a fault-kind breakdown.
Data retention
Two different things are kept, on purpose, with different lifetimes:
- Raw event log (
.blipburst/events.jsonl) — the last 5,000 events, in memory and on disk. This backs the live feed //api/events. It's a rolling window: once it fills up, older raw events are dropped to keep disk and memory use bounded, whether the dashboard runs for an hour or a month. - Aggregates (
.blipburst/aggregates.json) — per-endpoint heatmap totals, per-fault-kind MTTR running averages, and per-run summaries. These are updated incrementally on every event and never pruned, so the heatmap, MTTR, and run history stay accurate for the dashboard's entire lifetime even after the raw log has rolled over many times. This file stays small (a few KB) regardless of how much raw traffic has passed through.
In the browser, the dashboard also caches recent events in IndexedDB (capped at 2,000 rows, oldest pruned first) so a page reload repaints instantly from local cache and only delta-fetches what's new from the server, instead of re-downloading the full recent-events window every time.
HTTP API
| Endpoint | Method | Purpose |
|---|---|---|
| /ingest/log | POST | Used by toDashboardTransport() |
| /ingest/webhook | POST | Used by toDashboardWebhookUrl() |
| /ingest/request | POST | Used by wrapForDashboard() |
| /events/stream | GET (SSE) | Live event stream |
| /api/events | GET | Recent events (?limit=, ?since=) |
| /api/runs | GET | Grouped run history |
| /api/heatmap | GET | Endpoint x fault-kind matrix |
| /api/mttr | GET | MTTR per fault kind |
| /api/health | GET | Liveness check |
License
MIT © Ajmal N
