Skip to main content

iroh_proxy_utils/downstream/
metrics.rs

1use iroh_metrics::{Counter, MetricsGroup};
2
3#[derive(Debug, MetricsGroup)]
4#[non_exhaustive]
5#[metrics(name = "proxy-downstream", default)]
6pub struct DownstreamMetrics {
7    /// Total number of downstream requests that began processing (HTTP or TCP).
8    pub requests_accepted: Counter,
9
10    /// TCP-only requests (proxy is operating in `ProxyMode::Tcp`).
11    pub requests_accepted_tcp: Counter,
12    /// HTTP/1 requests that reached the downstream proxy.
13    pub requests_accepted_h1: Counter,
14    /// HTTP/2 requests that reached the downstream proxy.
15    pub requests_accepted_h2: Counter,
16
17    /// HTTP/1 CONNECT requests, i.e. e2e tunnels.
18    pub requests_accepted_h1_connect: Counter,
19    /// HTTP/1 upgrade requests (WebSocket, etc.) that were forwarded.
20    pub requests_accepted_h1_upgrade: Counter,
21
22    /// HTTP/2 CONNECT requests (excluding extended CONNECT), i.e. e2e tunnels.
23    pub requests_accepted_h2_connect: Counter,
24    /// HTTP/2 extended CONNECT requests (RFC 8441), i.e. WebSocket over HTTP/2.
25    pub requests_accepted_h2_extended_connect: Counter,
26
27    /// Requests rejected by the `RequestHandler` before opening an upstream tunnel.
28    pub requests_denied: Counter,
29    /// Requests that successfully finished and were proxied upstream.
30    pub requests_completed: Counter,
31    /// Requests that failed after being accepted (upstream or network error).
32    pub requests_failed: Counter,
33
34    /// Number of QUIC connections opened toward upstream iroh nodes.
35    pub iroh_connections_opened: Counter,
36    /// Connections that closed cleanly from the local side (pool dropped conn after idle timeout)
37    pub iroh_connections_closed_idle: Counter,
38    /// Connections that terminated with an error (timeouts, transport errors, resets).
39    pub iroh_connections_closed_error: Counter,
40
41    /// Bytes written to the upstream proxy (downstream ➜ upstream).
42    pub bytes_to_upstream: Counter,
43    /// Bytes read from the upstream proxy (upstream ➜ downstream).
44    pub bytes_from_upstream: Counter,
45}
46
47impl DownstreamMetrics {
48    /// Returns the number of requests currently in flight.
49    ///
50    /// Calculated as `accepted - completed - failed` using saturating arithmetic.
51    pub fn active_requests(&self) -> u64 {
52        self.requests_accepted
53            .get()
54            .saturating_sub(self.requests_completed.get())
55            .saturating_sub(self.requests_failed.get())
56    }
57
58    /// Returns the total number of opened QUIC connections.
59    pub fn total_iroh_connections(&self) -> u64 {
60        self.iroh_connections_opened.get()
61    }
62
63    /// Returns the estimated number of currently open QUIC connections.
64    pub fn active_iroh_connections(&self) -> u64 {
65        self.iroh_connections_opened
66            .get()
67            .saturating_sub(self.iroh_connections_closed_idle.get())
68            .saturating_sub(self.iroh_connections_closed_error.get())
69    }
70}