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 tokens a Live session used, by direction (`prompt` or
77/// `response`) and modality (`TEXT`, `AUDIO`, `IMAGE`, `VIDEO`).
78#[cfg(feature = "metrics")]
79pub fn record_tokens(direction: &'static str, modality: &str, tokens: u64) {
80    metrics::counter!(
81        "gemini_genai_rs_tokens_total",
82        "direction" => direction,
83        "modality" => modality.to_string()
84    )
85    .increment(tokens);
86}
87
88/// Record an HTTP REST API request.
89#[cfg(feature = "metrics")]
90pub fn record_http_request(method: &str, status: u16, duration_ms: f64) {
91    metrics::counter!(
92        "gemini_genai_rs_http_requests_total",
93        "method" => method.to_string(),
94        "status" => status.to_string()
95    )
96    .increment(1);
97    metrics::histogram!(
98        "gemini_genai_rs_http_request_duration_ms",
99        "method" => method.to_string()
100    )
101    .record(duration_ms);
102}
103
104// No-op stubs when metrics feature is disabled.
105
106/// Record a new session connection (no-op without `metrics` feature).
107#[cfg(not(feature = "metrics"))]
108pub fn record_session_connected() {}
109/// Record a session disconnection (no-op without `metrics` feature).
110#[cfg(not(feature = "metrics"))]
111pub fn record_session_disconnected() {}
112/// Record audio send latency (no-op without `metrics` feature).
113#[cfg(not(feature = "metrics"))]
114pub fn record_audio_latency(_: f64) {}
115/// Record time from end-of-speech to first model response (no-op without `metrics` feature).
116#[cfg(not(feature = "metrics"))]
117pub fn record_response_latency(_: f64) {}
118/// Record current jitter buffer depth (no-op without `metrics` feature).
119#[cfg(not(feature = "metrics"))]
120pub fn record_jitter_depth(_: f64) {}
121/// Record a jitter buffer underrun (no-op without `metrics` feature).
122#[cfg(not(feature = "metrics"))]
123pub fn record_jitter_underrun() {}
124/// Record a tool call execution (no-op without `metrics` feature).
125#[cfg(not(feature = "metrics"))]
126pub fn record_tool_call(_: &str, _: f64) {}
127/// Record a VAD event (no-op without `metrics` feature).
128#[cfg(not(feature = "metrics"))]
129pub fn record_vad_event(_: &str) {}
130/// Record a reconnection attempt (no-op without `metrics` feature).
131#[cfg(not(feature = "metrics"))]
132pub fn record_reconnection() {}
133/// Record WebSocket bytes sent (no-op without `metrics` feature).
134#[cfg(not(feature = "metrics"))]
135pub fn record_ws_bytes_sent(_: u64) {}
136/// Record WebSocket bytes received (no-op without `metrics` feature).
137#[cfg(not(feature = "metrics"))]
138pub fn record_ws_bytes_received(_: u64) {}
139/// Record Live session tokens by direction and modality (no-op without `metrics` feature).
140#[cfg(not(feature = "metrics"))]
141pub fn record_tokens(_: &'static str, _: &str, _: u64) {}
142/// Record an HTTP REST API request (no-op without `metrics` feature).
143#[cfg(not(feature = "metrics"))]
144pub fn record_http_request(_: &str, _: u16, _: f64) {}
145
146#[cfg(test)]
147mod tests {
148    use super::*;
149
150    #[test]
151    fn noop_metric_functions_compile() {
152        // All metric functions should compile and not panic as no-ops.
153        record_session_connected();
154        record_session_disconnected();
155        record_audio_latency(15.0);
156        record_response_latency(200.0);
157        record_jitter_depth(30.0);
158        record_jitter_underrun();
159        record_tool_call("get_weather", 50.0);
160        record_vad_event("speech_start");
161        record_reconnection();
162        record_ws_bytes_sent(1024);
163        record_ws_bytes_received(2048);
164        record_http_request("GET", 200, 42.5);
165    }
166}