#[macro_export]
macro_rules! observable_setup {
(
service_name: $service_name:expr,
metrics_prefix: $metrics_prefix:expr,
otlp_endpoint: $otlp_endpoint:expr
$(, log_level: $log_level:expr)?
$(,)?
) => {{
#[allow(unused_imports)]
use $crate::logger::{Logger, TracingLogger};
let logger: ::std::sync::Arc<dyn Logger> = ::std::sync::Arc::new(TracingLogger::new());
logger.info(
"Initializing observability stack",
&[
("service", &$service_name),
("metrics_prefix", &$metrics_prefix),
],
);
#[cfg(feature = "opentelemetry")]
{
use ::opentelemetry::global;
use ::opentelemetry_otlp::{SpanExporter, WithExportConfig};
use ::opentelemetry_sdk::Resource;
use ::opentelemetry_sdk::trace::TracerProvider;
logger.info(
"Initializing OpenTelemetry tracer",
&[("endpoint", &$otlp_endpoint)],
);
let exporter = SpanExporter::builder()
.with_tonic()
.with_endpoint($otlp_endpoint)
.build()
.expect("Failed to create OTLP exporter");
let tracer_provider = TracerProvider::builder()
.with_batch_exporter(exporter, ::opentelemetry_sdk::runtime::Tokio)
.with_resource(Resource::new(vec![::opentelemetry::KeyValue::new(
"service.name",
$service_name,
)]))
.build();
global::set_tracer_provider(tracer_provider);
logger.info("OpenTelemetry tracer initialized", &[]);
}
#[cfg(feature = "prometheus")]
let metrics = {
let m = ::std::sync::Arc::new(
$crate::observability::prometheus::PrometheusMetrics::with_prefix($metrics_prefix)
.expect("Failed to create Prometheus metrics"),
);
#[cfg(all(target_os = "linux", feature = "prometheus"))]
{
let process_collector =
$crate::prometheus::process_collector::ProcessCollector::for_self();
m.registry()
.register(Box::new(process_collector))
.expect("Failed to register process collector");
logger.info("Prometheus metrics initialized with process collector", &[]);
}
#[cfg(not(target_os = "linux"))]
logger.info("Prometheus metrics initialized", &[]);
m
};
#[cfg(not(feature = "prometheus"))]
let metrics = ();
$crate::observability::macros::ObservabilityStack {
#[cfg(feature = "prometheus")]
metrics,
logger,
}
}};
(
metrics_prefix: $metrics_prefix:expr
$(,)?
) => {{
#[allow(unused_imports)]
use $crate::logger::{Logger, TracingLogger};
let logger: ::std::sync::Arc<dyn Logger> = ::std::sync::Arc::new(TracingLogger::new());
logger.info(
"Initializing observability stack",
&[("metrics_prefix", &$metrics_prefix)],
);
#[cfg(feature = "prometheus")]
let metrics = {
let m = ::std::sync::Arc::new(
$crate::observability::prometheus::PrometheusMetrics::with_prefix($metrics_prefix)
.expect("Failed to create Prometheus metrics"),
);
#[cfg(all(target_os = "linux", feature = "prometheus"))]
{
let process_collector =
$crate::prometheus::process_collector::ProcessCollector::for_self();
m.registry()
.register(Box::new(process_collector))
.expect("Failed to register process collector");
logger.info("Prometheus metrics initialized with process collector", &[]);
}
#[cfg(not(target_os = "linux"))]
logger.info("Prometheus metrics initialized", &[]);
m
};
#[cfg(not(feature = "prometheus"))]
let metrics = ();
$crate::observability::macros::ObservabilityStack {
#[cfg(feature = "prometheus")]
metrics,
logger,
}
}};
(
service_name: $service_name:expr,
metrics_prefix: $metrics_prefix:expr
$(,)?
) => {{
#[allow(unused_imports)]
use $crate::logger::{Logger, TracingLogger};
let logger: ::std::sync::Arc<dyn Logger> = ::std::sync::Arc::new(TracingLogger::new());
logger.info(
"Initializing observability stack",
&[
("service", &$service_name),
("metrics_prefix", &$metrics_prefix),
],
);
#[cfg(feature = "prometheus")]
let metrics = {
let m = ::std::sync::Arc::new(
$crate::observability::prometheus::PrometheusMetrics::with_prefix($metrics_prefix)
.expect("Failed to create Prometheus metrics"),
);
#[cfg(all(target_os = "linux", feature = "prometheus"))]
{
let process_collector =
$crate::prometheus::process_collector::ProcessCollector::for_self();
m.registry()
.register(Box::new(process_collector))
.expect("Failed to register process collector");
logger.info("Prometheus metrics initialized with process collector", &[]);
}
#[cfg(not(target_os = "linux"))]
logger.info("Prometheus metrics initialized", &[]);
m
};
#[cfg(not(feature = "prometheus"))]
let metrics = ();
$crate::observability::macros::ObservabilityStack {
#[cfg(feature = "prometheus")]
metrics,
logger,
}
}};
}
pub struct ObservabilityStack {
#[cfg(feature = "prometheus")]
pub metrics: ::std::sync::Arc<super::prometheus::PrometheusMetrics>,
pub logger: ::std::sync::Arc<dyn crate::logger::Logger>,
}
impl ObservabilityStack {
#[cfg(feature = "prometheus")]
#[must_use]
pub fn metrics(&self) -> ::std::sync::Arc<super::prometheus::PrometheusMetrics> {
::std::sync::Arc::clone(&self.metrics)
}
#[must_use]
pub fn logger(&self) -> ::std::sync::Arc<dyn crate::logger::Logger> {
::std::sync::Arc::clone(&self.logger)
}
}