Export `CounterVecBuilder` as in prometheus::core
Hi devs,
Proposal
TL::DR, I have a visibility problem when coding a small cache and i think a struct should be exported.
Background
I had a fast loop that executed with_label_values() inside. Which is some kind of a performance hit. From the 3 strings that identify this CounterVec, i know 1 from the struct. one is a u64, but in 99% a number < 10. the last one is guaranteed to be 0 < n < 8. My Idea was to build a small cache, hold the values, and just return their references.
The Cache
pub(crate) struct PidCidFrameCache<T: MetricVecBuilder> {
metric: MetricVec<T>,
pid: String,
cache: Vec<[T::M; 8]>,
}
pid is the 1. string, the u64 is encoded in the vec and the 0 < n 8 is encoded in the array.
I wanted to build this for ALL kinds of MetricVecs, thats why i use your MetricVecBuilder trait you happily export to prometheus::core
I just skipp the implementation. However the point is, it works!
let x = PidCidFrameCache::new(self.metrics.frames_out_total.clone(), "RANDOM_PID_HERE");
The Problem
Unluckily the type of x is now:
prometheus::vec::MetricVec<prometheus::counter::CounterVecBuilder<prometheus::atomic64::AtomicI64>>
and here comes my problem.
I can happily create this cache!
But i can't pass it to another function, as it would require me to specify it's interface. And i can't write down CounterVecBuilder as it's private.
So yeah, it's a bit of a weird situation. The code for CounterVecBuilder itself is only 20 lines, and i tried to copy it like this:
pub type PidCidFrameCacheCV = PidCidFrameCache<MyCounterVecBuilder<prometheus::core::AtomicI64>>;
however compile doesn't like the assigment then any more:
let x:PidCidFrameCacheCV = PidCidFrameCacheCV::new(self.metrics.frames_out_total.clone(), "RANDOM_PID_HERE");
= note: expected struct `prometheus::vec::MetricVec<MyCounterVecBuilder<prometheus::atomic64::AtomicI64>>`
found struct `prometheus::vec::MetricVec<prometheus::counter::CounterVecBuilder<prometheus::atomic64::AtomicI64>>`
The Workaround
I could probably pass the <T: MetricVecBuilder> all trough my implementation.
But while the cache code itself will be used for multiple MetricCounts, this usage will only ever use CounterVecBuilder, so it would be quite ugly code which isn't needed.
additionally this doesn't give me the .inc function without some complicated rust template programming too
Thanks for report!
Looking at https://docs.rs/prometheus/0.9.0/prometheus/core/struct.MetricVec.html, there are indeed a bunch of private types appearing in public signatures (CounterVecBuilder and GaugeVecBuilder at least).
My guess is that this behavior is not intentional, as the types themselves are marked as pub but the top-level module is not re-exporting them.
This is indeed not a use case we covered before. How about simply make counter, gauge and histogram module pub?
that would prob work for me, if it's fine for you from the Api side
It doesn't seem like there's a valid use case here which doesn't use one of the resources in pub. Should this be closed?