Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 39 additions & 6 deletions crates/metrics/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
pub use {future::*, once_cell::sync::Lazy, opentelemetry as otel, task::*};
pub use {
future::*,
once_cell::sync::Lazy,
opentelemetry as otel,
opentelemetry_sdk as otel_sdk,
task::*,
};
use {
opentelemetry_sdk::metrics::SdkMeterProvider,
otel::metrics::{Meter, MeterProvider},
opentelemetry_sdk::metrics::{MeterProviderBuilder, SdkMeterProvider},
otel::{
global,
metrics::{Meter, MeterProvider},
},
prometheus::{Error as PrometheusError, Registry, TextEncoder},
std::{
sync::{Arc, Mutex},
Expand All @@ -17,19 +26,27 @@ const DEFAULT_SERVICE_NAME: &str = "unknown_service";

static SERVICE_NAME: Mutex<Option<&str>> = Mutex::new(None);

pub type MeterProviderBuilderFn = fn(MeterProviderBuilder) -> MeterProviderBuilder;
static METER_PROVIDER_BUILDER_FN: Mutex<Option<MeterProviderBuilderFn>> = Mutex::new(None);

static METRICS_CORE: Lazy<Arc<ServiceMetrics>> = Lazy::new(|| {
let service_name = SERVICE_NAME.lock().unwrap().unwrap_or(DEFAULT_SERVICE_NAME);
let meter_provider_builder = *METER_PROVIDER_BUILDER_FN.lock().unwrap();

let registry = Registry::new();
let prometheus_exporter = opentelemetry_prometheus::exporter()
.with_registry(registry.clone())
.build()
.unwrap();
let provider = SdkMeterProvider::builder()
.with_reader(prometheus_exporter)
.build();
let mut builder = SdkMeterProvider::builder().with_reader(prometheus_exporter);
if let Some(buidler_fn) = meter_provider_builder {
builder = buidler_fn(builder);
};
let provider = builder.build();
let meter = provider.meter(service_name);

global::set_meter_provider(provider);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enables general use of global:: stuff. Don't think we are using this right now, but it's a best practice


Arc::new(ServiceMetrics { registry, meter })
});

Expand Down Expand Up @@ -64,6 +81,22 @@ impl ServiceMetrics {
Lazy::force(&METRICS_CORE);
}

/// Initializes service metrics with the specified name and meter provider
/// builder.
///
/// # Panics
///
/// Panics if either prometheus exporter or opentelemetry meter fails to
/// initialize.
pub fn init_with_meter_builder(
name: &'static str,
meter_provider_builder: MeterProviderBuilderFn,
) {
*SERVICE_NAME.lock().unwrap() = Some(name);
*METER_PROVIDER_BUILDER_FN.lock().unwrap() = Some(meter_provider_builder);
Lazy::force(&METRICS_CORE);
}

/// Generates export data in Prometheus format, serialized into string.
pub fn export() -> Result<String, PrometheusError> {
let data = Self::get().registry.gather();
Expand Down