kevy_embedded/metric.rs
1//! Optional push-style metric callback. In-process embed mode has no metrics
2//! endpoint, so persistence events (AOF replay on startup, AOF rewrite/
3//! compaction) are pushed to a caller-supplied sink — wire it to Prometheus,
4//! a log line, a counter, whatever. Wire it via [`crate::Config::with_metric_sink`].
5
6use std::sync::Arc;
7
8/// A persistence event worth observing. More variants may be added; match
9/// non-exhaustively (`_ => {}`) to stay forward-compatible.
10#[derive(Debug, Clone)]
11#[non_exhaustive]
12pub enum KevyMetric {
13 /// AOF replay finished on startup. `bytes` is the AOF size replayed.
14 Replay {
15 commands: u64,
16 bytes: u64,
17 elapsed_ms: u64,
18 },
19 /// An AOF rewrite (compaction) completed. `before_bytes - after_bytes` is
20 /// the space reclaimed.
21 Rewrite {
22 keys: u64,
23 before_bytes: u64,
24 after_bytes: u64,
25 elapsed_ms: u64,
26 },
27}
28
29/// Cloneable handle to the caller's metric callback. Cheap `Arc` clone; the
30/// callback runs synchronously on whichever thread emits the event (the reaper
31/// thread for background rewrites, the opening thread for replay), so keep it
32/// fast / non-blocking.
33#[derive(Clone)]
34pub(crate) struct MetricSink(Arc<dyn Fn(KevyMetric) + Send + Sync>);
35
36impl MetricSink {
37 pub(crate) fn new(f: impl Fn(KevyMetric) + Send + Sync + 'static) -> Self {
38 MetricSink(Arc::new(f))
39 }
40
41 pub(crate) fn emit(&self, m: KevyMetric) {
42 (self.0)(m);
43 }
44}
45
46impl std::fmt::Debug for MetricSink {
47 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
48 f.write_str("MetricSink(<fn>)")
49 }
50}