Skip to main content

dipstick/output/
map.rs

1use crate::attributes::{Attributes, MetricId, OnFlush, Prefixed, WithAttributes};
2use crate::input::{Input, InputKind, InputMetric, InputScope};
3use crate::name::MetricName;
4use crate::{Flush, MetricValue};
5
6use std::collections::BTreeMap;
7
8use std::io;
9use std::sync::{Arc, RwLock};
10
11/// A BTreeMap wrapper to receive metrics or stats values.
12/// Every received value for a metric replaces the previous one (if any).
13#[derive(Clone, Default)]
14pub struct StatsMap {
15    attributes: Attributes,
16}
17
18impl WithAttributes for StatsMap {
19    fn get_attributes(&self) -> &Attributes {
20        &self.attributes
21    }
22    fn mut_attributes(&mut self) -> &mut Attributes {
23        &mut self.attributes
24    }
25}
26
27impl Input for StatsMap {
28    type SCOPE = StatsMapScope;
29
30    fn metrics(&self) -> Self::SCOPE {
31        StatsMapScope {
32            attributes: self.attributes.clone(),
33            inner: Arc::new(RwLock::new(BTreeMap::new())),
34        }
35    }
36}
37
38/// A BTreeMap wrapper to receive metrics or stats values.
39/// Every received value for a metric replaces the previous one (if any).
40#[derive(Clone, Default)]
41pub struct StatsMapScope {
42    attributes: Attributes,
43    inner: Arc<RwLock<BTreeMap<String, MetricValue>>>,
44}
45
46impl WithAttributes for StatsMapScope {
47    fn get_attributes(&self) -> &Attributes {
48        &self.attributes
49    }
50    fn mut_attributes(&mut self) -> &mut Attributes {
51        &mut self.attributes
52    }
53}
54
55impl InputScope for StatsMapScope {
56    fn new_metric(&self, name: MetricName, _kind: InputKind) -> InputMetric {
57        let name = self.prefix_append(name);
58        let write_to = self.inner.clone();
59        let key: String = name.join(".");
60        InputMetric::new(MetricId::forge("map", name), move |value, _labels| {
61            let _previous = write_to.write().expect("Lock").insert(key.clone(), value);
62        })
63    }
64}
65
66impl Flush for StatsMapScope {
67    fn flush(&self) -> io::Result<()> {
68        self.notify_flush_listeners();
69        Ok(())
70    }
71}
72
73impl From<StatsMapScope> for BTreeMap<String, MetricValue> {
74    fn from(map: StatsMapScope) -> Self {
75        // FIXME this is is possibly a full map copy, for no reason.
76        // into_inner() is what we'd really want here but would require some `unsafe`? don't know how to do this yet.
77        map.inner.read().unwrap().clone()
78    }
79}
80
81impl StatsMapScope {
82    /// Extract the backing BTreeMap.
83    pub fn into_map(self) -> BTreeMap<String, MetricValue> {
84        self.into()
85    }
86}