client_rust icon indicating copy to clipboard operation
client_rust copied to clipboard

Support deriving metric storage

Open Ten0 opened this issue 2 years ago • 2 comments

It would be super useful to have derives for metrics storages, like was done for the prometheus crate (essentially porting https://crates.io/crates/prometheus-metric-storage).

#[derive(prometheus_metric_storage::MetricStorage)]
#[metric(subsystem = "transport", labels("endpoint"))]
struct Metrics {
    /// Number of requests that are currently inflight.
    inflight: prometheus::IntGauge,

    /// Number of finished requests by response code.
    #[metric(labels("status"))]
    requests_finished: prometheus::IntCounterVec,

    /// Number of finished requests by total processing duration.
    #[metric(buckets(0.1, 0.2, 0.5, 1, 2, 4, 8))]
    requests_duration_seconds: prometheus::Histogram,
}

fn main() {
    let metrics = Metrics::new(
        prometheus::default_registry(),
        /* endpoint = */ "0.0.0.0:8080"
    ).unwrap();

    metrics.inflight.inc();
    metrics.requests_finished.with_label_values(&["200"]).inc();
    metrics.requests_duration_seconds.observe(0.015);
}

This would enable to not forget to register metrics that are in a struct into the registry.

Ten0 avatar Dec 24 '22 16:12 Ten0

Do I understand correctly, that this would generate the metric registration logic? I am not opposed to adding this to this crate. That said, given that it would be a proc derive macro, I suggest doing so out-of-tree, potentially only for now.

mxinden avatar Jan 02 '23 20:01 mxinden

Do I understand correctly, that this would generate the metric registration logic?

Yes, currently it's pretty boilerplateish and error-prone when you have a significant set of metrics held in a struct that need to be registered, so that would make it really great on both aspects 😊

Ten0 avatar Jan 03 '23 02:01 Ten0