linkerd2-proxy/src/telemetry/metrics/mod.rs

86 lines
2.9 KiB
Rust

//! Records and serves Prometheus metrics.
//!
//! # A note on label formatting
//!
//! Prometheus labels are represented as a comma-separated list of values
//! Since the proxy labels its metrics with a fixed set of labels
//! which we know in advance, we represent these labels using a number of
//! `struct`s, all of which implement `fmt::Display`. Some of the label
//! `struct`s contain other structs which represent a subset of the labels
//! which can be present on metrics in that scope. In this case, the
//! `fmt::Display` impls for those structs call the `fmt::Display` impls for
//! the structs that they own. This has the potential to complicate the
//! insertion of commas to separate label values.
//!
//! In order to ensure that commas are added correctly to separate labels,
//! we expect the `fmt::Display` implementations for label types to behave in
//! a consistent way: A label struct is *never* responsible for printing
//! leading or trailing commas before or after the label values it contains.
//! If it contains multiple labels, it *is* responsible for ensuring any
//! labels it owns are comma-separated. This way, the `fmt::Display` impl for
//! any struct that represents a subset of the labels are position-agnostic;
//! they don't need to know if there are other labels before or after them in
//! the formatted output. The owner is responsible for managing that.
//!
//! If this rule is followed consistently across all structs representing
//! labels, we can add new labels or modify the existing ones without having
//! to worry about missing commas, double commas, or trailing commas at the
//! end of the label set (all of which will make Prometheus angry).
use std::fmt;
mod counter;
mod gauge;
mod histogram;
pub mod latency;
pub mod prom;
mod scopes;
mod serve;
pub use self::counter::Counter;
pub use self::gauge::Gauge;
pub use self::histogram::Histogram;
pub use self::prom::{FmtMetrics, FmtLabels, FmtMetric};
pub use self::scopes::Scopes;
pub use self::serve::Serve;
use super::{http, process, tls_config_reload, transport};
/// The root scope for all runtime metrics.
#[derive(Debug)]
pub struct Root {
http: http::Report,
transports: transport::Report,
tls_config_reload: tls_config_reload::Report,
process: process::Report,
}
// ===== impl Root =====
impl Root {
pub(super) fn new(
http: http::Report,
transports: transport::Report,
tls_config_reload: tls_config_reload::Report,
process: process::Report,
) -> Self {
Self {
http,
transports,
tls_config_reload,
process,
}
}
}
// ===== impl Root =====
impl FmtMetrics for Root {
fn fmt_metrics(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.http.fmt_metrics(f)?;
self.transports.fmt_metrics(f)?;
self.tls_config_reload.fmt_metrics(f)?;
self.process.fmt_metrics(f)?;
Ok(())
}
}