rust-prometheus icon indicating copy to clipboard operation
rust-prometheus copied to clipboard

Using the register_* macros makes it difficult to test components

Open sazzer opened this issue 5 years ago • 6 comments

Is your feature request related to a problem? Please describe. I've been using the register_int_counter_vec macro to create and register my metrics, which works great. However, because it always registers with the default registry, this means that I can only call it once per thread. Running multiple tests thus hits problems because it's trying to register the same metric in different tests, and all but the first then fails with AlreadyReg.

I can work around this by using IntCounterVec::new and Register::register, but it would be nice if it could be done with the macros that are intended to make creating these easier.

Describe the solution you'd like Being able to pass the registry into the macros would solve this.

Additional context This is using prometheus = "0.11.0".

sazzer avatar Jan 24 '21 10:01 sazzer

Considering that these macros do both things: simplify the creation of the metrics && register to the default register, how about accepting one more optional parameter to specify the register?

breezewish avatar Jan 25 '21 01:01 breezewish

Sorry - Real life! Yes, that additional parameter would pretty much solve it :)

sazzer avatar Feb 28 '21 17:02 sazzer

Considering that these macros do both things: simplify the creation of the metrics && register to the default register, how about accepting one more optional parameter to specify the register?

@breeswish is there something in the works for this? if not I wouldn't mind implementing it, as I need this for a project currently using this crate

moustafab avatar Mar 03 '21 02:03 moustafab

@moustafab I don't think anybody is working on this right now, feel free to go ahead and submit a PR whenever you are ready for a review.

lucab avatar Mar 03 '21 09:03 lucab

@moustafab I don't think anybody is working on this right now, feel free to go ahead and submit a PR whenever you are ready for a review.

@lucab PR submitted, let me know if you need anything for that to land, I'll get it wrapped ASAP.

moustafab avatar Mar 08 '21 19:03 moustafab

FWIW, I solved this with auto-flush, "local" metrics:

use once_cell::sync::Lazy;
use prometheus::*;
use prometheus_static_metric::{auto_flush_from, make_auto_flush_static_metric};

make_auto_flush_static_metric! {
    pub label_enum Service {
        web,
        api,
    }

    pub label_enum Target {
        database,
        cache,
        initialization,
        process,
    }

    pub label_enum Event {
        hit,
        miss,
        error,
        start,
        finish,
    }

    pub struct ServiceTargetEvent : LocalIntCounter {
        "service" => Service,
        "target" => Target,
        "event" => Event,
    }
}

pub static STE_COUNTER_VEC: Lazy<IntCounterVec> = Lazy::new(|| {
    register_int_counter_vec!(
        "service_target_events",
        "Events related to targets of some service.",
        &["service", "target", "event"]
    )
    .unwrap()
});

pub static STE_COUNTER: Lazy<ServiceTargetEvent> = Lazy::new(|| {
    auto_flush_from!(
        STE_COUNTER_VEC,
        ServiceTargetEvent,
        std::time::Duration::from_secs(1)
    )
});

Usage looks like:

STE_COUNTER.api.initialization.finish.inc();

jasondemorrow avatar Jun 02 '24 18:06 jasondemorrow