1use std::{borrow::Cow, fmt::Debug};
16
17use mixtrics::metrics::{BoxedCounter, BoxedGauge, BoxedHistogram, BoxedRegistry, Buckets};
18
19#[expect(missing_docs)]
20pub struct Metrics {
21 pub memory_insert: BoxedCounter,
23 pub memory_replace: BoxedCounter,
24 pub memory_hit: BoxedCounter,
25 pub memory_miss: BoxedCounter,
26 pub memory_remove: BoxedCounter,
27 pub memory_evict: BoxedCounter,
28 pub memory_reinsert: BoxedCounter,
29 pub memory_release: BoxedCounter,
30 pub memory_queue: BoxedCounter,
31 pub memory_fetch: BoxedCounter,
32
33 pub memory_usage: BoxedGauge,
34 pub memory_entries: BoxedGauge,
35
36 pub storage_enqueue: BoxedCounter,
38 pub storage_hit: BoxedCounter,
39 pub storage_miss: BoxedCounter,
40 pub storage_throttled: BoxedCounter,
41 pub storage_delete: BoxedCounter,
42 pub storage_error: BoxedCounter,
43
44 pub storage_enqueue_duration: BoxedHistogram,
45 pub storage_hit_duration: BoxedHistogram,
46 pub storage_miss_duration: BoxedHistogram,
47 pub storage_throttled_duration: BoxedHistogram,
48 pub storage_delete_duration: BoxedHistogram,
49
50 pub storage_queue_rotate: BoxedCounter,
51 pub storage_queue_rotate_duration: BoxedHistogram,
52 pub storage_queue_buffer_overflow: BoxedCounter,
53 pub storage_queue_channel_overflow: BoxedCounter,
54
55 pub storage_disk_write: BoxedCounter,
56 pub storage_disk_read: BoxedCounter,
57 pub storage_disk_flush: BoxedCounter,
58
59 pub storage_disk_write_bytes: BoxedCounter,
60 pub storage_disk_read_bytes: BoxedCounter,
61
62 pub storage_disk_write_duration: BoxedHistogram,
63 pub storage_disk_read_duration: BoxedHistogram,
64 pub storage_disk_flush_duration: BoxedHistogram,
65
66 pub storage_block_engine_block_clean: BoxedGauge,
67 pub storage_block_engine_block_writing: BoxedGauge,
68 pub storage_block_engine_block_evictable: BoxedGauge,
69 pub storage_block_engine_block_reclaiming: BoxedGauge,
70
71 pub storage_block_engine_block_size_bytes: BoxedGauge,
72
73 pub storage_entry_serialize_duration: BoxedHistogram,
74 pub storage_entry_deserialize_duration: BoxedHistogram,
75
76 pub storage_block_engine_indexer_conflict: BoxedCounter,
77 pub storage_block_engine_enqueue_skip: BoxedCounter,
78 pub storage_block_engine_buffer_efficiency: BoxedHistogram,
79 pub storage_block_engine_recover_duration: BoxedHistogram,
80
81 pub hybrid_insert: BoxedCounter,
83 pub hybrid_hit: BoxedCounter,
84 pub hybrid_miss: BoxedCounter,
85 pub hybrid_throttled: BoxedCounter,
86 pub hybrid_remove: BoxedCounter,
87 pub hybrid_error: BoxedCounter,
88
89 pub hybrid_insert_duration: BoxedHistogram,
90 pub hybrid_hit_duration: BoxedHistogram,
91 pub hybrid_miss_duration: BoxedHistogram,
92 pub hybrid_throttled_duration: BoxedHistogram,
93 pub hybrid_remove_duration: BoxedHistogram,
94 pub hybrid_error_duration: BoxedHistogram,
95}
96
97impl Debug for Metrics {
98 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
99 f.debug_struct("Metrics").finish()
100 }
101}
102
103impl Metrics {
104 pub fn new(name: impl Into<Cow<'static, str>>, registry: &BoxedRegistry) -> Self {
106 let name = name.into();
107
108 let foyer_memory_op_total = registry.register_counter_vec(
111 "foyer_memory_op_total".into(),
112 "foyer in-memory cache operations".into(),
113 &["name", "op"],
114 );
115 let foyer_memory_usage = registry.register_gauge_vec(
116 "foyer_memory_usage".into(),
117 "foyer in-memory cache usage".into(),
118 &["name"],
119 );
120 let foyer_memory_entries = registry.register_gauge_vec(
121 "foyer_memory_entries".into(),
122 "foyer in-memory cache entries".into(),
123 &["name"],
124 );
125
126 let memory_insert = foyer_memory_op_total.counter(&[name.clone(), "insert".into()]);
127 let memory_replace = foyer_memory_op_total.counter(&[name.clone(), "replace".into()]);
128 let memory_hit = foyer_memory_op_total.counter(&[name.clone(), "hit".into()]);
129 let memory_miss = foyer_memory_op_total.counter(&[name.clone(), "miss".into()]);
130 let memory_remove = foyer_memory_op_total.counter(&[name.clone(), "remove".into()]);
131 let memory_evict = foyer_memory_op_total.counter(&[name.clone(), "evict".into()]);
132 let memory_reinsert = foyer_memory_op_total.counter(&[name.clone(), "reinsert".into()]);
133 let memory_release = foyer_memory_op_total.counter(&[name.clone(), "release".into()]);
134 let memory_queue = foyer_memory_op_total.counter(&[name.clone(), "queue".into()]);
135 let memory_fetch = foyer_memory_op_total.counter(&[name.clone(), "fetch".into()]);
136
137 let memory_usage = foyer_memory_usage.gauge(std::slice::from_ref(&name));
138 let memory_entries = foyer_memory_entries.gauge(std::slice::from_ref(&name));
139
140 let foyer_storage_op_total = registry.register_counter_vec(
143 "foyer_storage_op_total".into(),
144 "foyer disk cache operations".into(),
145 &["name", "op"],
146 );
147 let foyer_storage_op_duration = registry.register_histogram_vec_with_buckets(
148 "foyer_storage_op_duration".into(),
149 "foyer disk cache op durations".into(),
150 &["name", "op"],
151 Buckets::exponential(0.000_001, 2.0, 23),
153 );
154
155 let foyer_storage_inner_op_total = registry.register_counter_vec(
156 "foyer_storage_inner_op_total".into(),
157 "foyer disk cache inner operations".into(),
158 &["name", "op"],
159 );
160 let foyer_storage_inner_op_duration = registry.register_histogram_vec_with_buckets(
161 "foyer_storage_inner_op_duration".into(),
162 "foyer disk cache inner op durations".into(),
163 &["name", "op"],
164 Buckets::exponential(0.000_001, 2.0, 25),
166 );
167
168 let foyer_storage_disk_io_total = registry.register_counter_vec(
169 "foyer_storage_disk_io_total".into(),
170 "foyer disk cache disk operations".into(),
171 &["name", "op"],
172 );
173 let foyer_storage_disk_io_bytes = registry.register_counter_vec(
174 "foyer_storage_disk_io_bytes_total".into(),
175 "foyer disk cache disk io bytes".into(),
176 &["name", "op"],
177 );
178 let foyer_storage_disk_io_duration = registry.register_histogram_vec_with_buckets(
179 "foyer_storage_disk_io_duration".into(),
180 "foyer disk cache disk io duration".into(),
181 &["name", "op"],
182 Buckets::exponential(0.000_001, 2.0, 23),
184 );
185
186 let foyer_storage_block_engine_block = registry.register_gauge_vec(
187 "foyer_storage_block_engine_block".into(),
188 "foyer large object disk cache blocks".into(),
189 &["name", "type"],
190 );
191 let foyer_storage_block_engine_block_size_bytes = registry.register_gauge_vec(
192 "foyer_storage_block_engine_block_size_bytes".into(),
193 "foyer large object disk cache blocks sizes".into(),
194 &["name"],
195 );
196
197 let foyer_storage_entry_serde_duration = registry.register_histogram_vec_with_buckets(
198 "foyer_storage_entry_serde_duration".into(),
199 "foyer disk cache entry serde durations".into(),
200 &["name", "op"],
201 Buckets::exponential(0.000_000_01, 2.0, 23),
203 );
204
205 let foyer_storage_block_engine_op_total = registry.register_counter_vec(
206 "foyer_storage_block_engine_op_total".into(),
207 "foyer large object disk cache operations".into(),
208 &["name", "op"],
209 );
210
211 let foyer_storage_block_engine_buffer_efficiency = registry.register_histogram_vec_with_buckets(
212 "foyer_storage_block_engine_buffer_efficiency".into(),
213 "foyer large object disk cache buffer efficiency".into(),
214 &["name"],
215 Buckets::linear(0.1, 0.1, 10),
217 );
218
219 let foyer_storage_block_engine_recover_duration = registry.register_histogram_vec_with_buckets(
220 "foyer_storage_block_engine_recover_duration".into(),
221 "foyer large object disk cache recover duration".into(),
222 &["name"],
223 Buckets::exponential(0.001, 2.0, 21),
225 );
226
227 let storage_enqueue = foyer_storage_op_total.counter(&[name.clone(), "enqueue".into()]);
228 let storage_hit = foyer_storage_op_total.counter(&[name.clone(), "hit".into()]);
229 let storage_miss = foyer_storage_op_total.counter(&[name.clone(), "miss".into()]);
230 let storage_delete = foyer_storage_op_total.counter(&[name.clone(), "delete".into()]);
231 let storage_throttled = foyer_storage_op_total.counter(&[name.clone(), "throttled".into()]);
232 let storage_error = foyer_storage_op_total.counter(&[name.clone(), "error".into()]);
233
234 let storage_enqueue_duration = foyer_storage_op_duration.histogram(&[name.clone(), "enqueue".into()]);
235 let storage_hit_duration = foyer_storage_op_duration.histogram(&[name.clone(), "hit".into()]);
236 let storage_miss_duration = foyer_storage_op_duration.histogram(&[name.clone(), "miss".into()]);
237 let storage_throttled_duration = foyer_storage_op_duration.histogram(&[name.clone(), "throttled".into()]);
238 let storage_delete_duration = foyer_storage_op_duration.histogram(&[name.clone(), "delete".into()]);
239
240 let storage_queue_rotate = foyer_storage_inner_op_total.counter(&[name.clone(), "queue_rotate".into()]);
241 let storage_queue_buffer_overflow =
242 foyer_storage_inner_op_total.counter(&[name.clone(), "buffer_overflow".into()]);
243 let storage_queue_channel_overflow =
244 foyer_storage_inner_op_total.counter(&[name.clone(), "channel_overflow".into()]);
245
246 let storage_queue_rotate_duration =
247 foyer_storage_inner_op_duration.histogram(&[name.clone(), "queue_rotate".into()]);
248
249 let storage_disk_write = foyer_storage_disk_io_total.counter(&[name.clone(), "write".into()]);
250 let storage_disk_read = foyer_storage_disk_io_total.counter(&[name.clone(), "read".into()]);
251 let storage_disk_flush = foyer_storage_disk_io_total.counter(&[name.clone(), "flush".into()]);
252
253 let storage_disk_write_bytes = foyer_storage_disk_io_bytes.counter(&[name.clone(), "write".into()]);
254 let storage_disk_read_bytes = foyer_storage_disk_io_bytes.counter(&[name.clone(), "read".into()]);
255
256 let storage_disk_write_duration = foyer_storage_disk_io_duration.histogram(&[name.clone(), "write".into()]);
257 let storage_disk_read_duration = foyer_storage_disk_io_duration.histogram(&[name.clone(), "read".into()]);
258 let storage_disk_flush_duration = foyer_storage_disk_io_duration.histogram(&[name.clone(), "flush".into()]);
259
260 let storage_block_engine_block_clean = foyer_storage_block_engine_block.gauge(&[name.clone(), "clean".into()]);
261 let storage_block_engine_block_writing =
262 foyer_storage_block_engine_block.gauge(&[name.clone(), "writing".into()]);
263 let storage_block_engine_block_evictable =
264 foyer_storage_block_engine_block.gauge(&[name.clone(), "evictable".into()]);
265 let storage_block_engine_block_reclaiming =
266 foyer_storage_block_engine_block.gauge(&[name.clone(), "reclaiming".into()]);
267
268 let storage_block_engine_block_size_bytes =
269 foyer_storage_block_engine_block_size_bytes.gauge(std::slice::from_ref(&name));
270
271 let storage_entry_serialize_duration =
272 foyer_storage_entry_serde_duration.histogram(&[name.clone(), "serialize".into()]);
273 let storage_entry_deserialize_duration =
274 foyer_storage_entry_serde_duration.histogram(&[name.clone(), "deserialize".into()]);
275
276 let storage_block_engine_indexer_conflict =
277 foyer_storage_block_engine_op_total.counter(&[name.clone(), "indexer_conflict".into()]);
278 let storage_block_engine_enqueue_skip =
279 foyer_storage_block_engine_op_total.counter(&[name.clone(), "enqueue_skip".into()]);
280 let storage_block_engine_buffer_efficiency =
281 foyer_storage_block_engine_buffer_efficiency.histogram(std::slice::from_ref(&name));
282 let storage_block_engine_recover_duration =
283 foyer_storage_block_engine_recover_duration.histogram(std::slice::from_ref(&name));
284
285 let foyer_hybrid_op_total = registry.register_counter_vec(
288 "foyer_hybrid_op_total".into(),
289 "foyer hybrid cache operations".into(),
290 &["name", "op"],
291 );
292 let foyer_hybrid_op_duration = registry.register_histogram_vec(
293 "foyer_hybrid_op_duration".into(),
294 "foyer hybrid cache operation durations".into(),
295 &["name", "op"],
296 );
297
298 let hybrid_insert = foyer_hybrid_op_total.counter(&[name.clone(), "insert".into()]);
299 let hybrid_hit = foyer_hybrid_op_total.counter(&[name.clone(), "hit".into()]);
300 let hybrid_miss = foyer_hybrid_op_total.counter(&[name.clone(), "miss".into()]);
301 let hybrid_throttled = foyer_hybrid_op_total.counter(&[name.clone(), "throttled".into()]);
302 let hybrid_remove = foyer_hybrid_op_total.counter(&[name.clone(), "remove".into()]);
303 let hybrid_error = foyer_hybrid_op_total.counter(&[name.clone(), "error".into()]);
304
305 let hybrid_insert_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "insert".into()]);
306 let hybrid_hit_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "hit".into()]);
307 let hybrid_miss_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "miss".into()]);
308 let hybrid_throttled_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "throttled".into()]);
309 let hybrid_remove_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "remove".into()]);
310 let hybrid_error_duration = foyer_hybrid_op_duration.histogram(&[name.clone(), "error".into()]);
311
312 Self {
313 memory_insert,
314 memory_replace,
315 memory_hit,
316 memory_miss,
317 memory_remove,
318 memory_evict,
319 memory_reinsert,
320 memory_release,
321 memory_queue,
322 memory_fetch,
323 memory_usage,
324 memory_entries,
325
326 storage_enqueue,
327 storage_hit,
328 storage_miss,
329 storage_throttled,
330 storage_delete,
331 storage_error,
332 storage_enqueue_duration,
333 storage_hit_duration,
334 storage_miss_duration,
335 storage_throttled_duration,
336 storage_delete_duration,
337 storage_queue_rotate,
338 storage_queue_rotate_duration,
339 storage_queue_buffer_overflow,
340 storage_queue_channel_overflow,
341 storage_disk_write,
342 storage_disk_read,
343 storage_disk_flush,
344 storage_disk_write_bytes,
345 storage_disk_read_bytes,
346 storage_disk_write_duration,
347 storage_disk_read_duration,
348 storage_disk_flush_duration,
349 storage_block_engine_block_clean,
350 storage_block_engine_block_writing,
351 storage_block_engine_block_evictable,
352 storage_block_engine_block_reclaiming,
353 storage_block_engine_block_size_bytes,
354 storage_entry_serialize_duration,
355 storage_entry_deserialize_duration,
356 storage_block_engine_indexer_conflict,
357 storage_block_engine_enqueue_skip,
358 storage_block_engine_buffer_efficiency,
359 storage_block_engine_recover_duration,
360
361 hybrid_insert,
362 hybrid_hit,
363 hybrid_miss,
364 hybrid_throttled,
365 hybrid_throttled_duration,
366 hybrid_remove,
367 hybrid_error,
368 hybrid_insert_duration,
369 hybrid_hit_duration,
370 hybrid_miss_duration,
371 hybrid_remove_duration,
372 hybrid_error_duration,
373 }
374 }
375
376 #[doc(hidden)]
380 pub fn noop() -> Self {
381 let registry: BoxedRegistry = Box::new(mixtrics::registry::noop::NoopMetricsRegistry);
382 Self::new("test", ®istry)
383 }
384}
385
386#[cfg(test)]
387mod tests {
388 use mixtrics::metrics::BoxedRegistry;
389
390 use super::Metrics;
391
392 fn test_fn(registry: &BoxedRegistry) {
393 Metrics::new("test", registry);
394 }
395
396 mixtrics::test! { test_fn }
397}