|
|
|
@ -0,0 +1,89 @@
|
|
|
|
|
use hdrhistogram::serialization::{
|
|
|
|
|
Deserializer as HistogramDeserialiser, Serializer as HistogramSerializer, V2Serializer,
|
|
|
|
|
};
|
|
|
|
|
use hdrhistogram::Histogram;
|
|
|
|
|
use serde::de::Error;
|
|
|
|
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
|
|
|
|
use serde_bare::Uint;
|
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
|
|
pub fn get_supported_version() -> String {
|
|
|
|
|
format!("bare-metrics:{}", env!("CARGO_PKG_VERSION"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Header for a metric log file.
|
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
|
|
|
|
pub struct LogHeader {
|
|
|
|
|
/// String describing the version of this metrics log file.
|
|
|
|
|
pub bare_metrics_version: String,
|
|
|
|
|
/// Unix timestamp (milliseconds) describing the start of the metrics.
|
|
|
|
|
pub start_time_ms: u64,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// A single frame of metrics.
|
|
|
|
|
/// Has an end timestamp (the start timestamp should be inferred from the previous frame or the
|
|
|
|
|
/// header of the log file.
|
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug, Default)]
|
|
|
|
|
pub struct Frame {
|
|
|
|
|
/// Unix timestamp (milliseconds) describing the end of this frame of metrics.
|
|
|
|
|
pub end_time_ms: u64,
|
|
|
|
|
/// Absolute values of updated gauges.
|
|
|
|
|
pub gauge_updates: HashMap<MetricId, f64>,
|
|
|
|
|
/// Absolute values of updated counters.
|
|
|
|
|
/// TODO should this be counts only for this window?
|
|
|
|
|
pub counter_updates: HashMap<MetricId, Uint>,
|
|
|
|
|
/// Histograms only for this frame (this keeps them compact).
|
|
|
|
|
pub histograms: HashMap<MetricId, SerialisableHistogram>,
|
|
|
|
|
/// Descriptors of NEW metrics.
|
|
|
|
|
pub new_metrics: HashMap<MetricId, MetricDescriptor>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Copy, Clone, Debug)]
|
|
|
|
|
pub enum MetricKind {
|
|
|
|
|
Histogram,
|
|
|
|
|
Gauge,
|
|
|
|
|
Counter,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Copy, Clone, Debug, Hash, Eq, PartialEq, Ord, PartialOrd)]
|
|
|
|
|
pub struct MetricId(pub u16);
|
|
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Clone, Debug)]
|
|
|
|
|
pub struct MetricDescriptor {
|
|
|
|
|
pub kind: MetricKind,
|
|
|
|
|
pub unit: Option<String>,
|
|
|
|
|
pub description: String,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
|
pub struct SerialisableHistogram {
|
|
|
|
|
pub underlying: Histogram<u64>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Serialize for SerialisableHistogram {
|
|
|
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
|
|
|
where
|
|
|
|
|
S: Serializer,
|
|
|
|
|
{
|
|
|
|
|
let mut buf = Vec::new();
|
|
|
|
|
V2Serializer::new()
|
|
|
|
|
.serialize(&self.underlying, &mut buf)
|
|
|
|
|
.expect("can't fail writing to buf");
|
|
|
|
|
serializer.serialize_bytes(&buf)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<'a> Deserialize<'a> for SerialisableHistogram {
|
|
|
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
|
|
|
where
|
|
|
|
|
D: Deserializer<'a>,
|
|
|
|
|
{
|
|
|
|
|
let bytes = Vec::<u8>::deserialize(deserializer)?;
|
|
|
|
|
let histogram = HistogramDeserialiser::new()
|
|
|
|
|
.deserialize(&mut &bytes[..])
|
|
|
|
|
.map_err(|e| D::Error::custom(format!("{:?}", e)))?;
|
|
|
|
|
Ok(SerialisableHistogram {
|
|
|
|
|
underlying: histogram,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|