bare_metrics_core/
structures.rs

1use hdrhistogram::serialization::{
2    Deserializer as HistogramDeserialiser, Serializer as HistogramSerializer, V2Serializer,
3};
4use hdrhistogram::Histogram;
5use serde::de::Error;
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7use serde_bare::Uint;
8use std::collections::{BTreeMap, HashMap};
9
10pub fn get_supported_version() -> String {
11    format!("bare-metrics:{}", env!("CARGO_PKG_VERSION"))
12}
13
14#[derive(
15    Copy, Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize, Default,
16)]
17pub struct UnixTimestampMilliseconds(pub u64);
18
19impl UnixTimestampMilliseconds {
20    pub fn as_f64_seconds(self) -> f64 {
21        self.0 as f64 * 0.001
22    }
23}
24
25/// Header for a metric log file.
26#[derive(Serialize, Deserialize, Clone, Debug, Default)]
27pub struct LogHeader {
28    /// String describing the version of this metrics log file.
29    pub bare_metrics_version: String,
30    /// Name of the application that emitted this metrics log file.
31    /// Useful for auto-detection of rules for e.g. the GUI.
32    pub application_name: String,
33    /// Unix timestamp (milliseconds) describing the start of the metrics.
34    pub start_time: UnixTimestampMilliseconds,
35}
36
37/// A single frame of metrics.
38/// Has an end timestamp (the start timestamp should be inferred from the previous frame or the
39/// header of the log file.
40#[derive(Serialize, Deserialize, Clone, Debug, Default)]
41pub struct Frame {
42    /// Unix timestamp (milliseconds) describing the end of this frame of metrics.
43    pub end_time: UnixTimestampMilliseconds,
44    /// Absolute values of updated gauges.
45    pub gauge_updates: HashMap<MetricId, f64>,
46    /// Absolute values of updated counters.
47    /// TODO should this be counts only for this window?
48    pub counter_updates: HashMap<MetricId, Uint>,
49    /// Histograms only for this frame (this keeps them compact).
50    pub histograms: HashMap<MetricId, SerialisableHistogram>,
51    /// Descriptors of NEW metrics.
52    pub new_metrics: HashMap<MetricId, MetricDescriptor>,
53}
54
55#[derive(Serialize, Deserialize, Copy, Clone, Debug)]
56pub enum MetricKind {
57    Histogram,
58    Gauge,
59    Counter,
60}
61
62#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
63pub struct MetricId(pub u16);
64
65#[derive(Serialize, Deserialize, Clone, Debug)]
66pub struct MetricDescriptor {
67    pub kind: MetricKind,
68    pub unit: Option<String>,
69    pub description: String,
70    pub name: String,
71    pub labels: BTreeMap<String, String>,
72}
73
74#[derive(Clone, Debug)]
75pub struct SerialisableHistogram {
76    pub underlying: Histogram<u64>,
77}
78
79impl Serialize for SerialisableHistogram {
80    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
81    where
82        S: Serializer,
83    {
84        let mut buf = Vec::new();
85        V2Serializer::new()
86            .serialize(&self.underlying, &mut buf)
87            .expect("can't fail writing to buf");
88        serializer.serialize_bytes(&buf)
89    }
90}
91
92impl<'a> Deserialize<'a> for SerialisableHistogram {
93    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
94    where
95        D: Deserializer<'a>,
96    {
97        let bytes = Vec::<u8>::deserialize(deserializer)?;
98        let histogram = HistogramDeserialiser::new()
99            .deserialize(&mut &bytes[..])
100            .map_err(|e| D::Error::custom(format!("{:?}", e)))?;
101        Ok(SerialisableHistogram {
102            underlying: histogram,
103        })
104    }
105}