rustcdc/core/
observability.rs1use crate::core::{Error, Operation};
4
5pub trait MetricsCollector: Send + Sync {
7 fn record_event_processed(&self, op: Operation, latency_ms: u64);
9 fn record_checkpoint_committed(&self, event_count: u64, latency_ms: u64);
11 fn record_replication_lag_ms(&self, lag_ms: u64, lag_events: u64);
13 fn record_error(&self, error: &Error, context: &str);
15}
16
17pub trait EventTracer: Send + Sync {
19 fn trace_event_start(&self, event_id: &str);
21 fn trace_event_end(&self, event_id: &str, status: &str);
23 fn trace_checkpoint_barrier(&self, state: &str);
25}
26
27#[derive(Debug, Default)]
29pub struct NoOpMetricsCollector;
30
31impl MetricsCollector for NoOpMetricsCollector {
32 fn record_event_processed(&self, _op: Operation, _latency_ms: u64) {}
33 fn record_checkpoint_committed(&self, _event_count: u64, _latency_ms: u64) {}
34 fn record_replication_lag_ms(&self, _lag_ms: u64, _lag_events: u64) {}
35 fn record_error(&self, _error: &Error, _context: &str) {}
36}
37
38#[derive(Debug, Default)]
40pub struct NoOpEventTracer;
41
42impl EventTracer for NoOpEventTracer {
43 fn trace_event_start(&self, _event_id: &str) {}
44 fn trace_event_end(&self, _event_id: &str, _status: &str) {}
45 fn trace_checkpoint_barrier(&self, _state: &str) {}
46}
47
48#[cfg(test)]
49mod tests {
50 use super::{EventTracer, MetricsCollector, NoOpEventTracer, NoOpMetricsCollector};
51 use crate::core::{Error, Operation};
52
53 #[test]
54 fn noop_collectors_are_infallible() {
55 let metrics = NoOpMetricsCollector;
56 metrics.record_event_processed(Operation::Insert, 1);
57 metrics.record_checkpoint_committed(10, 5);
58 metrics.record_replication_lag_ms(42, 7);
59 metrics.record_error(&Error::ConfigError("bad".into()), "test");
60
61 let tracer = NoOpEventTracer;
62 tracer.trace_event_start("e1");
63 tracer.trace_event_end("e1", "ok");
64 tracer.trace_checkpoint_barrier("open");
65 }
66}