metrics-rs / metrics

A metrics ecosystem for Rust.
MIT License
1.13k stars 157 forks source link

Scoped recorders #389

Closed david-perez closed 10 months ago

david-perez commented 1 year ago

I'm testing a Recorder implementation and getting cross-test contamination because the recorder is shared across all threads and registered globally. I've had a look at how the crate tests its recorders and noticed how it uses Debugging::per_thread for thread-local metrics, and clear_recorder to test the entire recorder implementation in the same test, setting the recorder each time after clearing it. However, I don't think these ingredients suffice to test the same recorder implementation across different tests running in parallel in the same process.

I was wondering whether it's possible to introduce recorders that live within a scope, much like how tracing::dispatcher allows to set a scoped subscriber:

let recorder = MyRecorder::new();
let dispatcher = metrics::dispatch::Dispatcher::new(recorder);

// no default recorder

metrics::dispatcher::with_default(&dispatcher, || {
    // `recorder` will handle metrics emitted within this scope.
});

// no default recorder again
tobz commented 1 year ago

This has definitely come up before and is likely something I'll tackle in the future since, as you note, it makes actually testing any code that uses metrics much more complex/finnicky.