use crate::core::{Error, Operation};
pub trait MetricsCollector: Send + Sync {
fn record_event_processed(&self, op: Operation, latency_ms: u64);
fn record_checkpoint_committed(&self, event_count: u64, latency_ms: u64);
fn record_replication_lag_ms(&self, lag_ms: u64, lag_events: u64);
fn record_error(&self, error: &Error, context: &str);
}
pub trait EventTracer: Send + Sync {
fn trace_event_start(&self, event_id: &str);
fn trace_event_end(&self, event_id: &str, status: &str);
fn trace_checkpoint_barrier(&self, state: &str);
}
#[derive(Debug, Default)]
pub struct NoOpMetricsCollector;
impl MetricsCollector for NoOpMetricsCollector {
fn record_event_processed(&self, _op: Operation, _latency_ms: u64) {}
fn record_checkpoint_committed(&self, _event_count: u64, _latency_ms: u64) {}
fn record_replication_lag_ms(&self, _lag_ms: u64, _lag_events: u64) {}
fn record_error(&self, _error: &Error, _context: &str) {}
}
#[derive(Debug, Default)]
pub struct NoOpEventTracer;
impl EventTracer for NoOpEventTracer {
fn trace_event_start(&self, _event_id: &str) {}
fn trace_event_end(&self, _event_id: &str, _status: &str) {}
fn trace_checkpoint_barrier(&self, _state: &str) {}
}
#[cfg(test)]
mod tests {
use super::{EventTracer, MetricsCollector, NoOpEventTracer, NoOpMetricsCollector};
use crate::core::{Error, Operation};
#[test]
fn noop_collectors_are_infallible() {
let metrics = NoOpMetricsCollector;
metrics.record_event_processed(Operation::Insert, 1);
metrics.record_checkpoint_committed(10, 5);
metrics.record_replication_lag_ms(42, 7);
metrics.record_error(&Error::ConfigError("bad".into()), "test");
let tracer = NoOpEventTracer;
tracer.trace_event_start("e1");
tracer.trace_event_end("e1", "ok");
tracer.trace_checkpoint_barrier("open");
}
}