submilli_engine/runtime/metrics.rs
1//! Embedder hook for runtime observability. The interpreter times host-side
2//! operations (currently HTTP transport) and hands each one to a [`MetricsSink`]
3//! the embedder installs on [`StoreData`](super::StoreData). The default sink
4//! discards everything, so the pure-interpreter path stays dependency-free —
5//! the binary crates (CLI, server) are the only place a real metrics backend
6//! (Sentry) is wired in.
7
8/// One completed HTTP host operation, handed to [`MetricsSink::http_operation`]
9/// after the transport returns (success or failure).
10#[derive(Clone, Debug)]
11pub struct HttpMetric {
12 /// The gated capability that ran: `http.get`, `http.post`, `http.download`, …
13 pub capability: String,
14 /// Destination host from the request URL (e.g. `api.example.com`); empty when
15 /// the URL doesn't parse.
16 pub host: String,
17 /// Wall-clock of the network transport — `send` plus capped body read for a
18 /// request, or stream-plus-fsync for a download. Excludes arg marshalling.
19 pub duration_ms: u64,
20 /// HTTP status, or `0` if the request failed before any response arrived.
21 pub status: u16,
22 /// Bytes received: response-body length, or bytes written for a download.
23 pub bytes: u64,
24 /// Bounded outcome class: `ok`, `error`, `timeout`, or `too_large`.
25 pub outcome: &'static str,
26}
27
28/// Embedder sink for runtime metrics. Every method has a no-op default so an
29/// embedder only overrides what it reports on.
30pub trait MetricsSink: Send + Sync {
31 /// An HTTP host operation finished. Called once per `http_request` /
32 /// `http_download` host call, on both the success and failure paths.
33 fn http_operation(&self, _metric: HttpMetric) {}
34}
35
36/// Discards every metric. The [`StoreData`](super::StoreData) default.
37pub struct NoopMetricsSink;
38
39impl MetricsSink for NoopMetricsSink {}