gemini_genai_rs/telemetry/
metrics.rs

1//! Prometheus metric definitions — counters, histograms, gauges.
2//!
3//! Feature-gated behind `metrics`. When disabled, all functions compile to no-ops.
4
5/// Record a new session connection.
6#[cfg(feature = "metrics")]
7pub fn record_session_connected() {
8    metrics::counter!("gemini_genai_rs_connections_total").increment(1);
9    metrics::gauge!("gemini_genai_rs_sessions_active").increment(1.0);
10}
11
12/// Record a session disconnection.
13#[cfg(feature = "metrics")]
14pub fn record_session_disconnected() {
15    metrics::gauge!("gemini_genai_rs_sessions_active").decrement(1.0);
16}
17
18/// Record audio send latency.
19#[cfg(feature = "metrics")]
20pub fn record_audio_latency(latency_ms: f64) {
21    metrics::histogram!("gemini_genai_rs_audio_latency_ms").record(latency_ms);
22}
23
24/// Record time from end-of-speech to first model response.
25#[cfg(feature = "metrics")]
26pub fn record_response_latency(latency_ms: f64) {
27    metrics::histogram!("gemini_genai_rs_response_latency_ms").record(latency_ms);
28}
29
30/// Record current jitter buffer depth.
31#[cfg(feature = "metrics")]
32pub fn record_jitter_depth(depth_ms: f64) {
33    metrics::gauge!("gemini_genai_rs_jitter_buffer_depth_ms").set(depth_ms);
34}
35
36/// Record a jitter buffer underrun.
37#[cfg(feature = "metrics")]
38pub fn record_jitter_underrun() {
39    metrics::counter!("gemini_genai_rs_jitter_underruns_total").increment(1);
40}
41
42/// Record a tool call execution.
43#[cfg(feature = "metrics")]
44pub fn record_tool_call(function_name: &str, duration_ms: f64) {
45    metrics::counter!("gemini_genai_rs_tool_calls_total", "function" => function_name.to_string())
46        .increment(1);
47    metrics::histogram!("gemini_genai_rs_tool_call_duration_ms", "function" => function_name.to_string())
48        .record(duration_ms);
49}
50
51/// Record a VAD event.
52#[cfg(feature = "metrics")]
53pub fn record_vad_event(event: &str) {
54    metrics::counter!("gemini_genai_rs_vad_events_total", "event" => event.to_string())
55        .increment(1);
56}
57
58/// Record a reconnection attempt.
59#[cfg(feature = "metrics")]
60pub fn record_reconnection() {
61    metrics::counter!("gemini_genai_rs_reconnections_total").increment(1);
62}
63
64/// Record WebSocket bytes sent.
65#[cfg(feature = "metrics")]
66pub fn record_ws_bytes_sent(bytes: u64) {
67    metrics::counter!("gemini_genai_rs_ws_bytes_sent_total").increment(bytes);
68}
69
70/// Record WebSocket bytes received.
71#[cfg(feature = "metrics")]
72pub fn record_ws_bytes_received(bytes: u64) {
73    metrics::counter!("gemini_genai_rs_ws_bytes_received_total").increment(bytes);
74}
75
76/// Record an HTTP REST API request.
77#[cfg(feature = "metrics")]
78pub fn record_http_request(method: &str, status: u16, duration_ms: f64) {
79    metrics::counter!(
80        "gemini_genai_rs_http_requests_total",
81        "method" => method.to_string(),
82        "status" => status.to_string()
83    )
84    .increment(1);
85    metrics::histogram!(
86        "gemini_genai_rs_http_request_duration_ms",
87        "method" => method.to_string()
88    )
89    .record(duration_ms);
90}
91
92// No-op stubs when metrics feature is disabled.
93
94/// Record a new session connection (no-op without `metrics` feature).
95#[cfg(not(feature = "metrics"))]
96pub fn record_session_connected() {}
97/// Record a session disconnection (no-op without `metrics` feature).
98#[cfg(not(feature = "metrics"))]
99pub fn record_session_disconnected() {}
100/// Record audio send latency (no-op without `metrics` feature).
101#[cfg(not(feature = "metrics"))]
102pub fn record_audio_latency(_: f64) {}
103/// Record time from end-of-speech to first model response (no-op without `metrics` feature).
104#[cfg(not(feature = "metrics"))]
105pub fn record_response_latency(_: f64) {}
106/// Record current jitter buffer depth (no-op without `metrics` feature).
107#[cfg(not(feature = "metrics"))]
108pub fn record_jitter_depth(_: f64) {}
109/// Record a jitter buffer underrun (no-op without `metrics` feature).
110#[cfg(not(feature = "metrics"))]
111pub fn record_jitter_underrun() {}
112/// Record a tool call execution (no-op without `metrics` feature).
113#[cfg(not(feature = "metrics"))]
114pub fn record_tool_call(_: &str, _: f64) {}
115/// Record a VAD event (no-op without `metrics` feature).
116#[cfg(not(feature = "metrics"))]
117pub fn record_vad_event(_: &str) {}
118/// Record a reconnection attempt (no-op without `metrics` feature).
119#[cfg(not(feature = "metrics"))]
120pub fn record_reconnection() {}
121/// Record WebSocket bytes sent (no-op without `metrics` feature).
122#[cfg(not(feature = "metrics"))]
123pub fn record_ws_bytes_sent(_: u64) {}
124/// Record WebSocket bytes received (no-op without `metrics` feature).
125#[cfg(not(feature = "metrics"))]
126pub fn record_ws_bytes_received(_: u64) {}
127/// Record an HTTP REST API request (no-op without `metrics` feature).
128#[cfg(not(feature = "metrics"))]
129pub fn record_http_request(_: &str, _: u16, _: f64) {}
130
131#[cfg(test)]
132mod tests {
133    use super::*;
134
135    #[test]
136    fn noop_metric_functions_compile() {
137        // All metric functions should compile and not panic as no-ops.
138        record_session_connected();
139        record_session_disconnected();
140        record_audio_latency(15.0);
141        record_response_latency(200.0);
142        record_jitter_depth(30.0);
143        record_jitter_underrun();
144        record_tool_call("get_weather", 50.0);
145        record_vad_event("speech_start");
146        record_reconnection();
147        record_ws_bytes_sent(1024);
148        record_ws_bytes_received(2048);
149        record_http_request("GET", 200, 42.5);
150    }
151}