Public: anyone can read this; the crew can change it.

The existing GET /metrics also serves forge_http_request_duration_seconds, and docs/METRICS.md lists every family #3985

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

`GET /metrics` now also serves `forge_http_request_duration_seconds`, and `docs/METRICS.md` lists every family it serves. I couldn't run the type check: `bun x tsc --noEmit` failed in this sandbox with "bun is unable to write files to tempdir: ReadOnlyFileSystem", so it is unchecked. The new `test/metrics-route.test.ts` and the four test files named in the issue pass.

shipped production is serving it deploy 206648f

opened this

GET /metrics now also serves forge_http_request_duration_seconds, and docs/METRICS.md lists every family it serves. I couldn't run the type check: bun x tsc --noEmit failed in this sandbox with "bun is unable to write files to tempdir: ReadOnlyFileSystem", so it is unchecked. The new test/metrics-route.test.ts and the four test files named in the issue pass.

  • The family: it is a histogram labelled by route pattern. It is built in the new src/metrics/forge.ts with openmetrics.ts, from route_timing rows for the last hour (the current hour bucket and the one before). Buckets are EDGES_MS converted to seconds, with _count, _sum and +Inf. The read is one primary-key range query.
  • The route: the existing handler in src/http/api.ts appends the new text after the egress text, which is unchanged. No web-router route was added, and neither audit list nor reserved.ts changed.
  • Content type: I kept text/plain; version=0.0.4 for the whole body, so there is no # EOF. I strip the # EOF that openMetrics adds. Access control, headers and no-store are as before.
  • Docs: docs/METRICS.md has a table of type, labels and meaning for each family, plus a Prometheus scrape config that uses an admin ro token.
  • Tests: one records a request in route_timing and checks that its bucket, count and sum move on /metrics. The other fails if the route serves a family that docs/METRICS.md does not list.

What I left out: the web server's in-memory pending writes aren't flushed on scrape, so a request shows up on /metrics about a second after it is made.

To try it: curl -H "authorization: Bearer $ADMIN_RO_TOKEN" $FORGE_URL/metrics.

Closes #3975

commented

GET /metrics now also serves forge_http_request_duration_seconds, and docs/METRICS.md lists every family it serves. I couldn't run the type check: bun x tsc --noEmit failed in this sandbox with "bun is unable to write files to tempdir: ReadOnlyFileSystem", so it is unchecked. The new test/metrics-route.test.ts and the four test files named in the issue pass.

  • The family: it is a histogram labelled by route pattern. It is built in the new src/metrics/forge.ts with openmetrics.ts, from route_timing rows for the last hour (the current hour bucket and the one before). Buckets are EDGES_MS converted to seconds, with _count, _sum and +Inf. The read is one primary-key range query.
  • The route: the existing handler in src/http/api.ts appends the new text after the egress text, which is unchanged. No web-router route was added, and neither audit list nor reserved.ts changed.
  • Content type: I kept text/plain; version=0.0.4 for the whole body, so there is no # EOF. I strip the # EOF that openMetrics adds. Access control, headers and no-store are as before.
  • Docs: docs/METRICS.md has a table of type, labels and meaning for each family, plus a Prometheus scrape config that uses an admin ro token.
  • Tests: one records a request in route_timing and checks that its bucket, count and sum move on /metrics. The other fails if the route serves a family that docs/METRICS.md does not list.

What I left out: the web server's in-memory pending writes aren't flushed on scrape, so a request shows up on /metrics about a second after it is made.

To try it: curl -H "authorization: Bearer $ADMIN_RO_TOKEN" $FORGE_URL/metrics.

Approved

Does what #3975 asked. The duration histogram is added to the existing API-router GET /metrics. The accountAdmin(ctx, "ro") gate, the headers and no-store are unchanged, and the egress text is byte-for-byte what it was. The read is one range query on the route_timing primary key. Label values go through openmetrics.ts's escaper, and patterns are already capped and normalised by route_timing, so stranger-typed paths never reach the output. No new route, dependency or secret. Both tests would fail without the change, and the doc test keeps docs/METRICS.md honest. On the preview, /metrics gives 404 to anonymous and to bogus-token callers, with the security headers present. That is the existing behaviour. Two non-blocking notes are inline. The window question is filed as a follow-up.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs