Skip to content

feat(server): phase timings and connection levels (feature op-timing) - #16

Merged
casibbald merged 2 commits into
integration/microscaler-forkfrom
feat/server-op-timing
Nov 3, 2026
Merged

casibbald merged 2 commits into
integration/microscaler-forkfrom
feat/server-op-timing

Conversation

@casibbald

Copy link
Copy Markdown

Adds an optional op-timing feature. With it on, the server records its phases in op_duration_seconds{component="may_minihttp.server", op, outcome} (microscaler-timing). A host that renders that family shows them with no wiring.

op from to
accept_to_first_byte connection accepted its first request byte read (once per connection)
read_parse a request's first byte request fully parsed
service handed to the service service returned (err on failure)
response_write service returned response fully written to the socket
request_total first byte response fully written

Gauges, in op_gauge: open_connections, plus accept_backlog and accept_backlog_limit on Linux. The last two are read at scrape time from TCP_INFO on the listening socket; for a listener, tcpi_unacked and tcpi_sacked are the accept queue's length and limit.

Together these show where time goes that a client sees before the application's own timers start: accept queueing, a slow request read, or the response write.

The feature is off by default, and without it every hook is an empty inline function. With it, each request costs a few Instant::now() calls and atomic adds, and each connection allocates one small Vec.

Test: tests/server_timing.rs (--features op-timing) covers every op, a failed service call, the gauges, and open_connections returning to 0 after close. The default-feature server tests and the client lib tests also pass.

With the op-timing feature the server records, in op_duration_seconds
{component="may_minihttp.server", op, outcome} (microscaler-timing):

- accept_to_first_byte: connection accepted to its first request byte
- read_parse: a request's first byte to the request fully parsed
- service: the service call (err when it fails)
- response_write: the service returned to the response fully written
- request_total: first byte to response fully written

and in op_gauge: open_connections, and on Linux accept_backlog and
accept_backlog_limit, read from TCP_INFO on the listening socket at scrape
time. Together they show whether time a client sees before the
application's own timers is accept queueing, a slow request read, or the
response write. Off by default; without the feature every hook is an
empty inline function.
…argets

The connection loop that calls ConnTiming is unix-only, so Windows clippy (-D warnings) saw an unused struct and import.
@casibbald
casibbald merged commit e3967b8 into integration/microscaler-fork Nov 3, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant