use crate::metrics::MetricsCollector;
use crate::types::BackendId;
pub trait MetricsRecorder {
fn record_command(&self, backend_id: BackendId);
fn user_command(&self, username: Option<&str>);
fn stateful_session_started(&self);
fn stateful_session_ended(&self);
fn user_bytes_sent(&self, username: Option<&str>, bytes: u64);
fn user_bytes_received(&self, username: Option<&str>, bytes: u64);
fn record_client_to_backend_bytes_for(&self, backend_id: BackendId, bytes: u64);
fn record_backend_to_client_bytes_for(&self, backend_id: BackendId, bytes: u64);
fn user_connection_closed(&self, username: Option<&str>);
}
impl MetricsRecorder for Option<MetricsCollector> {
#[inline]
fn record_command(&self, backend_id: BackendId) {
if let Some(m) = self {
m.record_command(backend_id);
}
}
#[inline]
fn user_command(&self, username: Option<&str>) {
if let Some(m) = self {
m.user_command(username);
}
}
#[inline]
fn stateful_session_started(&self) {
if let Some(m) = self {
m.stateful_session_started();
}
}
#[inline]
fn stateful_session_ended(&self) {
if let Some(m) = self {
m.stateful_session_ended();
}
}
#[inline]
fn user_bytes_sent(&self, username: Option<&str>, bytes: u64) {
if let Some(m) = self {
m.user_bytes_sent(username, bytes);
}
}
#[inline]
fn user_bytes_received(&self, username: Option<&str>, bytes: u64) {
if let Some(m) = self {
m.user_bytes_received(username, bytes);
}
}
#[inline]
fn record_client_to_backend_bytes_for(&self, backend_id: BackendId, bytes: u64) {
if let Some(m) = self {
m.record_client_to_backend_bytes_for(backend_id, bytes);
}
}
#[inline]
fn record_backend_to_client_bytes_for(&self, backend_id: BackendId, bytes: u64) {
if let Some(m) = self {
m.record_backend_to_client_bytes_for(backend_id, bytes);
}
}
#[inline]
fn user_connection_closed(&self, username: Option<&str>) {
if let Some(m) = self {
m.user_connection_closed(username);
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_metrics_recorder_with_none() {
let metrics: Option<MetricsCollector> = None;
metrics.record_command(BackendId::from_index(0));
metrics.user_command(Some("testuser"));
metrics.stateful_session_started();
metrics.stateful_session_ended();
metrics.user_bytes_sent(Some("testuser"), 1024);
metrics.user_bytes_received(Some("testuser"), 2048);
metrics.record_client_to_backend_bytes_for(BackendId::from_index(0), 512);
metrics.record_backend_to_client_bytes_for(BackendId::from_index(0), 1024);
metrics.user_connection_closed(Some("testuser"));
}
#[test]
fn test_metrics_recorder_with_collector() {
let collector = MetricsCollector::new(1);
let metrics: Option<MetricsCollector> = Some(collector.clone());
metrics.record_command(BackendId::from_index(0));
metrics.user_command(Some("testuser"));
metrics.user_bytes_sent(Some("testuser"), 1024);
metrics.user_bytes_received(Some("testuser"), 2048);
let snapshot = collector.snapshot(None);
assert_eq!(snapshot.backend_stats[0].total_commands.get(), 1);
let user_stats = snapshot
.user_stats
.iter()
.find(|s| s.username == "testuser");
assert!(user_stats.is_some());
let stats = user_stats.unwrap();
assert_eq!(stats.total_commands.get(), 1);
assert_eq!(stats.bytes_sent.as_u64(), 1024);
assert_eq!(stats.bytes_received.as_u64(), 2048);
}
}