metrics-rs / metrics

A metrics ecosystem for Rust.
MIT License
1.1k stars 151 forks source link

Allow for declaration of set of labels without default values #356

Closed CinchBlue closed 1 year ago

CinchBlue commented 1 year ago

Currently using metrics and metrics-prometheus and prometheus.

Consider:

// Declare each metric with their default values
metrics::register_counter!("failures", "comp_id" => "", "error" => "");

metrics::counter!("failures", 1, "error"=>"true", "comp_id" => "nba");
metrics::counter!("failures", 2, "error"=>"false", "comp_id" => "nba");
metrics::counter!("failures", 3, "error"=>"whaoasdfa", "comp_id" => "a123");
metrics::counter!("failures", 3, "error"=>"asdfqwe", "comp_id" => "b123", "wowow" => "owowoww");

when the metrics report is generated, you get:

# HELP failures failures
# TYPE failures counter
failures{comp_id="",error=""} 0
failures{comp_id="a123",error="whaoasdfa"} 3
failures{comp_id="nba",error="false"} 2
failures{comp_id="nba",error="true"} 1

This is not so great because there's the extra "default" metric

failures{comp_id="",error=""} 0

is there a way to not have to have this? I know the set of labels but not the full set of values.

tobz commented 1 year ago

The calls to counter! (or any other macro for emitting a metric) will register a metric if it doesn't yet exist, so the call to register_counter! is extraneous here.

CinchBlue commented 1 year ago

I am using metrics-prometheus which allows for freezing metrics after a certain point: https://docs.rs/metrics-prometheus/0.3.1/metrics_prometheus/struct.FreezableRecorder.html

This allows downstream consumers of libraries that use metrics to only listen to the metrics that they desire, and then disallow the reporting of other metrics that are not specified.

Because there is not a way to pre-specify the labels without creating the default metric, you'll need to pay the cost of having this default metric if you do not have a good default value for all of your labels.

You could potentially work around this with configuration on the consumer/agent side, but that's not ideal.

tobz commented 1 year ago

Admittedly, taking a quick look at metrics_prometheus::FreezableRecorder... it looks like you'd have to register the precise metrics that you want (i.e. the labels would need to be populated).

Registering a metric, and having it immediately show up despite not yet having been emitted, is pretty fundamental. It's not something that we would change on the metrics side, at least.

CinchBlue commented 1 year ago

Ok, that sounds reasonable. Thanks.