47 lines
1.8 KiB
Rust
47 lines
1.8 KiB
Rust
//! The meter provider a swarm service pushes its OTLP metrics through.
|
|
//!
|
|
//! Built from the standard `OTEL_*` environment: the endpoint from
|
|
//! `OTEL_EXPORTER_OTLP_ENDPOINT` and the resource from
|
|
//! `OTEL_RESOURCE_ATTRIBUTES`. With no endpoint a service exports nothing, so
|
|
//! a run outside the swarm (a test, a dev shell) needs no collector.
|
|
|
|
use std::time::Duration;
|
|
|
|
use opentelemetry_otlp::{MetricExporter, Protocol, WithExportConfig};
|
|
use opentelemetry_sdk::metrics::{PeriodicReader, SdkMeterProvider};
|
|
|
|
/// How often the metrics are exported.
|
|
const INTERVAL: Duration = Duration::from_mins(1);
|
|
|
|
/// The provider for the service `cert` names in the `bao.client_cert.*` gauges
|
|
/// it also registers on a meter called `meter`, or `None` when no collector is
|
|
/// configured or the exporter failed to build.
|
|
///
|
|
/// The caller keeps the provider alive: it exports only while it lives.
|
|
#[must_use]
|
|
pub fn from_env(meter: &'static str, cert: &'static str) -> Option<SdkMeterProvider> {
|
|
use opentelemetry::metrics::MeterProvider as _;
|
|
|
|
if !std::env::var("OTEL_EXPORTER_OTLP_ENDPOINT").is_ok_and(|s| !s.trim().is_empty()) {
|
|
return None;
|
|
}
|
|
// The blocking client: `PeriodicReader` exports from a thread of its own
|
|
// with no Tokio reactor.
|
|
let exporter = match MetricExporter::builder()
|
|
.with_http()
|
|
.with_protocol(Protocol::HttpJson)
|
|
.build()
|
|
{
|
|
Ok(exporter) => exporter,
|
|
Err(e) => {
|
|
tracing::warn!(error = %e, meter, "building the metric exporter failed; no metrics are exported");
|
|
return None;
|
|
}
|
|
};
|
|
let reader = PeriodicReader::builder(exporter)
|
|
.with_interval(INTERVAL)
|
|
.build();
|
|
let provider = SdkMeterProvider::builder().with_reader(reader).build();
|
|
crate::cert_metrics::register(&provider.meter(meter), cert);
|
|
Some(provider)
|
|
}
|