Skip to content

Commit

Permalink
Reorganize xcp-metrics/xcp-metrics-common
Browse files Browse the repository at this point in the history
Remove protocol v3 replaced by newer "xcp-metrics protocol v1".
Remove XAPI RPC.
Remove xcp-rrdd compatibility layers.
Only support "xcp-metrics protocol" for plugins/daemon communication.
  • Loading branch information
TSnake41 committed Jan 6, 2025
1 parent 56ef89e commit 2a549af
Show file tree
Hide file tree
Showing 41 changed files with 647 additions and 2,897 deletions.
40 changes: 30 additions & 10 deletions xcp-metrics-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ rust-version = "1.70" # we need only 1.66 but our deps want 1.70
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
crc32fast = "1.4"
serde_json = "1.0"
anyhow = "1.0"
prost = "0.13"
prost-types = "0.13"
maplit = "1.0"
json5 = "0.4.1"
smol_str = { version = "0.3", features = ["serde"] }

# xcp-metrics protocol v1
ciborium = "0.2"

[dependencies.serde]
version = "1.0"
Expand All @@ -25,19 +24,40 @@ features = ["std", "derive"]
version = "1.11"
features = ["std", "serde", "v4", "fast-rng"]

[dependencies.indexmap]
version = "2.7"
features = ["serde"]

[dependencies.tokio]
version = "1"
features = ["io-util"]

# OpenMetrics support
[dependencies.prost]
version = "0.13"
optional = true

[dependencies.prost-types]
version = "0.13"
optional = true

# RRDD Compatibility dependencies
[dependencies.crc32fast]
version = "1.4"
optional = true

[dependencies.serde_json]
version = "1.0"
optional = true

[dependencies.indexmap]
version = "2.7"
features = ["serde"]
optional = true

[build-dependencies]
prost-build = "0.13"
prost-build = { version = "0.13", optional = true }

[features]
default = []
rrdd_compat = ["dep:crc32fast", "dep:serde_json", "dep:indexmap"]
openmetrics = ["dep:prost", "dep:prost-types", "dep:prost-build"]
test = ["tokio/full"]

[dev-dependencies]
Expand Down
1 change: 1 addition & 0 deletions xcp-metrics-common/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
fn main() {
#[cfg(feature = "openmetrics")]
prost_build::compile_protos(&["src/openmetrics_data_model.proto"], &["src/"]).unwrap();
}
7 changes: 5 additions & 2 deletions xcp-metrics-common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
//! xcp-metrics common library
pub mod metrics;
pub mod protocol;
pub mod utils;

#[cfg(feature = "openmetrics")]
pub mod openmetrics;
pub mod protocol_v3;
#[cfg(feature = "rrdd_compat")]
pub mod rrdd;
pub mod utils;

#[cfg(test)]
mod test;
48 changes: 22 additions & 26 deletions xcp-metrics-common/src/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
//! Common metrics data structures, mostly modelled after OpenMetrics.
use std::{collections::HashMap, time::SystemTime};

use serde::{Deserialize, Serialize};
use smol_str::SmolStr;

/// Top level metric data structure.
#[derive(Clone, Default, PartialEq, Debug)]
pub struct MetricSet {
pub families: HashMap<Box<str>, MetricFamily>,
pub families: HashMap<SmolStr, MetricFamily>,
}

/// A family of [Metric] sharing a [MetricType] and `unit`.
#[derive(Clone, Default, PartialEq, Debug)]
pub struct MetricFamily {
// Number of references to this family.
pub reference_count: usize,
pub metric_type: MetricType,
pub unit: Box<str>,
pub help: Box<str>,
pub unit: SmolStr,
pub help: SmolStr,

pub metrics: HashMap<uuid::Uuid, Metric>,
}

#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Debug)]
#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Debug, Serialize, Deserialize)]
pub enum MetricType {
#[default]
Unknown,
Expand Down Expand Up @@ -45,28 +50,19 @@ impl std::fmt::Display for MetricType {
}
}

#[derive(Clone, PartialEq, Debug, Eq, Hash)]
pub struct Label(
/// Label name
pub Box<str>,
/// Label value
pub Box<str>,
);
#[derive(Clone, PartialEq, Debug, Eq, Hash, Serialize, Deserialize)]
pub struct Label {
pub name: SmolStr,
pub value: SmolStr,
}

#[derive(Clone, Default, PartialEq, Debug)]
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub struct Metric {
pub labels: Box<[Label]>,
pub metrics_point: Box<[MetricPoint]>,
}

#[derive(Clone, PartialEq, Debug)]
pub struct MetricPoint {
/// *Its type should match with MetricFamily's MetricType for text export.*
pub value: MetricValue,
pub timestamp: SystemTime,
}

#[derive(Clone, PartialEq, Debug)]
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub enum MetricValue {
Unknown(NumberValue),
Gauge(NumberValue),
Expand Down Expand Up @@ -105,33 +101,33 @@ impl MetricValue {
}
}

#[derive(Clone, Default, PartialEq, Debug)]
#[derive(Clone, Default, PartialEq, Debug, Serialize, Deserialize)]
pub struct Bucket {
pub count: u64,
pub upper_bound: f64,
pub exemplar: Option<Box<Exemplar>>,
}

#[derive(Clone, Default, PartialEq, Debug)]
#[derive(Clone, Default, PartialEq, Debug, Serialize, Deserialize)]
pub struct Exemplar {
pub value: f64,
pub timestamp: Option<SystemTime>,
pub labels: Box<[Label]>,
}

#[derive(Clone, Default, PartialEq, Debug)]
#[derive(Clone, Default, PartialEq, Debug, Serialize, Deserialize)]
pub struct State {
pub enabled: bool,
pub name: Box<str>,
pub name: SmolStr,
}

#[derive(Clone, Copy, Default, PartialEq, Debug)]
#[derive(Clone, Copy, Default, PartialEq, Debug, Serialize, Deserialize)]
pub struct Quantile {
pub quantile: f64,
pub value: f64,
}

#[derive(Clone, Copy, Default, PartialEq, Debug)]
#[derive(Clone, Copy, Default, PartialEq, Debug, Serialize, Deserialize)]
pub enum NumberValue {
Double(f64),
Int64(i64),
Expand Down
58 changes: 25 additions & 33 deletions xcp-metrics-common/src/openmetrics/convert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
use std::time::SystemTime;

use crate::metrics::{
Bucket, Exemplar, Label, Metric, MetricFamily, MetricPoint, MetricSet, MetricType, MetricValue,
NumberValue, Quantile, State,
Bucket, Exemplar, Label, Metric, MetricFamily, MetricSet, MetricType, MetricValue, NumberValue,
Quantile, State,
};

use super::{
Expand Down Expand Up @@ -59,17 +59,20 @@ impl From<openmetrics::MetricType> for MetricType {

/// Convert a [Label] into a [openmetrics::Label].
impl From<Label> for openmetrics::Label {
fn from(Label(name, value): Label) -> Self {
fn from(Label { name, value }: Label) -> Self {
Self {
name: name.into_string(),
value: value.into_string(),
name: name.to_string(),
value: value.to_string(),
}
}
}

impl From<openmetrics::Label> for Label {
fn from(value: openmetrics::Label) -> Self {
Self(value.name.into_boxed_str(), value.value.into_boxed_str())
Self {
name: value.name.into(),
value: value.value.into(),
}
}
}

Expand Down Expand Up @@ -230,7 +233,7 @@ impl From<State> for openmetrics::state_set_value::State {
fn from(State { enabled, name }: State) -> Self {
Self {
enabled,
name: name.into_string(),
name: name.to_string(),
}
}
}
Expand All @@ -241,7 +244,7 @@ impl From<openmetrics::state_set_value::State> for State {
) -> Self {
Self {
enabled,
name: name.into_boxed_str(),
name: name.into(),
}
}
}
Expand Down Expand Up @@ -360,39 +363,27 @@ impl From<openmetrics::metric_point::Value> for MetricValue {
}
}

impl From<MetricPoint> for openmetrics::MetricPoint {
fn from(MetricPoint { value, timestamp }: MetricPoint) -> Self {
impl From<MetricValue> for openmetrics::MetricPoint {
fn from(value: MetricValue) -> Self {
Self {
value: Some(value.into()),
timestamp: Some(timestamp.into()),
timestamp: None,
}
}
}

impl From<openmetrics::MetricPoint> for MetricPoint {
fn from(openmetrics::MetricPoint { value, timestamp }: openmetrics::MetricPoint) -> Self {
Self {
value: value.map_or(MetricValue::Unknown(NumberValue::Undefined), Into::into),
timestamp: timestamp.map_or_else(SystemTime::now, protobuf_ts_to_std),
}
impl From<openmetrics::MetricPoint> for MetricValue {
fn from(openmetrics::MetricPoint { value, .. }: openmetrics::MetricPoint) -> Self {
value.map_or(MetricValue::Unknown(NumberValue::Undefined), Into::into)
}
}

/// Convert a [Metric] to a [openmetrics::Metric].
impl From<Metric> for openmetrics::Metric {
fn from(
Metric {
labels,
metrics_point,
}: Metric,
) -> Self {
fn from(Metric { labels, value }: Metric) -> Self {
Self {
labels: labels.into_vec().into_iter().map(Into::into).collect(),
metric_points: metrics_point
.into_vec()
.into_iter()
.map(Into::into)
.collect(),
metric_points: vec![value.into()],
}
}
}
Expand All @@ -406,7 +397,7 @@ impl From<openmetrics::Metric> for Metric {
) -> Self {
Self {
labels: labels.into_iter().map(Into::into).collect(),
metrics_point: metric_points.into_iter().map(Into::into).collect(),
value: metric_points.first().cloned().unwrap_or_default().into(),
}
}
}
Expand All @@ -418,9 +409,9 @@ impl From<MetricSet> for openmetrics::MetricSet {
metric_families: families
.into_iter()
.map(|(name, family)| openmetrics::MetricFamily {
name: name.into_string(),
help: family.help.into_string(),
unit: family.unit.into_string(),
name: name.into(),
help: family.help.into(),
unit: family.unit.into(),
r#type: openmetrics::MetricType::from(family.metric_type).into(),
metrics: family
.metrics
Expand All @@ -441,8 +432,9 @@ impl From<openmetrics::MetricSet> for MetricSet {
.into_iter()
.map(|family| {
(
family.name.into_boxed_str(),
family.name.into(),
MetricFamily {
reference_count: 1,
help: family.help.into(),
unit: family.unit.into(),
metric_type: openmetrics::MetricType::try_from(family.r#type)
Expand Down
Loading

0 comments on commit 2a549af

Please sign in to comment.