Repository navigation
Add the bitbang-metrics-dump command and a build/test CI workflow - #2
Conversation
deploy/upload_production cross-compiles ./cmd/bitbang-metrics-dump and
ships it next to signaling-go, and the README and production.env.example
document its use. But the command source was never committed, so the
production deploy fails at build time:
stat .../cmd/bitbang-metrics-dump: directory not found
Two things hid this: the test deploy only builds ./cmd/signaling, and
there was no CI. An unanchored `bitbang-metrics-dump` line in .gitignore
also matched the cmd/bitbang-metrics-dump/ source directory, not just the
intended root binary, so the source could not be committed in the first
place.
The command reads the SQLite database the recorder writes
(internal/metrics), via the modernc.org/sqlite driver already in the
module (so CGO_ENABLED=0 builds work), and prints snapshot rows as JSON:
- no args: the latest snapshot, as a JSON object
- -history N: the last N snapshots, as a JSON array, newest first
- -db PATH: the database (defaults to $METRICS_PATH)
The row type embeds metrics.Snapshot to reuse its JSON tags. It opens the
database read-only (mode=ro plus PRAGMA query_only): it never creates the
database and never modifies a recorded row. Tests run through the real
recorder, so they fail if the schema drifts, and exercise the command end
to end including its read-only guarantees.
The deploy ships the binary to /opt/bitbang and sets METRICS_PATH only in
the systemd unit, so the README and production.env.example show the
explicit invocation rather than a bare command that is neither on PATH nor
handed the database path.
CI runs go vet, go test, and the two deploy cross-builds, so a missing
build target fails in CI instead of at deploy time.
|
Hi @kodareef5, many thanks for this -- the metrics feature was incorporated mostly because I wanted to get some simple metrics of direct-vs-relay numbers. I'll give this a good look when I get back from travel. |
|
Thanks @kodareef5, and sorry this sat -- you were right about all of it, including the part I verified the diagnosis from a clean checkout:
One thing you could not have known, and it explains why the docs described the command --I had already written it. :) Having compared them, I am taking yours, and the deciding reason is not the one I expected: Mine opens the database read-write. A mistyped path makes SQLite create an empty The tests are the other half. Mine has none -- it could not, being untracked -- and yours run Merging as-isNot holding this for anything. It has waited long enough, and it fixes a deploy that is One thing I would like to change afterward, and I would rather ask than quietly rewrite your Nothing else. The On the CIGood instinct pointing the cross-build step at the same commands One addition: Also a heads-up for whenever you rebase: @Brumbelow's browser flow-control work in #4 adds Thanks again. A broken deploy path plus the reason it was invisible plus a test that keeps it |
What & why
deploy/upload_productioncross-compiles./cmd/bitbang-metrics-dumpand ships it besidesignaling-go, and the README +production.env.exampledocument it. But the command source was never committed, so the documented production deploy fails at build time:Two things kept this hidden: the test deploy (
upload_test) only builds./cmd/signaling, and there was no CI. The source was also swallowed by an unanchoredbitbang-metrics-dumpline in.gitignore, which matches thecmd/bitbang-metrics-dump/directory as well as the intended root binary, so it could not be committed in the first place.What's in this PR
The command the docs already describe:
-history N: the last N snapshots, as a JSON array, newest first-db PATH: the database (defaults to$METRICS_PATH)It reads the same SQLite database the recorder writes (
internal/metrics) via the pure-Gomodernc.org/sqlitedriver already in the module, so it builds underCGO_ENABLED=0like the deploy expects. No new dependencies. Therowtype embedsmetrics.Snapshot, so the counter keys are the ones/statusemits (tsand the two gauges are added on top;/statusalso carriesversion/protocol/active_codes, so this is a subset). It opens the database read-only (mode=roplusPRAGMA query_only): it never creates the database and never modifies a recorded row.Deploy realism: the binary ships to
/opt/bitbangandMETRICS_PATHis set only in the systemd unit, so a barebitbang-metrics-dumpon the box would hit "command not found" (or, with the full path, "no database path"). The README andproduction.env.examplenow show the explicit on-server invocation.Tests run through the real recorder (so they fail if the schema drifts) and cover the command end to end: object vs. array vs.
null/[]output, the$METRICS_PATHfallback, missing-path and negative-history errors, write rejection, special-character and relative database paths, and the JSON-key contract..gitignoreanchors the two build-artifact patterns to the module root, so a source directory can no longer collide with an ignored binary.CI (new):
go vet,go test, and the two deploy cross-builds, so a missing build target fails in CI instead of at deploy time.Verification
Example output:
{ "ts": "2026-07-31T00:05:00Z", "devices": 4, "clients": 6, "connection_requests_total": 200, "connections_direct_total": 120, "connections_relay_total": 60, "connections_tcp_relay_total": 10, "connections_failed_total": 10 }One question: is
bitbang-metrics-dumpmeant to exist (this PR assumes so, since the deploy and docs call for it), or was it dropped on purpose? If it was dropped, I can instead remove the references; the CI check stands either way.