Skip to content

Commit

Permalink
src/metrics: Implement info metrics
Browse files Browse the repository at this point in the history
Open Metrics [`Info`] metric "to expose textual information which SHOULD
NOT change during process lifetime".

```
use open_metrics_client::metrics::info::Info;

let _info = Info::new(vec![("os", "GNU/linux")]);
```
  • Loading branch information
mxinden committed Jun 8, 2021
1 parent 6afc61f commit 01a1749
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 3 deletions.
2 changes: 0 additions & 2 deletions README.md
Expand Up @@ -28,8 +28,6 @@ behind the Open Metrics specification. Not being compliant with all requirements
(`MUST` and `MUST NOT`) of the specification is considered a bug and likely to
be fixed in the future. Contributions in all forms are most welcome.

- Info metric.

- State set metric.

- Enforce "A Histogram MetricPoint MUST contain at least one bucket".
Expand Down
42 changes: 42 additions & 0 deletions src/encoding/text.rs
Expand Up @@ -29,6 +29,7 @@ use crate::metrics::exemplar::{CounterWithExemplar, Exemplar, HistogramWithExemp
use crate::metrics::family::Family;
use crate::metrics::gauge::{self, Gauge};
use crate::metrics::histogram::Histogram;
use crate::metrics::info::Info;
use crate::metrics::{MetricType, TypedMetric};
use crate::registry::{Registry, Unit};

Expand Down Expand Up @@ -167,6 +168,7 @@ impl Encode for MetricType {
MetricType::Counter => "counter",
MetricType::Gauge => "gauge",
MetricType::Histogram => "histogram",
MetricType::Info => "info",
MetricType::Unknown => "unknown",
};

Expand Down Expand Up @@ -540,6 +542,28 @@ fn encode_histogram_with_maybe_exemplars<S: Encode>(
Ok(())
}

/////////////////////////////////////////////////////////////////////////////////
// Info

impl<S> EncodeMetric for Info<S>
where
S: Clone + std::hash::Hash + Eq + Encode,
{
fn encode(&self, mut encoder: Encoder) -> Result<(), std::io::Error> {
encoder
.encode_suffix("info")?
.no_bucket()?
.encode_value(1u32)?
.no_exemplar()?;

Ok(())
}

fn metric_type(&self) -> MetricType {
Self::TYPE
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -639,6 +663,24 @@ mod tests {
parse_with_python_client(String::from_utf8(encoded).unwrap());
}

#[test]
fn encode_info() {
let mut registry = Registry::default();
let info = Info::new(vec![("os".to_string(), "GNU/linux".to_string())]);
registry.register("my_info_metric", "My info metric", info);

let mut encoded = Vec::new();
encode(&mut encoded, &registry).unwrap();

let expected = "# HELP my_info_metric My info metric.\n".to_owned()
+ "# TYPE my_info_metric info\n"
+ "my_info_metric_info 1\n"
+ "# EOF\n";
assert_eq!(expected, String::from_utf8(encoded.clone()).unwrap());

parse_with_python_client(String::from_utf8(encoded).unwrap());
}

#[test]
fn encode_histogram() {
let mut registry = Registry::default();
Expand Down
3 changes: 2 additions & 1 deletion src/metrics.rs
Expand Up @@ -5,6 +5,7 @@ pub mod exemplar;
pub mod family;
pub mod gauge;
pub mod histogram;
pub mod info;

/// A metric that is aware of its Open Metrics metric type.
pub trait TypedMetric {
Expand All @@ -16,11 +17,11 @@ pub enum MetricType {
Counter,
Gauge,
Histogram,
Info,
Unknown,
// Not (yet) supported metric types.
//
// GaugeHistogram,
// Info,
// StateSet,
// Summary
}
25 changes: 25 additions & 0 deletions src/metrics/info.rs
@@ -0,0 +1,25 @@
//! Module implementing an Open Metrics info metric.
//!
//! See [`Info`] for details.

use crate::metrics::{MetricType, TypedMetric};

/// Open Metrics [`Info`] metric "to expose textual information which SHOULD NOT
/// change during process lifetime".
///
/// ```
/// # use open_metrics_client::metrics::info::Info;
///
/// let _info = Info::new(vec![("os", "GNU/linux")]);
/// ```
pub struct Info<S>(S);

impl<S> Info<S> {
pub fn new(label_set: S) -> Self {
Self(label_set)
}
}

impl<S> TypedMetric for Info<S> {
const TYPE: MetricType = MetricType::Info;
}

0 comments on commit 01a1749

Please sign in to comment.