Skip to main content

tiny_proxy/metrics/
recorder.rs

1//! Request/TLS recording helpers and the in-flight request guard.
2
3/// Record a completed HTTP request.
4#[cfg(feature = "metrics")]
5pub fn record_request(method: &str, status: u16, site: &str, duration: std::time::Duration) {
6    use metrics::{counter, histogram};
7
8    counter!(
9        "http_requests_total",
10        "method" => method.to_owned(),
11        "status" => status.to_string(),
12        "site" => site.to_owned(),
13    )
14    .increment(1);
15
16    histogram!(
17        "http_request_duration_seconds",
18        "method" => method.to_owned(),
19        "status" => status.to_string(),
20    )
21    .record(duration.as_secs_f64());
22}
23
24/// No-op when `metrics` feature is disabled.
25#[cfg(not(feature = "metrics"))]
26pub fn record_request(_method: &str, _status: u16, _site: &str, _duration: std::time::Duration) {}
27
28/// RAII guard that tracks one in-flight request.
29///
30/// On creation, increments the `http_active_requests` gauge.
31/// Call `.record(status)` to record the request counter + latency histogram.
32/// On drop, decrements the gauge.
33pub struct MetricsGuard {
34    #[cfg(feature = "metrics")]
35    method: String,
36    #[cfg(feature = "metrics")]
37    site: String,
38    #[cfg(feature = "metrics")]
39    start: std::time::Instant,
40}
41
42impl MetricsGuard {
43    pub fn new(_method: String, _site: String) -> Self {
44        #[cfg(feature = "metrics")]
45        {
46            metrics::gauge!("http_active_requests").increment(1.0);
47        }
48        Self {
49            #[cfg(feature = "metrics")]
50            method: _method,
51            #[cfg(feature = "metrics")]
52            site: _site,
53            #[cfg(feature = "metrics")]
54            start: std::time::Instant::now(),
55        }
56    }
57
58    /// Record the request counter + duration histogram for this request.
59    pub fn record(&mut self, status: u16) {
60        #[cfg(feature = "metrics")]
61        {
62            record_request(&self.method, status, &self.site, self.start.elapsed());
63        }
64        #[cfg(not(feature = "metrics"))]
65        let _ = status;
66    }
67}
68
69#[cfg(feature = "metrics")]
70impl Drop for MetricsGuard {
71    fn drop(&mut self) {
72        metrics::gauge!("http_active_requests").decrement(1.0);
73    }
74}
75
76/// Record a TLS handshake result.
77#[cfg(feature = "metrics")]
78pub fn tls_handshake(status: &str) {
79    metrics::counter!("tls_handshakes_total", "status" => status.to_owned()).increment(1);
80}
81
82/// No-op when `metrics` feature is disabled.
83#[cfg(not(feature = "metrics"))]
84pub fn tls_handshake(_status: &str) {}