Skip to main content

rustcdc/core/
observability.rs

1//! Metrics and tracing abstractions used by the runtime.
2
3use crate::core::{Error, Operation};
4
5/// Abstract metrics collector for runtime and source instrumentation.
6pub trait MetricsCollector: Send + Sync {
7    /// Record the observed latency for a processed event.
8    fn record_event_processed(&self, op: Operation, latency_ms: u64);
9    /// Record checkpoint commit throughput and latency.
10    fn record_checkpoint_committed(&self, event_count: u64, latency_ms: u64);
11    /// Record replication lag in milliseconds and events.
12    fn record_replication_lag_ms(&self, lag_ms: u64, lag_events: u64);
13    /// Record a typed error with an execution context label.
14    fn record_error(&self, error: &Error, context: &str);
15}
16
17/// Abstract event tracer for lifecycle hooks and barrier transitions.
18pub trait EventTracer: Send + Sync {
19    /// Trace the start of processing for a logical event.
20    fn trace_event_start(&self, event_id: &str);
21    /// Trace the end of processing for a logical event.
22    fn trace_event_end(&self, event_id: &str, status: &str);
23    /// Trace the current state of the checkpoint barrier.
24    fn trace_checkpoint_barrier(&self, state: &str);
25}
26
27/// No-op metrics collector used by default in tests and skeleton deployments.
28#[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/// No-op tracer used by default in tests and skeleton deployments.
39#[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}