use crate::observability::config::MetricsConfig;
use crate::observability::remote::append_otlp_path;
use anyhow::{bail, Context as AnyhowContext, Result};
use opentelemetry::KeyValue;
use opentelemetry_otlp::{MetricExporter, Protocol, WithExportConfig};
use opentelemetry_sdk::{metrics::SdkMeterProvider, metrics::Temporality, Resource};
pub fn build_metrics_provider(config: &MetricsConfig) -> Result<SdkMeterProvider> {
if config.exporter != "otlp" {
bail!("unsupported metrics exporter `{}`", config.exporter);
}
let endpoint = append_otlp_path(&config.endpoint, "/v1/metrics");
let exporter = MetricExporter::builder()
.with_http()
.with_protocol(Protocol::HttpBinary)
.with_endpoint(endpoint)
.with_temporality(Temporality::LowMemory)
.build()
.context("failed to create OpenTelemetry metrics exporter")?;
let provider = SdkMeterProvider::builder()
.with_periodic_exporter(exporter)
.with_resource(resource(config))
.build();
Ok(provider)
}
fn resource(config: &MetricsConfig) -> Resource {
let mut builder = Resource::builder().with_service_name(config.service_name.clone());
if let Some(version) = &config.service_version {
builder = builder.with_attribute(KeyValue::new("service.version", version.clone()));
}
builder.build()
}