Skip to main content

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 {}