use std::{borrow::Cow, fmt::Debug};
use mixtrics::metrics::{BoxedCounter, BoxedGauge, BoxedHistogram, BoxedRegistry, Buckets};
#[expect(missing_docs)]
pub struct Metrics {
pub memory_insert: BoxedCounter,
pub memory_replace: BoxedCounter,
pub memory_hit: BoxedCounter,
pub memory_miss: BoxedCounter,
pub memory_remove: BoxedCounter,
pub memory_evict: BoxedCounter,
pub memory_reinsert: BoxedCounter,
pub memory_release: BoxedCounter,
pub memory_queue: BoxedCounter,
pub memory_fetch: BoxedCounter,
pub memory_usage: BoxedGauge,
pub memory_entries: BoxedGauge,
pub storage_enqueue: BoxedCounter,
pub storage_hit: BoxedCounter,
pub storage_miss: BoxedCounter,
pub storage_throttled: BoxedCounter,
pub storage_delete: BoxedCounter,
pub storage_error: BoxedCounter,
pub storage_enqueue_duration: BoxedHistogram,
pub storage_hit_duration: BoxedHistogram,
pub storage_miss_duration: BoxedHistogram,
pub storage_throttled_duration: BoxedHistogram,
pub storage_delete_duration: BoxedHistogram,
pub storage_queue_rotate: BoxedCounter,
pub storage_queue_rotate_duration: BoxedHistogram,
pub storage_queue_buffer_overflow: BoxedCounter,
pub storage_queue_channel_overflow: BoxedCounter,
pub storage_disk_write: BoxedCounter,
pub storage_disk_read: BoxedCounter,
pub storage_disk_flush: BoxedCounter,
pub storage_disk_write_bytes: BoxedCounter,
pub storage_disk_read_bytes: BoxedCounter,
pub storage_disk_write_duration: BoxedHistogram,
pub storage_disk_read_duration: BoxedHistogram,
pub storage_disk_flush_duration: BoxedHistogram,
pub storage_block_engine_block_clean: BoxedGauge,
pub storage_block_engine_block_writing: BoxedGauge,
pub storage_block_engine_block_evictable: BoxedGauge,
pub storage_block_engine_block_reclaiming: BoxedGauge,
pub storage_block_engine_block_size_bytes: BoxedGauge,
pub storage_entry_serialize_duration: BoxedHistogram,
pub storage_entry_deserialize_duration: BoxedHistogram,
pub storage_block_engine_indexer_conflict: BoxedCounter,
pub storage_block_engine_enqueue_skip: BoxedCounter,
pub storage_block_engine_buffer_efficiency: BoxedHistogram,
pub storage_block_engine_recover_duration: BoxedHistogram,
pub hybrid_insert: BoxedCounter,
pub hybrid_hit: BoxedCounter,
pub hybrid_miss: BoxedCounter,
pub hybrid_throttled: BoxedCounter,
pub hybrid_remove: BoxedCounter,
pub hybrid_error: BoxedCounter,
pub hybrid_insert_duration: BoxedHistogram,
pub hybrid_hit_duration: BoxedHistogram,
pub hybrid_miss_duration: BoxedHistogram,
pub hybrid_throttled_duration: BoxedHistogram,
pub hybrid_remove_duration: BoxedHistogram,
pub hybrid_error_duration: BoxedHistogram,
}
impl Debug for Metrics {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Metrics").finish()
}
}
impl Metrics {
pub fn new(name: impl Into<Cow<'static, str>>, registry: &BoxedRegistry) -> Self {
let name = name.into();
let foyer_memory_op_total = registry.register_counter_vec(
"foyer_memory_op_total".into(),
"foyer in-memory cache operations".into(),
&["name", "op"],
);
let foyer_memory_usage = registry.register_gauge_vec(
"foyer_memory_usage".into(),
"foyer in-memory cache usage".into(),
&["name"],
);
let foyer_memory_entries = registry.register_gauge_vec(
"foyer_memory_entries".into(),
"foyer in-memory cache entries".into(),
&["name"],
);
let memory_insert = foyer_memory_op_total.counter(&[name.clone(), "insert".into()]);
let memory_replace = foyer_memory_op_total.counter(&[name.clone(), "replace".into()]);
let memory_hit = foyer_memory_op_total.counter(&[name.clone(), "hit".into()]);
let memory_miss = foyer_memory_op_total.counter(&[name.clone(), "miss".into()]);
let memory_remove = foyer_memory_op_total.counter(&[name.clone(), "remove".into()]);
let memory_evict = foyer_memory_op_total.counter(&[name.clone(), "evict".into()]);
let memory_reinsert = foyer_memory_op_total.counter(&[name.clone(), "reinsert".into()]);
let memory_release = foyer_memory_op_total.counter(&[name.clone(), "release".into()]);
let memory_queue = foyer_memory_op_total.counter(&[name.clone(), "queue".into()]);
let memory_fetch = foyer_memory_op_total.counter(&[name.clone(), "fetch".into()]);
let memory_usage = foyer_memory_usage.gauge(std::slice::from_ref(&name));
let memory_entries = foyer_memory_entries.gauge(std::slice::from_ref(&name));
let foyer_storage_op_total = registry.register_counter_vec(
"foyer_storage_op_total".into(),
"foyer disk cache operations".into(),
&["name", "op"],
);
let foyer_storage_op_duration = registry.register_histogram_vec_with_buckets(
"foyer_storage_op_duration".into(),
"foyer disk cache op durations".into(),
&["name", "op"],
Buckets::exponential(0.000_001, 2.0, 23),
);
let foyer_storage_inner_op_total = registry.register_counter_vec(
"foyer_storage_inner_op_total".into(),
"foyer disk cache inner operations".into(),
&["name", "op"],
);
let foyer_storage_inner_op_duration = registry.register_histogram_vec_with_buckets(
"foyer_storage_inner_op_duration".into(),
"foyer disk cache inner op durations".into(),
&["name", "op"],
Buckets::exponential(0.000_001, 2.0, 25),
);
let foyer_storage_disk_io_total = registry.register_counter_vec(
"foyer_storage_disk_io_total".into(),
"foyer disk cache disk operations".into(),
&["name", "op"],
);
let foyer_storage_disk_io_bytes = registry.register_counter_vec(
"foyer_storage_disk_io_bytes_total".into(),
"foyer disk cache disk io bytes".into(),
&["name", "op"],
);
let foyer_storage_disk_io_duration = registry.register_histogram_vec_with_buckets(
"foyer_storage_disk_io_duration".into(),
"foyer disk cache disk io duration".into(),
&["name", "op"],
Buckets::exponential(0.000_001, 2.0, 23),
);
let foyer_storage_block_engine_block = registry.register_gauge_vec(
"foyer_storage_block_engine_block".into(),
"foyer large object disk cache blocks".into(),
&["name", "type"],
);
let foyer_storage_block_engine_block_size_bytes = registry.register_gauge_vec(
"foyer_storage_block_engine_block_size_bytes".into(),
"foyer large object disk cache blocks sizes".into(),
&["name"],
);
let foyer_storage_entry_serde_duration = registry.register_histogram_vec_with_buckets(
"foyer_storage_entry_serde_duration".into(),
"foyer disk cache entry serde durations".into(),
&["name", "op"],
Buckets::exponential(0.000_000_01, 2.0, 23),
);
let foyer_storage_block_engine_op_total = registry.register_counter_vec(
"foyer_storage_block_engine_op_total".into(),
"foyer large object disk cache operations".into(),
&["name", "op"],
);
let foyer_storage_block_engine_buffer_efficiency = registry.register_histogram_vec_with_buckets(
"foyer_storage_block_engine_buffer_efficiency".into(),
"foyer large object disk cache buffer efficiency".into(),
&["name"],
Buckets::linear(0.1, 0.1, 10),
);
let foyer_storage_block_engine_recover_duration = registry.register_histogram_vec_with_buckets(
"foyer_storage_block_engine_recover_duration".into(),
"foyer large object disk cache recover duration".into(),
&["name"],
Buckets::exponential(0.001, 2.0, 21),
);
let storage_enqueue = foyer_storage_op_total.counter(&[name.clone(), "enqueue".into()]);
let storage_hit = foyer_storage_op_total.counter(&[name.clone(), "hit".into()]);
let storage_miss = foyer_storage_op_total.counter(&[name.clone(), "miss".into()]);
let storage_delete = foyer_storage_op_total.counter(&[name.clone(), "delete".into()]);
let storage_throttled = foyer_storage_op_total.counter(&[name.clone(), "throttled".into()]);
let storage_error = foyer_storage_op_total.counter(&[name.clone(), "error".into()]);
let storage_enqueue_duration = foyer_storage_op_duration.histogram(&[name.clone(), "enqueue".into()]);
let storage_hit_duration = foyer_storage_op_duration.histogram(&[name.clone(), "hit".into()]);
let storage_miss_duration = foyer_storage_op_duration.histogram(&[name.clone(), "miss".into()]);
let storage_throttled_duration = foyer_storage_op_duration.histogram(&[name.clone(), "throttled".into()]);
let storage_delete_duration = foyer_storage_op_duration.histogram(&[name.clone(), "delete".into()]);
let storage_queue_rotate = foyer_storage_inner_op_total.counter(&[name.clone(), "queue_rotate".into()]);
let storage_queue_buffer_overflow =
foyer_storage_inner_op_total.counter(&[name.clone(), "buffer_overflow".into()]);
let storage_queue_channel_overflow =
foyer_storage_inner_op_total.counter(&[name.clone(), "channel_overflow".into()]);
let storage_queue_rotate_duration =
foyer_storage_inner_op_duration.histogram(&[name.clone(), "queue_rotate".into()]);
let storage_disk_write = foyer_storage_disk_io_total.counter(&[name.clone(), "write".into()]);
let storage_disk_read = foyer_storage_disk_io_total.counter(&[name.clone(), "read".into()]);
let storage_disk_flush = foyer_storage_disk_io_total.counter(&[name.clone(), "flush".into()]);
let storage_disk_write_bytes = foyer_storage_disk_io_bytes.counter(&[name.clone(), "write".into()]);
let storage_disk_read_bytes = foyer_storage_disk_io_bytes.counter(&[name.clone(), "read".into()]);
let storage_disk_write_duration = foyer_storage_disk_io_duration.histogram(&[name.clone(), "write".into()]);
let storage_disk_read_duration = foyer_storage_disk_io_duration.histogram(&[name.clone(), "read".into()]);
let storage_disk_flush_duration = foyer_storage_disk_io_duration.histogram(&[name.clone(), "flush".into()]);
let storage_block_engine_block_clean = foyer_storage_block_engine_block.gauge(&[name.clone(), "clean".into()]);
let storage_block_engine_block_writing =
foyer_storage_block_engine_block.gauge(&[name.clone(), "writing".into()]);
let storage_block_engine_block_evictable =
foyer_storage_block_engine_block.gauge(&[name.clone(), "evictable".into()]);
let storage_block_engine_block_reclaiming =
foyer_storage_block_engine_block.gauge(&[name.clone(), "reclaiming".into()]);
let storage_block_engine_block_size_bytes =
foyer_storage_block_engine_block_size_bytes.gauge(std::slice::from_ref(&name));
let storage_entry_serialize_duration =
foyer_storage_entry_serde_duration.histogram(&[name.clone(), "serialize".into()]);
let storage_entry_deserialize_duration =
foyer_storage_entry_serde_duration.histogram(&[name.clone(), "deserialize".into()]);
let storage_block_engine_indexer_conflict =
foyer_storage_block_engine_op_total.counter(&[name.clone(), "indexer_conflict".into()]);
let storage_block_engine_enqueue_skip =
foyer_storage_block_engine_op_total.counter(&[name.clone(), "enqueue_skip".into()]);
let storage_block_engine_buffer_efficiency =
foyer_storage_block_engine_buffer_efficiency.histogram(std::slice::from_ref(&name));
let storage_block_engine_recover_duration =
foyer_storage_block_engine_recover_duration.histogram(std::slice::from_ref(&name));
let foyer_hybrid_op_total = registry.register_counter_vec(
"foyer_hybrid_op_total".into(),
"foyer hybrid cache operations".into(),
&["name", "op"],
);
let foyer_hybrid_op_duration = registry.register_histogram_vec(
"foyer_hybrid_op_duration".into(),
"foyer hybrid cache operation durations".into(),
&["name", "op"],
);
let hybrid_insert = foyer_hybrid_op_total.counter(&[name.clone(), "insert".into()]);
let hybrid_hit = foyer_hybrid_op_total.counter(&[name.clone(), "hit".into()]);
let hybrid_miss = foyer_hybrid_op_total.counter(&[name.clone(), "miss".into()]);
let hybrid_throttled = foyer_hybrid_op_total.counter(&[name.clone(), "throttled".into()]);
let hybrid_remove = foyer_hybrid_op_total.counter(&[name.clone(), "remove".into()]);
let hybrid_error = foyer_hybrid_op_total.counter(&[name.clone(), "error".into()]);
let hybrid_insert_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "insert".into()]);
let hybrid_hit_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "hit".into()]);
let hybrid_miss_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "miss".into()]);
let hybrid_throttled_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "throttled".into()]);
let hybrid_remove_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "remove".into()]);
let hybrid_error_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "error".into()]);
Self {
memory_insert,
memory_replace,
memory_hit,
memory_miss,
memory_remove,
memory_evict,
memory_reinsert,
memory_release,
memory_queue,
memory_fetch,
memory_usage,
memory_entries,
storage_enqueue,
storage_hit,
storage_miss,
storage_throttled,
storage_delete,
storage_error,
storage_enqueue_duration,
storage_hit_duration,
storage_miss_duration,
storage_throttled_duration,
storage_delete_duration,
storage_queue_rotate,
storage_queue_rotate_duration,
storage_queue_buffer_overflow,
storage_queue_channel_overflow,
storage_disk_write,
storage_disk_read,
storage_disk_flush,
storage_disk_write_bytes,
storage_disk_read_bytes,
storage_disk_write_duration,
storage_disk_read_duration,
storage_disk_flush_duration,
storage_block_engine_block_clean,
storage_block_engine_block_writing,
storage_block_engine_block_evictable,
storage_block_engine_block_reclaiming,
storage_block_engine_block_size_bytes,
storage_entry_serialize_duration,
storage_entry_deserialize_duration,
storage_block_engine_indexer_conflict,
storage_block_engine_enqueue_skip,
storage_block_engine_buffer_efficiency,
storage_block_engine_recover_duration,
hybrid_insert,
hybrid_hit,
hybrid_miss,
hybrid_throttled,
hybrid_throttled_duration,
hybrid_remove,
hybrid_error,
hybrid_insert_duration,
hybrid_hit_duration,
hybrid_miss_duration,
hybrid_remove_duration,
hybrid_error_duration,
}
}
#[doc(hidden)]
pub fn noop() -> Self {
let registry: BoxedRegistry = Box::new(mixtrics::registry::noop::NoopMetricsRegistry);
Self::new("test", ®istry)
}
}
#[cfg(test)]
mod tests {
use mixtrics::metrics::BoxedRegistry;
use super::Metrics;
fn test_fn(registry: &BoxedRegistry) {
Metrics::new("test", registry);
}
mixtrics::test! { test_fn }
}