prometheus/
auto_flush.rs
1use crate::core::Atomic;
2use crate::counter::{CounterWithValueType, GenericLocalCounter};
3use crate::histogram::{Instant, LocalHistogram};
4use crate::metrics::MayFlush;
5use crate::timer;
6use parking_lot::Mutex;
7use std::thread::LocalKey;
8
9pub trait CounterDelegator<T: 'static + MayFlush, V: CounterWithValueType> {
11 fn get_root_metric(&self) -> &'static LocalKey<T>;
13
14 fn get_local<'a>(&self, root_metric: &'a T) -> &'a GenericLocalCounter<V::ValueType>;
16}
17
18pub trait HistogramDelegator<T: 'static + MayFlush> {
20 fn get_root_metric(&self) -> &'static LocalKey<T>;
22
23 fn get_local<'a>(&self, root_metric: &'a T) -> &'a LocalHistogram;
25}
26
27#[derive(Debug)]
29pub struct AFLocalCounter<T: 'static + MayFlush, V: CounterWithValueType, D: CounterDelegator<T, V>>
30{
31 delegator: D,
33 _p: std::marker::PhantomData<(Mutex<T>, Mutex<V>)>,
35}
36
37impl<T: 'static + MayFlush, V: CounterWithValueType, D: CounterDelegator<T, V>>
38 AFLocalCounter<T, V, D>
39{
40 pub fn new(delegator: D) -> AFLocalCounter<T, V, D> {
42 timer::ensure_updater();
43 AFLocalCounter {
44 delegator,
45 _p: std::marker::PhantomData,
46 }
47 }
48}
49
50impl<T: 'static + MayFlush, V: CounterWithValueType, D: CounterDelegator<T, V>>
52 AFLocalCounter<T, V, D>
53{
54 #[inline]
55 fn get_root_metric(&self) -> &'static LocalKey<T> {
57 self.delegator.get_root_metric()
58 }
59
60 #[inline]
61 fn get_counter<'a>(&self, root_metric: &'a T) -> &'a GenericLocalCounter<V::ValueType> {
63 self.delegator.get_local(root_metric)
64 }
65
66 #[inline]
72 pub fn inc_by(&self, v: <V::ValueType as Atomic>::T) {
73 self.get_root_metric().with(|m| {
74 let counter = self.get_counter(m);
75 counter.inc_by(v);
76 m.may_flush();
77 })
78 }
79
80 #[inline]
83 pub fn inc(&self) {
84 self.get_root_metric().with(|m| {
85 let counter = self.get_counter(m);
86 counter.inc();
87 m.may_flush();
88 })
89 }
90
91 #[inline]
93 pub fn get(&self) -> <V::ValueType as Atomic>::T {
94 self.get_root_metric().with(|m| {
95 let counter = self.get_counter(m);
96 counter.get()
97 })
98 }
99
100 #[inline]
102 pub fn reset(&self) {
103 self.get_root_metric().with(|m| {
104 let counter = self.get_counter(m);
105 counter.reset();
106 })
107 }
108
109 #[inline]
111 pub fn flush(&self) {
112 self.get_root_metric().with(|m| m.flush())
113 }
114}
115
116#[derive(Debug)]
118pub struct AFLocalHistogram<T: 'static + MayFlush, D: HistogramDelegator<T>> {
119 delegator: D,
121 _p: std::marker::PhantomData<Mutex<T>>,
123}
124
125impl<T: 'static + MayFlush, D: HistogramDelegator<T>> AFLocalHistogram<T, D> {
126 pub fn new(delegator: D) -> AFLocalHistogram<T, D> {
128 timer::ensure_updater();
129 AFLocalHistogram {
130 delegator,
131 _p: std::marker::PhantomData,
132 }
133 }
134}
135
136impl<M: 'static + MayFlush, D: HistogramDelegator<M>> AFLocalHistogram<M, D> {
137 pub fn observe(&self, v: f64) {
139 self.delegator.get_root_metric().with(|m| {
140 let local = self.delegator.get_local(m);
141 local.observe(v);
142 m.may_flush();
143 })
144 }
145
146 pub fn observe_closure_duration<F, T>(&self, f: F) -> T
148 where
149 F: FnOnce() -> T,
150 {
151 let instant = Instant::now();
152 let res = f();
153 let elapsed = instant.elapsed_sec();
154 self.observe(elapsed);
155 res
156 }
157
158 #[cfg(feature = "nightly")]
160 pub fn observe_closure_duration_coarse<F, T>(&self, f: F) -> T
161 where
162 F: FnOnce() -> T,
163 {
164 let instant = Instant::now_coarse();
165 let res = f();
166 let elapsed = instant.elapsed_sec();
167 self.observe(elapsed);
168 res
169 }
170
171 pub fn clear(&self) {
173 self.delegator
174 .get_root_metric()
175 .with(|m| self.delegator.get_local(m).clear())
176 }
177
178 pub fn flush(&self) {
180 self.delegator
181 .get_root_metric()
182 .with(|m| self.delegator.get_local(m).flush());
183 }
184
185 pub fn get_sample_sum(&self) -> f64 {
187 self.delegator
188 .get_root_metric()
189 .with(|m| self.delegator.get_local(m).get_sample_sum())
190 }
191
192 pub fn get_sample_count(&self) -> u64 {
194 self.delegator
195 .get_root_metric()
196 .with(|m| self.delegator.get_local(m).get_sample_count())
197 }
198}