feat: Prometheus /metrics endpoint (ENABLE_METRICS) #4

Merged
rcsheets merged 2 commits from feat/prometheus-metrics into main 2026-07-24 03:20:47 +00:00
Owner

Adds a Prometheus-compatible /metrics endpoint -- the machine-readable signal stock acng lacks (it has only the HTML report page and log parsing), which is what kept the InRelease-corruption incidents invisible until apt tripped over them.

Exposed counters:

acng_bytes_fetched_total          upstream -> acng
acng_bytes_served_total           acng -> clients
acng_downloads_total{result="complete"|"error"}

Build-guarded. Everything is behind the CMake option ENABLE_METRICS (default on), which sets #cmakedefine HAVE_PROMETHEUS. With -DENABLE_METRICS=off none of it compiles and the binary matches stock acng -- same pattern as USE_SSL/HAVE_CHECKSUM. No new libraries; the text exposition is hand-rolled in src/metrics.{h,cc}.

Integration points:

  • Byte counters at aclogger.cc transfer(), into dedicated lock-free atomics -- the existing totalIn/totalOut are exchange(0)-reset by the report page and can't back a monotonic counter.
  • Download outcomes at fileitem.cc DlFinish/DlSetError, guarded to count only the real state transition (no double-count on repeat calls).
  • The endpoint is an unauthenticated maintenance work type dispatched like style.css, so a scraper needs no admin password. It exposes only aggregate counters, never cache contents.

Verified: the module compiles clean under -Wall -Wextra and emits valid exposition format (checked standalone); the CI image build + smoke test now also scrapes /metrics and asserts the acng_downloads_total TYPE line.

Next (noted in FORK.md): acng_downloads_truncated_total -- fetches ending with fewer bytes than the declared Content-Length, the range-splice/abort precursor that started this whole investigation. Deferred to a follow-up because it needs careful placement in the download path.

🤖 Generated with Claude Code

Adds a Prometheus-compatible `/metrics` endpoint -- the machine-readable signal stock acng lacks (it has only the HTML report page and log parsing), which is what kept the InRelease-corruption incidents invisible until apt tripped over them. **Exposed counters:** ``` acng_bytes_fetched_total upstream -> acng acng_bytes_served_total acng -> clients acng_downloads_total{result="complete"|"error"} ``` **Build-guarded.** Everything is behind the CMake option `ENABLE_METRICS` (default on), which sets `#cmakedefine HAVE_PROMETHEUS`. With `-DENABLE_METRICS=off` none of it compiles and the binary matches stock acng -- same pattern as `USE_SSL`/`HAVE_CHECKSUM`. No new libraries; the text exposition is hand-rolled in `src/metrics.{h,cc}`. **Integration points:** - Byte counters at `aclogger.cc` `transfer()`, into dedicated lock-free atomics -- the existing `totalIn`/`totalOut` are `exchange(0)`-reset by the report page and can't back a monotonic counter. - Download outcomes at `fileitem.cc` `DlFinish`/`DlSetError`, guarded to count only the real state transition (no double-count on repeat calls). - The endpoint is an unauthenticated maintenance work type dispatched like `style.css`, so a scraper needs no admin password. It exposes only aggregate counters, never cache contents. Verified: the module compiles clean under `-Wall -Wextra` and emits valid exposition format (checked standalone); the CI image build + smoke test now also scrapes `/metrics` and asserts the `acng_downloads_total` TYPE line. **Next (noted in FORK.md):** `acng_downloads_truncated_total` -- fetches ending with fewer bytes than the declared `Content-Length`, the range-splice/abort precursor that started this whole investigation. Deferred to a follow-up because it needs careful placement in the download path. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat: Prometheus /metrics endpoint (ENABLE_METRICS)
All checks were successful
ci / image (pull_request) Successful in 1m37s
5b0a6555cf
Stock acng exposes no machine-readable metrics -- only the HTML report page
and after-the-fact log parsing -- which is what left the InRelease-corruption
incidents invisible until apt tripped over them. Adds an unauthenticated
/metrics endpoint (Prometheus text exposition) with:

  acng_bytes_fetched_total          (upstream -> acng)
  acng_bytes_served_total           (acng -> clients)
  acng_downloads_total{result=...}  (complete | error)

The whole feature is gated behind the CMake option ENABLE_METRICS (default
on) -> #cmakedefine HAVE_PROMETHEUS; with it off, none of it compiles and the
binary matches stock acng. No new libraries -- the exposition format is
hand-rolled in src/metrics.{h,cc}.

Counters are dedicated lock-free atomics: the existing totalIn/totalOut are
exchange(0)-reset by the report page and can't back a monotonic counter.
Increment points: aclogger transfer() for bytes, fileitem DlFinish/DlSetError
for the download outcome (guarded to count only the real state transition).
The endpoint is an unauthenticated maintenance work type, dispatched like
style.css so a scraper needs no admin password; it exposes only aggregate
counters, never cache contents. CI smoke test now scrapes /metrics too.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
style: uniform trailing comma on the guarded enum value
All checks were successful
ci / image (pull_request) Successful in 1m36s
e25b000657
Both preprocessor branches now end the enumerator list with a trailing comma
rather than only the disabled branch relying on it -- valid C++11+ either way,
just consistent to read.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
rcsheets deleted branch feat/prometheus-metrics 2026-07-24 03:20:47 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
brooktrails/apt-cacher-ng!4
No description provided.