diff --git a/nym-node/src/logging.rs b/nym-node/src/logging.rs index 4852b68635..d0fb15b2d3 100644 --- a/nym-node/src/logging.rs +++ b/nym-node/src/logging.rs @@ -6,6 +6,20 @@ use tracing_subscriber::filter::Directive; use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::util::SubscriberInitExt; +// Signoz +use opentelemetry::trace::TracerProvider; +use opentelemetry::{global, KeyValue}; +use opentelemetry_otlp::tonic_types::metadata::MetadataMap; +use opentelemetry_otlp::tonic_types::transport::ClientTlsConfig; +use opentelemetry_otlp::{WithExportConfig, WithTonicConfig}; +use opentelemetry_sdk::metrics::{MeterProviderBuilder, PeriodicReader, SdkMeterProvider}; +use opentelemetry_sdk::trace::{RandomIdGenerator, SdkTracerProvider}; +use opentelemetry_sdk::{trace::Sampler, Resource}; +use opentelemetry_semantic_conventions::resource::{DEPLOYMENT_ENVIRONMENT_NAME, SERVICE_VERSION}; +use opentelemetry_semantic_conventions::SCHEMA_URL; +use tracing_core::Level; +use tracing_opentelemetry::{MetricsLayer, OpenTelemetryLayer}; + pub(crate) fn granual_filtered_env() -> anyhow::Result { fn directive_checked(directive: impl Into) -> anyhow::Result { directive.into().parse().map_err(From::from) @@ -13,7 +27,6 @@ pub(crate) fn granual_filtered_env() -> anyhow::Result anyhow::Result anyhow::Result { - Ok(tracing_subscriber::registry() + let key = std::env::var("SIGNOZ_INGESTION_KEY").expect("SIGNOZ_INGESTION_KEY not set"); + println!("SIGNOZ_INGESTION_KEY = {}", key); + let mut metadata = MetadataMap::new(); + metadata.insert( + "signoz-ingestion-key", + key.parse().expect("Could not parse key"), + ); + + let tracer_provider = init_tracer_provider(metadata)?; + let meter_provider = init_meter_provider()?; + let tracer = tracer_provider.tracer("tracing-otel-subscriber"); + + let registry = tracing_subscriber::registry() .with(default_tracing_fmt_layer(std::io::stderr)) - .with(granual_filtered_env()?)) + .with(granual_filtered_env()?) + .with(tracing_subscriber::filter::LevelFilter::from_level( + Level::DEBUG, + )) + .with(MetricsLayer::new(meter_provider)) + .with(OpenTelemetryLayer::new(tracer)); + + Ok(registry) } pub(crate) fn setup_tracing_logger() -> anyhow::Result<()> { build_tracing_logger()?.init(); - Ok(()) } + +// Signoz +fn resource() -> Resource { + Resource::builder() + .with_service_name("nym-node") + .with_schema_url( + [ + KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")), + KeyValue::new(DEPLOYMENT_ENVIRONMENT_NAME, "develop"), + ], + SCHEMA_URL, + ) + .build() +} + +fn init_tracer_provider(metadata: MetadataMap) -> anyhow::Result { + let endpoint = std::env::var("SIGNOZ_ENDPOINT").expect("SIGNOZ_ENDPOINT not set"); + println!("SIGNOZ_ENDPOINT = {}", endpoint); + + let mut exporter_builder = opentelemetry_otlp::SpanExporter::builder() + .with_tonic() + .with_metadata(metadata) + .with_endpoint(&endpoint); + + if endpoint.starts_with("https://") { + exporter_builder = + exporter_builder.with_tls_config(ClientTlsConfig::new().with_enabled_roots()); + } + + let exporter = exporter_builder.build()?; + + let tracer = SdkTracerProvider::builder() + .with_sampler(Sampler::ParentBased(Box::new(Sampler::TraceIdRatioBased( + 1.0, + )))) + .with_id_generator(RandomIdGenerator::default()) + .with_resource(resource()) + .with_batch_exporter(exporter) + .build(); + + Ok(tracer) +} + +fn init_meter_provider() -> anyhow::Result { + let exporter = opentelemetry_otlp::MetricExporter::builder() + .with_tonic() + .with_temporality(opentelemetry_sdk::metrics::Temporality::default()) + .build()?; + + let reader = PeriodicReader::builder(exporter) + .with_interval(std::time::Duration::from_secs(30)) + .build(); + + let stdout_reader = + PeriodicReader::builder(opentelemetry_stdout::MetricExporter::default()).build(); + + let meter_provider = MeterProviderBuilder::default() + .with_resource(resource()) + .with_reader(reader) + .with_reader(stdout_reader) + .build(); + + global::set_meter_provider(meter_provider.clone()); + + Ok(meter_provider) +} diff --git a/nym-node/src/node/mod.rs b/nym-node/src/node/mod.rs index 5df5abce4d..c240686b8a 100644 --- a/nym-node/src/node/mod.rs +++ b/nym-node/src/node/mod.rs @@ -69,23 +69,6 @@ use tokio::sync::mpsc; use tracing::{debug, info, trace}; use zeroize::Zeroizing; -// signoz -use opentelemetry::trace::TracerProvider; -use opentelemetry::{global, KeyValue}; -use opentelemetry_otlp::tonic_types::metadata::MetadataMap; -use opentelemetry_otlp::tonic_types::transport::ClientTlsConfig; -use opentelemetry_otlp::{WithExportConfig, WithTonicConfig}; -use opentelemetry_sdk::metrics::{MeterProviderBuilder, PeriodicReader, SdkMeterProvider}; -use opentelemetry_sdk::trace::{RandomIdGenerator, SdkTracerProvider}; -use opentelemetry_sdk::{trace::Sampler, Resource}; -use opentelemetry_semantic_conventions::{ - attribute::{DEPLOYMENT_ENVIRONMENT_NAME, SERVICE_VERSION}, - SCHEMA_URL, -}; -use tracing_core::Level; -use tracing_opentelemetry::{MetricsLayer, OpenTelemetryLayer}; -use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; - pub mod bonding_information; pub mod description; pub mod helpers; @@ -1213,15 +1196,6 @@ impl NymNode { } pub(crate) async fn run(mut self) -> Result<(), NymNodeError> { - let key = std::env::var("SIGNOZ_INGESTION_KEY").expect("SIGNOZ_INGESTION_KEY not set"); - println!("SIGNOZ_INGESTION_KEY = {}", key); - let mut metadata = MetadataMap::new(); - metadata.insert( - "signoz-ingestion-key", - key.parse().expect("Could not parse key"), - ); - let _guard = init_tracing_subscriber(metadata); - let mut shutdown_signals = self.shutdown_manager.detach_shutdown_signals(); // listen for shutdown signal in case we received it when attempting to spawn all the tasks @@ -1241,118 +1215,3 @@ impl NymNode { Ok(()) } } - -fn resource() -> Resource { - Resource::builder() - .with_service_name("sdk-example-surb-reply") - .with_schema_url( - [ - KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")), - KeyValue::new(DEPLOYMENT_ENVIRONMENT_NAME, "develop"), - ], - SCHEMA_URL, - ) - .build() -} - -fn init_tracer_provider(metadata: MetadataMap) -> anyhow::Result { - let endpoint = std::env::var("SIGNOZ_ENDPOINT").expect("SIGNOZ_ENDPOINT not set"); - println!("SIGNOZ_ENDPOINT = {}", endpoint); - - // Configure OTLP exporter with metadata - let mut exporter_builder = opentelemetry_otlp::SpanExporter::builder() - .with_tonic() - .with_metadata(metadata) - .with_endpoint(&endpoint); - - // Try with TLS - seems to work - if endpoint.starts_with("https://") { - exporter_builder = - exporter_builder.with_tls_config(ClientTlsConfig::new().with_enabled_roots()); - } - - let exporter = exporter_builder.build()?; - - let tracer = SdkTracerProvider::builder() - // Customize sampling strategy - .with_sampler(Sampler::ParentBased(Box::new(Sampler::TraceIdRatioBased( - 1.0, - )))) - // If export trace to AWS X-Ray, you can use XrayIdGenerator - .with_id_generator(RandomIdGenerator::default()) - .with_resource(resource()) - .with_batch_exporter(exporter) - .build(); - - Ok(tracer) -} - -fn init_meter_provider() -> SdkMeterProvider { - let exporter = opentelemetry_otlp::MetricExporter::builder() - .with_tonic() - .with_temporality(opentelemetry_sdk::metrics::Temporality::default()) - .build() - .unwrap(); - - let reader = PeriodicReader::builder(exporter) - .with_interval(std::time::Duration::from_secs(30)) - .build(); - - // For debugging in development - let stdout_reader = - PeriodicReader::builder(opentelemetry_stdout::MetricExporter::default()).build(); - - let meter_provider = MeterProviderBuilder::default() - .with_resource(resource()) - .with_reader(reader) - .with_reader(stdout_reader) - .build(); - - global::set_meter_provider(meter_provider.clone()); - - meter_provider -} - -fn init_tracing_subscriber(metadata: MetadataMap) -> OtelGuard { - let tracer_provider = init_tracer_provider(metadata).expect("Initializing tracer failed"); - let meter_provider = init_meter_provider(); - - let tracer = tracer_provider.tracer("tracing-otel-subscriber"); - - tracing_subscriber::registry() - // The global level filter prevents the exporter network stack - // from reentering the globally installed OpenTelemetryLayer with - // its own spans while exporting, as the libraries should not use - // tracing levels below DEBUG. If the OpenTelemetry layer needs to - // trace spans and events with higher verbosity levels, consider using - // per-layer filtering to target the telemetry layer specifically, - // e.g. by target matching. - .with(tracing_subscriber::filter::LevelFilter::from_level( - Level::DEBUG, - )) - .with(tracing_subscriber::fmt::layer()) - .with(MetricsLayer::new(meter_provider.clone())) - .with(OpenTelemetryLayer::new(tracer)) - .init(); - - OtelGuard { - tracer_provider, - meter_provider, - } -} - -struct OtelGuard { - tracer_provider: SdkTracerProvider, - meter_provider: SdkMeterProvider, -} - -impl Drop for OtelGuard { - fn drop(&mut self) { - if let Err(err) = self.tracer_provider.shutdown() { - eprintln!("{err:?}"); - } - if let Err(err) = self.meter_provider.shutdown() { - eprintln!("{err:?}"); - } - } -}