use std::{borrow::Cow, fs::File, io::Write, sync::Arc, time::Instant};
use mixtrics::{
metrics::{BoxedCounter, BoxedHistogram, BoxedRegistry},
registry::prometheus_0_14::PrometheusMetricsRegistry,
};
#[allow(dead_code)]
struct DiskMetrics {
write_ops: BoxedCounter,
write_duration: BoxedHistogram,
read_ops: BoxedCounter,
read_duration: BoxedHistogram,
sync_ops: BoxedCounter,
sync_duration: BoxedHistogram,
}
impl DiskMetrics {
fn new(app: impl Into<Cow<'static, str>>, registry: &BoxedRegistry) -> Self {
let app = app.into();
let op_total = registry.register_counter_vec("disk_op_total".into(), "disk ops".into(), &["app", "op"]);
let op_duration =
registry.register_histogram_vec("disk_op_duration".into(), "disk op duration".into(), &["app", "op"]);
let slow_op_duration = registry.register_histogram_vec_with_buckets(
"disk_slow_op_duration".into(),
"disk slow op duration".into(),
&["app", "op"],
vec![0.001, 0.025, 0.05, 0.075, 0.1, 0.25, 0.5, 0.75, 1.0],
);
let write_ops = op_total.counter(&[app.clone(), "write".into()]);
let write_duration = op_duration.histogram(&[app.clone(), "write".into()]);
let read_ops = op_total.counter(&[app.clone(), "read".into()]);
let read_duration = op_duration.histogram(&[app.clone(), "read".into()]);
let sync_ops = op_total.counter(&[app.clone(), "sync".into()]);
let sync_duration = slow_op_duration.histogram(&[app.clone(), "sync".into()]);
Self {
write_ops,
write_duration,
read_ops,
read_duration,
sync_ops,
sync_duration,
}
}
#[cfg(test)]
fn noop() -> Self {
let registry: BoxedRegistry = Box::new(mixtrics::registry::noop::NoopMetricsRegistry);
Self::new("test", ®istry)
}
}
pub struct App {
file: File,
metrics: Arc<DiskMetrics>,
}
impl App {
pub fn new(registry: &BoxedRegistry) -> Self {
let metrics = Arc::new(DiskMetrics::new("my_app", registry));
let file = tempfile::tempfile().unwrap();
Self { file, metrics }
}
pub fn write(&mut self, data: &[u8]) {
let start = Instant::now();
self.file.write_all(data).unwrap();
let elapsed = start.elapsed();
self.metrics.write_ops.increase(1);
self.metrics.write_duration.record(elapsed.as_secs_f64());
}
}
fn main() {
let registry = Box::new(PrometheusMetricsRegistry::new(prometheus_0_14::Registry::new())) as _;
let mut app = App::new(®istry);
app.write(b"Hello, world!");
}