From d3b1c47e1aa3b96edaec0297ccb86ec7668bc0c0 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 24 Oct 2024 13:41:41 -0700 Subject: [PATCH 1/5] Global error handler cleanup - MeterProvider (#2237) --- .../src/metrics/meter_provider.rs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/opentelemetry-sdk/src/metrics/meter_provider.rs b/opentelemetry-sdk/src/metrics/meter_provider.rs index 591be34165..c91773434b 100644 --- a/opentelemetry-sdk/src/metrics/meter_provider.rs +++ b/opentelemetry-sdk/src/metrics/meter_provider.rs @@ -8,9 +8,8 @@ use std::{ }; use opentelemetry::{ - global, metrics::{Meter, MeterProvider, MetricsError, Result}, - KeyValue, + otel_debug, otel_error, KeyValue, }; use crate::{instrumentation::Scope, Resource}; @@ -137,13 +136,21 @@ impl Drop for SdkMeterProviderInner { fn drop(&mut self) { // If user has already shutdown the provider manually by calling // shutdown(), then we don't need to call shutdown again. - if !self.is_shutdown.load(Ordering::Relaxed) { - if let Err(err) = self.shutdown() { - global::handle_error(err); - } + if self.is_shutdown.load(Ordering::Relaxed) { + otel_debug!( + name: "MeterProvider.AlreadyShutdown", + message = "Meter provider was already shut down; drop will not attempt shutdown again." + ); + } else if let Err(err) = self.shutdown() { + otel_error!( + name: "MeterProvider.ShutdownFailed", + message = "Shutdown attempt failed during drop of MeterProvider.", + reason = format!("{}", err) + ); } } } + impl MeterProvider for SdkMeterProvider { fn versioned_meter( &self, From a18853e47afa9afe0d9e176bd352bd1926f96486 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 24 Oct 2024 13:43:46 -0700 Subject: [PATCH 2/5] Global error handler cleanup - exponential histogram (#2235) Co-authored-by: Zhongyang Wu Co-authored-by: Cijo Thomas --- .../metrics/internal/exponential_histogram.rs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/opentelemetry-sdk/src/metrics/internal/exponential_histogram.rs b/opentelemetry-sdk/src/metrics/internal/exponential_histogram.rs index c23b441663..e85e0ece55 100644 --- a/opentelemetry-sdk/src/metrics/internal/exponential_histogram.rs +++ b/opentelemetry-sdk/src/metrics/internal/exponential_histogram.rs @@ -1,7 +1,7 @@ use std::{collections::HashMap, f64::consts::LOG2_E, sync::Mutex, time::SystemTime}; use once_cell::sync::Lazy; -use opentelemetry::{metrics::MetricsError, KeyValue}; +use opentelemetry::{otel_debug, KeyValue}; use crate::{ metrics::data::{self, Aggregation, Temporality}, @@ -100,9 +100,18 @@ impl ExpoHistogramDataPoint { if (self.scale - scale_delta as i8) < EXPO_MIN_SCALE { // With a scale of -10 there is only two buckets for the whole range of f64 values. // This can only happen if there is a max size of 1. - opentelemetry::global::handle_error(MetricsError::Other( - "exponential histogram scale underflow".into(), - )); + + // TODO - to check if this should be logged as an error if this is auto-recoverable. + otel_debug!( + name: "ExponentialHistogramDataPoint.Scale.Underflow", + current_scale = self.scale, + scale_delta = scale_delta, + max_size = self.max_size, + min_scale = EXPO_MIN_SCALE, + value = format!("{:?}", v), + message = "The measurement will be dropped due to scale underflow. Check the histogram configuration" + ); + return; } // Downscale From 5628f66395e737d3085c6f4ab6ed4cffee8a4194 Mon Sep 17 00:00:00 2001 From: Jialun Cai Date: Fri, 25 Oct 2024 12:34:40 +0800 Subject: [PATCH 3/5] Exclude benchmark setup duration using iter_batched (#2233) --- opentelemetry-sdk/benches/metrics_counter.rs | 112 ++++++++++--------- 1 file changed, 61 insertions(+), 51 deletions(-) diff --git a/opentelemetry-sdk/benches/metrics_counter.rs b/opentelemetry-sdk/benches/metrics_counter.rs index 24a4403266..8361c423ef 100644 --- a/opentelemetry-sdk/benches/metrics_counter.rs +++ b/opentelemetry-sdk/benches/metrics_counter.rs @@ -12,7 +12,7 @@ | ThreadLocal_Random_Generator_5 | 37 ns | */ -use criterion::{criterion_group, criterion_main, Criterion}; +use criterion::{criterion_group, criterion_main, BatchSize, Criterion}; use opentelemetry::{ metrics::{Counter, MeterProvider as _}, KeyValue, @@ -57,62 +57,72 @@ fn criterion_benchmark(c: &mut Criterion) { fn counter_add_sorted(c: &mut Criterion) { let counter = create_counter("Counter_Add_Sorted"); c.bench_function("Counter_Add_Sorted", |b| { - b.iter(|| { - // 4*4*10*10 = 1600 time series. - let rands = CURRENT_RNG.with(|rng| { - let mut rng = rng.borrow_mut(); - [ - rng.gen_range(0..4), - rng.gen_range(0..4), - rng.gen_range(0..10), - rng.gen_range(0..10), - ] - }); - let index_first_attribute = rands[0]; - let index_second_attribute = rands[1]; - let index_third_attribute = rands[2]; - let index_fourth_attribute = rands[3]; - counter.add( - 1, - &[ - KeyValue::new("attribute1", ATTRIBUTE_VALUES[index_first_attribute]), - KeyValue::new("attribute2", ATTRIBUTE_VALUES[index_second_attribute]), - KeyValue::new("attribute3", ATTRIBUTE_VALUES[index_third_attribute]), - KeyValue::new("attribute4", ATTRIBUTE_VALUES[index_fourth_attribute]), - ], - ); - }); + b.iter_batched( + || { + // 4*4*10*10 = 1600 time series. + CURRENT_RNG.with(|rng| { + let mut rng = rng.borrow_mut(); + [ + rng.gen_range(0..4), + rng.gen_range(0..4), + rng.gen_range(0..10), + rng.gen_range(0..10), + ] + }) + }, + |rands| { + let index_first_attribute = rands[0]; + let index_second_attribute = rands[1]; + let index_third_attribute = rands[2]; + let index_fourth_attribute = rands[3]; + counter.add( + 1, + &[ + KeyValue::new("attribute1", ATTRIBUTE_VALUES[index_first_attribute]), + KeyValue::new("attribute2", ATTRIBUTE_VALUES[index_second_attribute]), + KeyValue::new("attribute3", ATTRIBUTE_VALUES[index_third_attribute]), + KeyValue::new("attribute4", ATTRIBUTE_VALUES[index_fourth_attribute]), + ], + ); + }, + BatchSize::SmallInput, + ); }); } fn counter_add_unsorted(c: &mut Criterion) { let counter = create_counter("Counter_Add_Unsorted"); c.bench_function("Counter_Add_Unsorted", |b| { - b.iter(|| { - // 4*4*10*10 = 1600 time series. - let rands = CURRENT_RNG.with(|rng| { - let mut rng = rng.borrow_mut(); - [ - rng.gen_range(0..4), - rng.gen_range(0..4), - rng.gen_range(0..10), - rng.gen_range(0..10), - ] - }); - let index_first_attribute = rands[0]; - let index_second_attribute = rands[1]; - let index_third_attribute = rands[2]; - let index_fourth_attribute = rands[3]; - counter.add( - 1, - &[ - KeyValue::new("attribute2", ATTRIBUTE_VALUES[index_second_attribute]), - KeyValue::new("attribute3", ATTRIBUTE_VALUES[index_third_attribute]), - KeyValue::new("attribute1", ATTRIBUTE_VALUES[index_first_attribute]), - KeyValue::new("attribute4", ATTRIBUTE_VALUES[index_fourth_attribute]), - ], - ); - }); + b.iter_batched( + || { + // 4*4*10*10 = 1600 time series. + CURRENT_RNG.with(|rng| { + let mut rng = rng.borrow_mut(); + [ + rng.gen_range(0..4), + rng.gen_range(0..4), + rng.gen_range(0..10), + rng.gen_range(0..10), + ] + }) + }, + |rands| { + let index_first_attribute = rands[0]; + let index_second_attribute = rands[1]; + let index_third_attribute = rands[2]; + let index_fourth_attribute = rands[3]; + counter.add( + 1, + &[ + KeyValue::new("attribute2", ATTRIBUTE_VALUES[index_second_attribute]), + KeyValue::new("attribute3", ATTRIBUTE_VALUES[index_third_attribute]), + KeyValue::new("attribute1", ATTRIBUTE_VALUES[index_first_attribute]), + KeyValue::new("attribute4", ATTRIBUTE_VALUES[index_fourth_attribute]), + ], + ); + }, + BatchSize::SmallInput, + ); }); } From e2db7a0a3749dd623d7bf4a46447edc50030fb7b Mon Sep 17 00:00:00 2001 From: stormshield-fabs <161044609+stormshield-fabs@users.noreply.github.com> Date: Fri, 25 Oct 2024 06:55:24 +0200 Subject: [PATCH 4/5] Unify builders across signals (#2220) Co-authored-by: Lalit Kumar Bhasin Co-authored-by: Lalit Kumar Bhasin Co-authored-by: Cijo Thomas --- opentelemetry-appender-log/src/lib.rs | 12 +- .../benches/logs.rs | 4 +- opentelemetry-appender-tracing/src/layer.rs | 11 +- .../examples/basic-otlp-http/src/main.rs | 19 +-- .../examples/basic-otlp/src/main.rs | 24 ++- .../expected/serialized_traces.json | 39 +---- opentelemetry-proto/src/transform/common.rs | 8 +- opentelemetry-proto/src/transform/logs.rs | 12 +- opentelemetry-proto/src/transform/trace.rs | 15 +- opentelemetry-sdk/CHANGELOG.md | 6 + .../benches/batch_span_processor.rs | 2 +- opentelemetry-sdk/benches/log.rs | 4 +- opentelemetry-sdk/benches/log_exporter.rs | 10 +- opentelemetry-sdk/benches/log_processor.rs | 18 ++- opentelemetry-sdk/src/export/logs/mod.rs | 36 +++-- opentelemetry-sdk/src/export/trace.rs | 6 +- opentelemetry-sdk/src/instrumentation.rs | 5 - opentelemetry-sdk/src/lib.rs | 3 +- opentelemetry-sdk/src/logs/log_emitter.rs | 76 ++++------ opentelemetry-sdk/src/logs/log_processor.rs | 51 ++++--- opentelemetry-sdk/src/logs/mod.rs | 37 +---- opentelemetry-sdk/src/metrics/data/mod.rs | 10 +- opentelemetry-sdk/src/metrics/instrument.rs | 13 +- opentelemetry-sdk/src/metrics/meter.rs | 7 +- .../src/metrics/meter_provider.rs | 78 +++++----- opentelemetry-sdk/src/metrics/mod.rs | 26 ++-- opentelemetry-sdk/src/metrics/pipeline.rs | 9 +- .../src/testing/logs/in_memory_exporter.rs | 8 +- .../src/testing/trace/span_exporters.rs | 8 +- opentelemetry-sdk/src/trace/mod.rs | 39 ++--- opentelemetry-sdk/src/trace/provider.rs | 48 ++---- opentelemetry-sdk/src/trace/span.rs | 2 +- opentelemetry-sdk/src/trace/span_processor.rs | 2 +- opentelemetry-sdk/src/trace/tracer.rs | 36 ++--- opentelemetry-stdout/examples/basic.rs | 11 +- opentelemetry-stdout/src/common.rs | 4 +- opentelemetry-stdout/src/trace/exporter.rs | 8 +- opentelemetry-zipkin/src/exporter/mod.rs | 22 +-- .../src/exporter/model/mod.rs | 4 +- .../src/exporter/model/span.rs | 2 +- opentelemetry/CHANGELOG.md | 9 ++ opentelemetry/src/common.rs | 77 ++++------ opentelemetry/src/global/metrics.rs | 36 ++--- opentelemetry/src/global/mod.rs | 15 +- opentelemetry/src/global/trace.rs | 45 ++++-- opentelemetry/src/lib.rs | 2 +- opentelemetry/src/logs/logger.rs | 113 ++------------- opentelemetry/src/logs/noop.rs | 16 +- opentelemetry/src/metrics/meter.rs | 48 +++--- opentelemetry/src/metrics/noop.rs | 8 +- opentelemetry/src/trace/mod.rs | 12 +- opentelemetry/src/trace/noop.rs | 6 +- opentelemetry/src/trace/tracer_provider.rs | 137 ++---------------- stress/src/logs.rs | 4 +- 54 files changed, 457 insertions(+), 806 deletions(-) delete mode 100644 opentelemetry-sdk/src/instrumentation.rs diff --git a/opentelemetry-appender-log/src/lib.rs b/opentelemetry-appender-log/src/lib.rs index f20b5f65ff..0fe09acde3 100644 --- a/opentelemetry-appender-log/src/lib.rs +++ b/opentelemetry-appender-log/src/lib.rs @@ -97,11 +97,10 @@ use log::{Level, Metadata, Record}; use opentelemetry::{ logs::{AnyValue, LogRecord, Logger, LoggerProvider, Severity}, - Key, + InstrumentationScope, Key, }; #[cfg(feature = "experimental_metadata_attributes")] use opentelemetry_semantic_conventions::attribute::{CODE_FILEPATH, CODE_LINENO, CODE_NAMESPACE}; -use std::borrow::Cow; pub struct OpenTelemetryLogBridge where @@ -170,11 +169,12 @@ where L: Logger + Send + Sync, { pub fn new(provider: &P) -> Self { + let scope = InstrumentationScope::builder("opentelemetry-log-appender") + .with_version(env!("CARGO_PKG_VERSION")) + .build(); + OpenTelemetryLogBridge { - logger: provider - .logger_builder("opentelemetry-log-appender") - .with_version(Cow::Borrowed(env!("CARGO_PKG_VERSION"))) - .build(), + logger: provider.logger_with_scope(scope), _phantom: Default::default(), } } diff --git a/opentelemetry-appender-tracing/benches/logs.rs b/opentelemetry-appender-tracing/benches/logs.rs index a5ebb83249..0237e4a769 100644 --- a/opentelemetry-appender-tracing/benches/logs.rs +++ b/opentelemetry-appender-tracing/benches/logs.rs @@ -16,7 +16,7 @@ use async_trait::async_trait; use criterion::{criterion_group, criterion_main, Criterion}; use opentelemetry::logs::LogResult; -use opentelemetry::{InstrumentationLibrary, KeyValue}; +use opentelemetry::{InstrumentationScope, KeyValue}; use opentelemetry_appender_tracing::layer as tracing_layer; use opentelemetry_sdk::export::logs::{LogBatch, LogExporter}; use opentelemetry_sdk::logs::{LogProcessor, LogRecord, LoggerProvider}; @@ -55,7 +55,7 @@ impl NoopProcessor { } impl LogProcessor for NoopProcessor { - fn emit(&self, _: &mut LogRecord, _: &InstrumentationLibrary) { + fn emit(&self, _: &mut LogRecord, _: &InstrumentationScope) { // no-op } diff --git a/opentelemetry-appender-tracing/src/layer.rs b/opentelemetry-appender-tracing/src/layer.rs index fbbf8e4d97..0408eec64c 100644 --- a/opentelemetry-appender-tracing/src/layer.rs +++ b/opentelemetry-appender-tracing/src/layer.rs @@ -1,6 +1,6 @@ use opentelemetry::{ logs::{AnyValue, LogRecord, Logger, LoggerProvider, Severity}, - Key, + InstrumentationScope, Key, }; use std::borrow::Cow; use tracing_core::Level; @@ -136,11 +136,12 @@ where L: Logger + Send + Sync, { pub fn new(provider: &P) -> Self { + let scope = InstrumentationScope::builder(INSTRUMENTATION_LIBRARY_NAME) + .with_version(Cow::Borrowed(env!("CARGO_PKG_VERSION"))) + .build(); + OpenTelemetryTracingBridge { - logger: provider - .logger_builder(INSTRUMENTATION_LIBRARY_NAME) - .with_version(Cow::Borrowed(env!("CARGO_PKG_VERSION"))) - .build(), + logger: provider.logger_with_scope(scope), _phantom: Default::default(), } } diff --git a/opentelemetry-otlp/examples/basic-otlp-http/src/main.rs b/opentelemetry-otlp/examples/basic-otlp-http/src/main.rs index 387cf6e7c9..029efaaa30 100644 --- a/opentelemetry-otlp/examples/basic-otlp-http/src/main.rs +++ b/opentelemetry-otlp/examples/basic-otlp-http/src/main.rs @@ -2,8 +2,8 @@ use once_cell::sync::Lazy; use opentelemetry::{ global, metrics::MetricsError, - trace::{TraceContextExt, TraceError, Tracer, TracerProvider as _}, - KeyValue, + trace::{TraceContextExt, TraceError, Tracer}, + InstrumentationScope, KeyValue, }; use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge; use opentelemetry_otlp::WithExportConfig; @@ -128,16 +128,13 @@ async fn main() -> Result<(), Box> { .init(); let common_scope_attributes = vec![KeyValue::new("scope-key", "scope-value")]; - let tracer = global::tracer_provider() - .tracer_builder("basic") - .with_attributes(common_scope_attributes.clone()) + let scope = InstrumentationScope::builder("basic") + .with_version("1.0") + .with_attributes(common_scope_attributes) .build(); - let meter = global::meter_with_version( - "basic", - Some("v1.0"), - Some("schema_url"), - Some(common_scope_attributes.clone()), - ); + + let tracer = global::tracer_with_scope(scope.clone()); + let meter = global::meter_with_scope(scope); let counter = meter .u64_counter("test_counter") diff --git a/opentelemetry-otlp/examples/basic-otlp/src/main.rs b/opentelemetry-otlp/examples/basic-otlp/src/main.rs index 8da8dff7f2..60f2922a35 100644 --- a/opentelemetry-otlp/examples/basic-otlp/src/main.rs +++ b/opentelemetry-otlp/examples/basic-otlp/src/main.rs @@ -1,12 +1,9 @@ use once_cell::sync::Lazy; -use opentelemetry::global; use opentelemetry::logs::LogError; use opentelemetry::metrics::MetricsError; -use opentelemetry::trace::{TraceError, TracerProvider}; -use opentelemetry::{ - trace::{TraceContextExt, Tracer}, - KeyValue, -}; +use opentelemetry::trace::{TraceContextExt, TraceError, Tracer}; +use opentelemetry::KeyValue; +use opentelemetry::{global, InstrumentationScope}; use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge; use opentelemetry_otlp::{LogExporter, MetricsExporter, SpanExporter, WithExportConfig}; use opentelemetry_sdk::logs::LoggerProvider; @@ -108,16 +105,13 @@ async fn main() -> Result<(), Box> { .init(); let common_scope_attributes = vec![KeyValue::new("scope-key", "scope-value")]; - let tracer = global::tracer_provider() - .tracer_builder("basic") - .with_attributes(common_scope_attributes.clone()) + let scope = InstrumentationScope::builder("basic") + .with_version("1.0") + .with_attributes(common_scope_attributes) .build(); - let meter = global::meter_with_version( - "basic", - Some("v1.0"), - Some("schema_url"), - Some(common_scope_attributes.clone()), - ); + + let tracer = global::tracer_with_scope(scope.clone()); + let meter = global::meter_with_scope(scope); let counter = meter .u64_counter("test_counter") diff --git a/opentelemetry-otlp/tests/integration_test/expected/serialized_traces.json b/opentelemetry-otlp/tests/integration_test/expected/serialized_traces.json index e5982877cf..f1d64108ad 100644 --- a/opentelemetry-otlp/tests/integration_test/expected/serialized_traces.json +++ b/opentelemetry-otlp/tests/integration_test/expected/serialized_traces.json @@ -26,7 +26,7 @@ "spanId": "cd7cf7bf939930b7", "traceState": "", "parentSpanId": "d58cf2d702a061e0", - "flags": 0, + "flags": 1, "name": "Sub operation...", "kind": 1, "startTimeUnixNano": "1703985537070566698", @@ -55,40 +55,13 @@ "message": "", "code": 0 } - } - ], - "schemaUrl": "" - } - ], - "schemaUrl": "" - }, - { - "resource": { - "attributes": [ - { - "key": "service.name", - "value": { - "stringValue": "basic-otlp-tracing-example" - } - } - ], - "droppedAttributesCount": 0 - }, - "scopeSpans": [ - { - "scope": { - "name": "ex.com/basic", - "version": "", - "attributes": [], - "droppedAttributesCount": 0 - }, - "spans": [ + }, { "traceId": "9b458af7378cba65253d7042d34fc72e", "spanId": "d58cf2d702a061e0", "traceState": "", "parentSpanId": "", - "flags": 0, + "flags": 1, "name": "operation", "kind": 1, "startTimeUnixNano": "1703985537070558635", @@ -112,12 +85,6 @@ "value": { "intValue": "100" } - }, - { - "key": "number/int", - "value": { - "intValue": "100" - } } ], "droppedAttributesCount": 0 diff --git a/opentelemetry-proto/src/transform/common.rs b/opentelemetry-proto/src/transform/common.rs index c37a3dbec1..0821165c89 100644 --- a/opentelemetry-proto/src/transform/common.rs +++ b/opentelemetry-proto/src/transform/common.rs @@ -44,13 +44,13 @@ pub mod tonic { impl From<( - opentelemetry_sdk::InstrumentationLibrary, + opentelemetry::InstrumentationScope, Option>, )> for InstrumentationScope { fn from( data: ( - opentelemetry_sdk::InstrumentationLibrary, + opentelemetry::InstrumentationScope, Option>, ), ) -> Self { @@ -75,13 +75,13 @@ pub mod tonic { impl From<( - &opentelemetry_sdk::InstrumentationLibrary, + &opentelemetry::InstrumentationScope, Option>, )> for InstrumentationScope { fn from( data: ( - &opentelemetry_sdk::InstrumentationLibrary, + &opentelemetry::InstrumentationScope, Option>, ), ) -> Self { diff --git a/opentelemetry-proto/src/transform/logs.rs b/opentelemetry-proto/src/transform/logs.rs index 48e100c60d..52fd3cace4 100644 --- a/opentelemetry-proto/src/transform/logs.rs +++ b/opentelemetry-proto/src/transform/logs.rs @@ -143,7 +143,7 @@ pub mod tonic { From<( ( &opentelemetry_sdk::logs::LogRecord, - &opentelemetry::InstrumentationLibrary, + &opentelemetry::InstrumentationScope, ), &ResourceAttributesWithSchema, )> for ResourceLogs @@ -152,7 +152,7 @@ pub mod tonic { data: ( ( &opentelemetry_sdk::logs::LogRecord, - &opentelemetry::InstrumentationLibrary, + &opentelemetry::InstrumentationScope, ), &ResourceAttributesWithSchema, ), @@ -189,7 +189,7 @@ pub mod tonic { Cow<'static, str>, Vec<( &opentelemetry_sdk::logs::LogRecord, - &opentelemetry::InstrumentationLibrary, + &opentelemetry::InstrumentationScope, )>, >, (log_record, instrumentation)| { @@ -235,19 +235,19 @@ pub mod tonic { mod tests { use crate::transform::common::tonic::ResourceAttributesWithSchema; use opentelemetry::logs::LogRecord as _; - use opentelemetry::InstrumentationLibrary; + use opentelemetry::InstrumentationScope; use opentelemetry_sdk::{export::logs::LogBatch, logs::LogRecord, Resource}; use std::time::SystemTime; fn create_test_log_data( instrumentation_name: &str, _message: &str, - ) -> (LogRecord, InstrumentationLibrary) { + ) -> (LogRecord, InstrumentationScope) { let mut logrecord = LogRecord::default(); logrecord.set_timestamp(SystemTime::now()); logrecord.set_observed_timestamp(SystemTime::now()); let instrumentation = - InstrumentationLibrary::builder(instrumentation_name.to_string()).build(); + InstrumentationScope::builder(instrumentation_name.to_string()).build(); (logrecord, instrumentation) } diff --git a/opentelemetry-proto/src/transform/trace.rs b/opentelemetry-proto/src/transform/trace.rs index 12871b33aa..27018d624a 100644 --- a/opentelemetry-proto/src/transform/trace.rs +++ b/opentelemetry-proto/src/transform/trace.rs @@ -101,12 +101,12 @@ pub mod tonic { schema_url: resource.schema_url.clone().unwrap_or_default(), scope_spans: vec![ScopeSpans { schema_url: source_span - .instrumentation_lib + .instrumentation_scope .schema_url .as_ref() .map(ToString::to_string) .unwrap_or_default(), - scope: Some((source_span.instrumentation_lib, None).into()), + scope: Some((source_span.instrumentation_scope, None).into()), spans: vec![Span { trace_id: source_span.span_context.trace_id().to_bytes().to_vec(), span_id: source_span.span_context.span_id().to_bytes().to_vec(), @@ -155,12 +155,11 @@ pub mod tonic { spans: Vec, resource: &ResourceAttributesWithSchema, ) -> Vec { - // Group spans by their instrumentation library + // Group spans by their instrumentation scope let scope_map = spans.iter().fold( HashMap::new(), - |mut scope_map: HashMap<&opentelemetry_sdk::InstrumentationLibrary, Vec<&SpanData>>, - span| { - let instrumentation = &span.instrumentation_lib; + |mut scope_map: HashMap<&opentelemetry::InstrumentationScope, Vec<&SpanData>>, span| { + let instrumentation = &span.instrumentation_scope; scope_map.entry(instrumentation).or_default().push(span); scope_map }, @@ -198,11 +197,11 @@ mod tests { use opentelemetry::trace::{ SpanContext, SpanId, SpanKind, Status, TraceFlags, TraceId, TraceState, }; + use opentelemetry::InstrumentationScope; use opentelemetry::KeyValue; use opentelemetry_sdk::export::trace::SpanData; use opentelemetry_sdk::resource::Resource; use opentelemetry_sdk::trace::{SpanEvents, SpanLinks}; - use opentelemetry_sdk::InstrumentationLibrary; use std::borrow::Cow; use std::time::{Duration, SystemTime}; @@ -227,7 +226,7 @@ mod tests { events: SpanEvents::default(), links: SpanLinks::default(), status: Status::Unset, - instrumentation_lib: InstrumentationLibrary::builder(instrumentation_name).build(), + instrumentation_scope: InstrumentationScope::builder(instrumentation_name).build(), } } diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index 515cd5633b..0841dc708c 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -19,6 +19,12 @@ Now: ```rust let counter = meter.u64_counter("my_counter").build(); ``` +- **BREAKING**: [#2220](https://github.com/open-telemetry/opentelemetry-rust/pull/2220) + - Removed `InstrumentationLibrary` re-export and its `Scope` alias, use `opentelemetry::InstrumentationLibrary` instead. + - Unified builders across signals + - Removed deprecated `LoggerProvider::versioned_logger`, `TracerProvider::versioned_tracer` + - Removed `MeterProvider::versioned_meter` + - Replaced these methods with `LoggerProvider::logger_with_scope`, `TracerProvider::logger_with_scope`, `MeterProvider::meter_with_scope` ## v0.26.0 Released 2024-Sep-30 diff --git a/opentelemetry-sdk/benches/batch_span_processor.rs b/opentelemetry-sdk/benches/batch_span_processor.rs index abc7d0df02..ed20c45a06 100644 --- a/opentelemetry-sdk/benches/batch_span_processor.rs +++ b/opentelemetry-sdk/benches/batch_span_processor.rs @@ -32,7 +32,7 @@ fn get_span_data() -> Vec { events: SpanEvents::default(), links: SpanLinks::default(), status: Status::Unset, - instrumentation_lib: Default::default(), + instrumentation_scope: Default::default(), }) .collect::>() } diff --git a/opentelemetry-sdk/benches/log.rs b/opentelemetry-sdk/benches/log.rs index 20d3503100..ca8a76a414 100644 --- a/opentelemetry-sdk/benches/log.rs +++ b/opentelemetry-sdk/benches/log.rs @@ -25,7 +25,7 @@ use opentelemetry::logs::{ }; use opentelemetry::trace::Tracer; use opentelemetry::trace::TracerProvider as _; -use opentelemetry::{InstrumentationLibrary, Key}; +use opentelemetry::{InstrumentationScope, Key}; use opentelemetry_sdk::logs::{LogProcessor, LogRecord, Logger, LoggerProvider}; use opentelemetry_sdk::trace; use opentelemetry_sdk::trace::{Sampler, TracerProvider}; @@ -34,7 +34,7 @@ use opentelemetry_sdk::trace::{Sampler, TracerProvider}; struct NoopProcessor; impl LogProcessor for NoopProcessor { - fn emit(&self, _data: &mut LogRecord, _library: &InstrumentationLibrary) {} + fn emit(&self, _data: &mut LogRecord, _scope: &InstrumentationScope) {} fn force_flush(&self) -> LogResult<()> { Ok(()) diff --git a/opentelemetry-sdk/benches/log_exporter.rs b/opentelemetry-sdk/benches/log_exporter.rs index 3549c08af5..c3c027f3e1 100644 --- a/opentelemetry-sdk/benches/log_exporter.rs +++ b/opentelemetry-sdk/benches/log_exporter.rs @@ -18,7 +18,7 @@ use criterion::{criterion_group, criterion_main, Criterion}; use opentelemetry::logs::{LogRecord as _, LogResult, Logger as _, LoggerProvider as _, Severity}; -use opentelemetry::InstrumentationLibrary; +use opentelemetry::InstrumentationScope; use opentelemetry_sdk::export::logs::LogBatch; use opentelemetry_sdk::logs::LogProcessor; use opentelemetry_sdk::logs::LogRecord; @@ -65,9 +65,9 @@ impl ExportingProcessorWithFuture { } impl LogProcessor for ExportingProcessorWithFuture { - fn emit(&self, record: &mut LogRecord, library: &InstrumentationLibrary) { + fn emit(&self, record: &mut LogRecord, scope: &InstrumentationScope) { let mut exporter = self.exporter.lock().expect("lock error"); - let logs = [(record as &LogRecord, library)]; + let logs = [(record as &LogRecord, scope)]; futures_executor::block_on(exporter.export(LogBatch::new(&logs))); } @@ -94,8 +94,8 @@ impl ExportingProcessorWithoutFuture { } impl LogProcessor for ExportingProcessorWithoutFuture { - fn emit(&self, record: &mut LogRecord, library: &InstrumentationLibrary) { - let logs = [(record as &LogRecord, library)]; + fn emit(&self, record: &mut LogRecord, scope: &InstrumentationScope) { + let logs = [(record as &LogRecord, scope)]; self.exporter .lock() .expect("lock error") diff --git a/opentelemetry-sdk/benches/log_processor.rs b/opentelemetry-sdk/benches/log_processor.rs index 1bc0a130b4..03cd71549c 100644 --- a/opentelemetry-sdk/benches/log_processor.rs +++ b/opentelemetry-sdk/benches/log_processor.rs @@ -18,8 +18,10 @@ use std::{ }; use criterion::{criterion_group, criterion_main, Criterion}; -use opentelemetry::logs::{LogRecord as _, LogResult, Logger as _, LoggerProvider as _, Severity}; -use opentelemetry::InstrumentationLibrary; +use opentelemetry::{ + logs::{LogRecord as _, LogResult, Logger as _, LoggerProvider as _, Severity}, + InstrumentationScope, +}; use opentelemetry_sdk::logs::{LogProcessor, LogRecord, Logger, LoggerProvider}; // Run this benchmark with: @@ -43,7 +45,7 @@ fn create_log_record(logger: &Logger) -> LogRecord { struct NoopProcessor; impl LogProcessor for NoopProcessor { - fn emit(&self, _data: &mut LogRecord, _library: &InstrumentationLibrary) {} + fn emit(&self, _data: &mut LogRecord, _scope: &InstrumentationScope) {} fn force_flush(&self) -> LogResult<()> { Ok(()) @@ -58,7 +60,7 @@ impl LogProcessor for NoopProcessor { struct CloningProcessor; impl LogProcessor for CloningProcessor { - fn emit(&self, data: &mut LogRecord, _library: &InstrumentationLibrary) { + fn emit(&self, data: &mut LogRecord, _scope: &InstrumentationScope) { let _data_cloned = data.clone(); } @@ -73,8 +75,8 @@ impl LogProcessor for CloningProcessor { #[derive(Debug)] struct SendToChannelProcessor { - sender: std::sync::mpsc::Sender<(LogRecord, InstrumentationLibrary)>, - receiver: Arc>>, + sender: std::sync::mpsc::Sender<(LogRecord, InstrumentationScope)>, + receiver: Arc>>, } impl SendToChannelProcessor { @@ -101,8 +103,8 @@ impl SendToChannelProcessor { } impl LogProcessor for SendToChannelProcessor { - fn emit(&self, record: &mut LogRecord, library: &InstrumentationLibrary) { - let res = self.sender.send((record.clone(), library.clone())); + fn emit(&self, record: &mut LogRecord, scope: &InstrumentationScope) { + let res = self.sender.send((record.clone(), scope.clone())); if res.is_err() { println!("Error sending log data to channel {0}", res.err().unwrap()); } diff --git a/opentelemetry-sdk/src/export/logs/mod.rs b/opentelemetry-sdk/src/export/logs/mod.rs index 8056f28222..2656544ce0 100644 --- a/opentelemetry-sdk/src/export/logs/mod.rs +++ b/opentelemetry-sdk/src/export/logs/mod.rs @@ -4,26 +4,24 @@ use crate::Resource; use async_trait::async_trait; #[cfg(feature = "logs_level_enabled")] use opentelemetry::logs::Severity; -use opentelemetry::{ - logs::{LogError, LogResult}, - InstrumentationLibrary, -}; +use opentelemetry::logs::{LogError, LogResult}; +use opentelemetry::InstrumentationScope; use std::fmt::Debug; /// A batch of log records to be exported by a `LogExporter`. /// /// The `LogBatch` struct holds a collection of log records along with their associated -/// instrumentation libraries. This structure is used to group log records together for efficient +/// instrumentation scopes. This structure is used to group log records together for efficient /// export operations. /// /// # Type Parameters -/// - `'a`: The lifetime of the references to the log records and instrumentation libraries. +/// - `'a`: The lifetime of the references to the log records and instrumentation scopes. /// #[derive(Debug)] pub struct LogBatch<'a> { /// The data field contains a slice of tuples, where each tuple consists of a reference to - /// a `LogRecord` and a reference to an `InstrumentationLibrary`. - data: &'a [(&'a LogRecord, &'a InstrumentationLibrary)], + /// a `LogRecord` and a reference to an `InstrumentationScope`. + data: &'a [(&'a LogRecord, &'a InstrumentationScope)], } impl<'a> LogBatch<'a> { @@ -32,32 +30,32 @@ impl<'a> LogBatch<'a> { /// # Arguments /// /// * `data` - A slice of tuples, where each tuple consists of a reference to a `LogRecord` - /// and a reference to an `InstrumentationLibrary`. These tuples represent the log records - /// and their associated instrumentation libraries to be exported. + /// and a reference to an `InstrumentationScope`. These tuples represent the log records + /// and their associated instrumentation scopes to be exported. /// /// # Returns /// - /// A `LogBatch` instance containing the provided log records and instrumentation libraries. + /// A `LogBatch` instance containing the provided log records and instrumentation scopes. /// /// Note - this is not a public function, and should not be used directly. This would be /// made private in the future. - pub fn new(data: &'a [(&'a LogRecord, &'a InstrumentationLibrary)]) -> LogBatch<'a> { + pub fn new(data: &'a [(&'a LogRecord, &'a InstrumentationScope)]) -> LogBatch<'a> { LogBatch { data } } } impl LogBatch<'_> { - /// Returns an iterator over the log records and instrumentation libraries in the batch. + /// Returns an iterator over the log records and instrumentation scopes in the batch. /// /// Each item yielded by the iterator is a tuple containing references to a `LogRecord` - /// and an `InstrumentationLibrary`. + /// and an `InstrumentationScope`. /// /// # Returns /// - /// An iterator that yields references to the `LogRecord` and `InstrumentationLibrary` in the batch. + /// An iterator that yields references to the `LogRecord` and `InstrumentationScope` in the batch. /// - pub fn iter(&self) -> impl Iterator { + pub fn iter(&self) -> impl Iterator { self.data .iter() .map(|(record, library)| (*record, *library)) @@ -67,16 +65,16 @@ impl LogBatch<'_> { /// `LogExporter` defines the interface that log exporters should implement. #[async_trait] pub trait LogExporter: Send + Sync + Debug { - /// Exports a batch of log records and their associated instrumentation libraries. + /// Exports a batch of log records and their associated instrumentation scopes. /// /// The `export` method is responsible for sending a batch of log records to an external /// destination. It takes a `LogBatch` as an argument, which contains references to the - /// log records and their corresponding instrumentation libraries. The method returns + /// log records and their corresponding instrumentation scopes. The method returns /// a `LogResult` indicating the success or failure of the export operation. /// /// # Arguments /// - /// * `batch` - A `LogBatch` containing the log records and instrumentation libraries + /// * `batch` - A `LogBatch` containing the log records and instrumentation scopes /// to be exported. /// /// # Returns diff --git a/opentelemetry-sdk/src/export/trace.rs b/opentelemetry-sdk/src/export/trace.rs index 4b43e00c36..c606d85b1a 100644 --- a/opentelemetry-sdk/src/export/trace.rs +++ b/opentelemetry-sdk/src/export/trace.rs @@ -2,7 +2,7 @@ use crate::Resource; use futures_util::future::BoxFuture; use opentelemetry::trace::{SpanContext, SpanId, SpanKind, Status, TraceError}; -use opentelemetry::KeyValue; +use opentelemetry::{InstrumentationScope, KeyValue}; use std::borrow::Cow; use std::fmt::Debug; use std::time::SystemTime; @@ -95,6 +95,6 @@ pub struct SpanData { pub links: crate::trace::SpanLinks, /// Span status pub status: Status, - /// Instrumentation library that produced this span - pub instrumentation_lib: crate::InstrumentationLibrary, + /// Instrumentation scope that produced this span + pub instrumentation_scope: InstrumentationScope, } diff --git a/opentelemetry-sdk/src/instrumentation.rs b/opentelemetry-sdk/src/instrumentation.rs deleted file mode 100644 index 75a74efa73..0000000000 --- a/opentelemetry-sdk/src/instrumentation.rs +++ /dev/null @@ -1,5 +0,0 @@ -pub use opentelemetry::InstrumentationLibrary; - -/// A logical unit of the application code with which the emitted telemetry can -/// be associated. -pub type Scope = InstrumentationLibrary; diff --git a/opentelemetry-sdk/src/lib.rs b/opentelemetry-sdk/src/lib.rs index 00df78fe3c..273cb183c8 100644 --- a/opentelemetry-sdk/src/lib.rs +++ b/opentelemetry-sdk/src/lib.rs @@ -122,7 +122,7 @@ pub mod export; pub(crate) mod growable_array; -mod instrumentation; + #[cfg(feature = "logs")] #[cfg_attr(docsrs, doc(cfg(feature = "logs")))] pub mod logs; @@ -146,6 +146,5 @@ pub mod trace; #[doc(hidden)] pub mod util; -pub use instrumentation::{InstrumentationLibrary, Scope}; #[doc(inline)] pub use resource::Resource; diff --git a/opentelemetry-sdk/src/logs/log_emitter.rs b/opentelemetry-sdk/src/logs/log_emitter.rs index 71b02dc158..1271f0ddd0 100644 --- a/opentelemetry-sdk/src/logs/log_emitter.rs +++ b/opentelemetry-sdk/src/logs/log_emitter.rs @@ -4,17 +4,20 @@ use opentelemetry::{ logs::{LogError, LogResult}, otel_debug, trace::TraceContextExt, - Context, InstrumentationLibrary, + Context, InstrumentationScope, }; #[cfg(feature = "logs_level_enabled")] use opentelemetry::logs::Severity; +use std::time::SystemTime; use std::{ borrow::Cow, - sync::{atomic::Ordering, Arc}, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, }; -use std::{sync::atomic::AtomicBool, time::SystemTime}; use once_cell::sync::Lazy; @@ -51,42 +54,23 @@ const DEFAULT_COMPONENT_NAME: &str = "rust.opentelemetry.io/sdk/logger"; impl opentelemetry::logs::LoggerProvider for LoggerProvider { type Logger = Logger; - /// Create a new versioned `Logger` instance. - fn versioned_logger( - &self, - name: impl Into>, - version: Option>, - schema_url: Option>, - attributes: Option>, - ) -> Logger { - let name = name.into(); - let component_name = if name.is_empty() { - Cow::Borrowed(DEFAULT_COMPONENT_NAME) - } else { - name - }; - - let mut builder = self.logger_builder(component_name); + fn logger(&self, name: impl Into>) -> Self::Logger { + let mut name = name.into(); - if let Some(v) = version { - builder = builder.with_version(v); - } - if let Some(s) = schema_url { - builder = builder.with_schema_url(s); - } - if let Some(a) = attributes { - builder = builder.with_attributes(a); - } + if name.is_empty() { + name = Cow::Borrowed(DEFAULT_COMPONENT_NAME) + }; - builder.build() + let scope = InstrumentationScope::builder(name).build(); + self.logger_with_scope(scope) } - fn library_logger(&self, library: Arc) -> Self::Logger { + fn logger_with_scope(&self, scope: InstrumentationScope) -> Self::Logger { // If the provider is shutdown, new logger will refer a no-op logger provider. if self.inner.is_shutdown.load(Ordering::Relaxed) { - return Logger::new(library, NOOP_LOGGER_PROVIDER.clone()); + return Logger::new(scope, NOOP_LOGGER_PROVIDER.clone()); } - Logger::new(library, self.clone()) + Logger::new(scope, self.clone()) } } @@ -250,19 +234,13 @@ impl Builder { /// /// [`LogRecord`]: opentelemetry::logs::LogRecord pub struct Logger { - instrumentation_lib: Arc, + scope: InstrumentationScope, provider: LoggerProvider, } impl Logger { - pub(crate) fn new( - instrumentation_lib: Arc, - provider: LoggerProvider, - ) -> Self { - Logger { - instrumentation_lib, - provider, - } + pub(crate) fn new(scope: InstrumentationScope, provider: LoggerProvider) -> Self { + Logger { scope, provider } } /// LoggerProvider associated with this logger. @@ -270,9 +248,9 @@ impl Logger { &self.provider } - /// Instrumentation library information of this logger. - pub fn instrumentation_library(&self) -> &InstrumentationLibrary { - &self.instrumentation_lib + /// Instrumentation scope of this logger. + pub fn instrumentation_scope(&self) -> &InstrumentationScope { + &self.scope } } @@ -304,7 +282,7 @@ impl opentelemetry::logs::Logger for Logger { } for p in processors { - p.emit(&mut record, self.instrumentation_library()); + p.emit(&mut record, self.instrumentation_scope()); } } @@ -318,7 +296,7 @@ impl opentelemetry::logs::Logger for Logger { || processor.event_enabled( level, target, - self.instrumentation_library().name.as_ref(), + self.instrumentation_scope().name.as_ref(), ); } enabled @@ -366,7 +344,7 @@ mod tests { } impl LogProcessor for ShutdownTestLogProcessor { - fn emit(&self, _data: &mut LogRecord, _library: &InstrumentationLibrary) { + fn emit(&self, _data: &mut LogRecord, _scope: &InstrumentationScope) { self.is_shutdown .lock() .map(|is_shutdown| { @@ -745,7 +723,7 @@ mod tests { } impl LogProcessor for LazyLogProcessor { - fn emit(&self, _data: &mut LogRecord, _library: &InstrumentationLibrary) { + fn emit(&self, _data: &mut LogRecord, _scope: &InstrumentationScope) { // nothing to do. } @@ -776,7 +754,7 @@ mod tests { } impl LogProcessor for CountingShutdownProcessor { - fn emit(&self, _data: &mut LogRecord, _library: &InstrumentationLibrary) { + fn emit(&self, _data: &mut LogRecord, _scope: &InstrumentationScope) { // nothing to do } diff --git a/opentelemetry-sdk/src/logs/log_processor.rs b/opentelemetry-sdk/src/logs/log_processor.rs index 47489881b0..b70ace08b3 100644 --- a/opentelemetry-sdk/src/logs/log_processor.rs +++ b/opentelemetry-sdk/src/logs/log_processor.rs @@ -13,7 +13,7 @@ use futures_util::{ use opentelemetry::logs::Severity; use opentelemetry::{ logs::{LogError, LogResult}, - otel_debug, otel_error, otel_warn, InstrumentationLibrary, + otel_debug, otel_error, otel_warn, InstrumentationScope, }; use std::sync::atomic::AtomicBool; @@ -56,8 +56,8 @@ pub trait LogProcessor: Send + Sync + Debug { /// /// # Parameters /// - `record`: A mutable reference to `LogData` representing the log record. - /// - `instrumentation`: The instrumentation library associated with the log record. - fn emit(&self, data: &mut LogRecord, instrumentation: &InstrumentationLibrary); + /// - `instrumentation`: The instrumentation scope associated with the log record. + fn emit(&self, data: &mut LogRecord, instrumentation: &InstrumentationScope); /// Force the logs lying in the cache to be exported. fn force_flush(&self) -> LogResult<()>; /// Shuts down the processor. @@ -95,7 +95,7 @@ impl SimpleLogProcessor { } impl LogProcessor for SimpleLogProcessor { - fn emit(&self, record: &mut LogRecord, instrumentation: &InstrumentationLibrary) { + fn emit(&self, record: &mut LogRecord, instrumentation: &InstrumentationScope) { // noop after shutdown if self.is_shutdown.load(std::sync::atomic::Ordering::Relaxed) { // this is a warning, as the user is trying to log after the processor has been shutdown @@ -168,7 +168,7 @@ impl Debug for BatchLogProcessor { } impl LogProcessor for BatchLogProcessor { - fn emit(&self, record: &mut LogRecord, instrumentation: &InstrumentationLibrary) { + fn emit(&self, record: &mut LogRecord, instrumentation: &InstrumentationScope) { let result = self.message_sender.try_send(BatchMessage::ExportLog(( record.clone(), instrumentation.clone(), @@ -320,7 +320,7 @@ async fn export_with_timeout( time_out: Duration, exporter: &mut E, runtime: &R, - batch: Vec<(LogRecord, InstrumentationLibrary)>, + batch: Vec<(LogRecord, InstrumentationScope)>, ) -> ExportResult where R: RuntimeChannel, @@ -331,7 +331,7 @@ where } // TBD - Can we avoid this conversion as it involves heap allocation with new vector? - let log_vec: Vec<(&LogRecord, &InstrumentationLibrary)> = batch + let log_vec: Vec<(&LogRecord, &InstrumentationScope)> = batch .iter() .map(|log_data| (&log_data.0, &log_data.1)) .collect(); @@ -515,7 +515,7 @@ where #[derive(Debug)] enum BatchMessage { /// Export logs, usually called when the log is emitted. - ExportLog((LogRecord, InstrumentationLibrary)), + ExportLog((LogRecord, InstrumentationScope)), /// Flush the current buffer to the backend, it can be triggered by /// pre configured interval or a call to `force_push` function. Flush(Option>), @@ -550,9 +550,8 @@ mod tests { use opentelemetry::logs::AnyValue; use opentelemetry::logs::LogRecord as _; use opentelemetry::logs::{Logger, LoggerProvider as _}; - use opentelemetry::InstrumentationLibrary; - use opentelemetry::Key; use opentelemetry::{logs::LogResult, KeyValue}; + use opentelemetry::{InstrumentationScope, Key}; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex}; use std::time::Duration; @@ -794,8 +793,8 @@ mod tests { runtime::Tokio, ); - let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let mut record = LogRecord::default(); + let instrumentation = InstrumentationScope::default(); processor.emit(&mut record, &instrumentation); processor.force_flush().unwrap(); @@ -813,7 +812,7 @@ mod tests { let processor = SimpleLogProcessor::new(Box::new(exporter.clone())); let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); processor.emit(&mut record, &instrumentation); @@ -883,11 +882,11 @@ mod tests { #[derive(Debug)] struct FirstProcessor { - pub(crate) logs: Arc>>, + pub(crate) logs: Arc>>, } impl LogProcessor for FirstProcessor { - fn emit(&self, record: &mut LogRecord, instrumentation: &InstrumentationLibrary) { + fn emit(&self, record: &mut LogRecord, instrumentation: &InstrumentationScope) { // add attribute record.add_attribute( Key::from_static_str("processed_by"), @@ -913,11 +912,11 @@ mod tests { #[derive(Debug)] struct SecondProcessor { - pub(crate) logs: Arc>>, + pub(crate) logs: Arc>>, } impl LogProcessor for SecondProcessor { - fn emit(&self, record: &mut LogRecord, instrumentation: &InstrumentationLibrary) { + fn emit(&self, record: &mut LogRecord, instrumentation: &InstrumentationScope) { assert!(record.attributes_contains( &Key::from_static_str("processed_by"), &AnyValue::String("FirstProcessor".into()) @@ -994,7 +993,7 @@ mod tests { let processor = SimpleLogProcessor::new(Box::new(exporter.clone())); let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); processor.emit(&mut record, &instrumentation); @@ -1007,7 +1006,7 @@ mod tests { let processor = SimpleLogProcessor::new(Box::new(exporter.clone())); let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); processor.emit(&mut record, &instrumentation); @@ -1024,7 +1023,7 @@ mod tests { let processor_clone = Arc::clone(&processor); let handle = tokio::spawn(async move { let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); processor_clone.emit(&mut record, &instrumentation); }); handles.push(handle); @@ -1043,7 +1042,7 @@ mod tests { let processor = SimpleLogProcessor::new(Box::new(exporter.clone())); let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); processor.emit(&mut record, &instrumentation); @@ -1090,7 +1089,7 @@ mod tests { let processor = SimpleLogProcessor::new(Box::new(exporter.clone())); let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); // This will panic because an tokio async operation within exporter without a runtime. processor.emit(&mut record, &instrumentation); @@ -1146,7 +1145,7 @@ mod tests { let processor_clone = Arc::clone(&processor); let handle = tokio::spawn(async move { let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); processor_clone.emit(&mut record, &instrumentation); }); handles.push(handle); @@ -1170,7 +1169,7 @@ mod tests { let processor = SimpleLogProcessor::new(Box::new(exporter.clone())); let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); processor.emit(&mut record, &instrumentation); @@ -1189,7 +1188,7 @@ mod tests { let processor = SimpleLogProcessor::new(Box::new(exporter.clone())); let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); processor.emit(&mut record, &instrumentation); @@ -1209,7 +1208,7 @@ mod tests { let processor = SimpleLogProcessor::new(Box::new(exporter.clone())); let mut record: LogRecord = Default::default(); - let instrumentation: InstrumentationLibrary = Default::default(); + let instrumentation: InstrumentationScope = Default::default(); processor.emit(&mut record, &instrumentation); diff --git a/opentelemetry-sdk/src/logs/mod.rs b/opentelemetry-sdk/src/logs/mod.rs index 59b1b9b338..c01ed8c626 100644 --- a/opentelemetry-sdk/src/logs/mod.rs +++ b/opentelemetry-sdk/src/logs/mod.rs @@ -8,16 +8,16 @@ pub use log_processor::{ BatchConfig, BatchConfigBuilder, BatchLogProcessor, BatchLogProcessorBuilder, LogProcessor, SimpleLogProcessor, }; +use opentelemetry::InstrumentationScope; pub use record::{LogRecord, TraceContext}; -use opentelemetry::InstrumentationLibrary; /// `LogData` represents a single log event without resource context. #[derive(Clone, Debug)] pub struct LogData { /// Log record pub record: LogRecord, /// Instrumentation details for the emitter who produced this `LogEvent`. - pub instrumentation: InstrumentationLibrary, + pub instrumentation: InstrumentationScope, } #[cfg(all(test, feature = "testing"))] @@ -104,38 +104,17 @@ mod tests { #[test] fn logger_attributes() { let provider = LoggerProvider::builder().build(); - let logger = provider - .logger_builder("test_logger") + let scope = InstrumentationScope::builder("test_logger") .with_schema_url("https://opentelemetry.io/schema/1.0.0") .with_attributes(vec![(KeyValue::new("test_k", "test_v"))]) .build(); - let instrumentation_library = logger.instrumentation_library(); - let attributes = &instrumentation_library.attributes; - assert_eq!(instrumentation_library.name, "test_logger"); - assert_eq!( - instrumentation_library.schema_url, - Some("https://opentelemetry.io/schema/1.0.0".into()) - ); - assert_eq!(attributes.len(), 1); - assert_eq!(attributes[0].key, "test_k".into()); - assert_eq!(attributes[0].value, "test_v".into()); - } - #[test] - #[allow(deprecated)] - fn versioned_logger_options() { - let provider = LoggerProvider::builder().build(); - let logger = provider.versioned_logger( - "test_logger", - Some("v1.2.3".into()), - Some("https://opentelemetry.io/schema/1.0.0".into()), - Some(vec![(KeyValue::new("test_k", "test_v"))]), - ); - let instrumentation_library = logger.instrumentation_library(); - let attributes = &instrumentation_library.attributes; - assert_eq!(instrumentation_library.version, Some("v1.2.3".into())); + let logger = provider.logger_with_scope(scope); + let instrumentation_scope = logger.instrumentation_scope(); + let attributes = &instrumentation_scope.attributes; + assert_eq!(instrumentation_scope.name, "test_logger"); assert_eq!( - instrumentation_library.schema_url, + instrumentation_scope.schema_url, Some("https://opentelemetry.io/schema/1.0.0".into()) ); assert_eq!(attributes.len(), 1); diff --git a/opentelemetry-sdk/src/metrics/data/mod.rs b/opentelemetry-sdk/src/metrics/data/mod.rs index c7512bdc04..83b8ed5e97 100644 --- a/opentelemetry-sdk/src/metrics/data/mod.rs +++ b/opentelemetry-sdk/src/metrics/data/mod.rs @@ -2,9 +2,9 @@ use std::{any, borrow::Cow, fmt, time::SystemTime}; -use opentelemetry::KeyValue; +use opentelemetry::{InstrumentationScope, KeyValue}; -use crate::{instrumentation::Scope, Resource}; +use crate::Resource; pub use self::temporality::Temporality; @@ -15,15 +15,15 @@ mod temporality; pub struct ResourceMetrics { /// The entity that collected the metrics. pub resource: Resource, - /// The collection of metrics with unique [Scope]s. + /// The collection of metrics with unique [InstrumentationScope]s. pub scope_metrics: Vec, } /// A collection of metrics produced by a meter. #[derive(Default, Debug)] pub struct ScopeMetrics { - /// The [Scope] that the meter was created with. - pub scope: Scope, + /// The [InstrumentationScope] that the meter was created with. + pub scope: InstrumentationScope, /// The list of aggregations created by the meter. pub metrics: Vec, } diff --git a/opentelemetry-sdk/src/metrics/instrument.rs b/opentelemetry-sdk/src/metrics/instrument.rs index b84fabbd3a..c2b3ce5219 100644 --- a/opentelemetry-sdk/src/metrics/instrument.rs +++ b/opentelemetry-sdk/src/metrics/instrument.rs @@ -2,13 +2,10 @@ use std::{borrow::Cow, collections::HashSet, sync::Arc}; use opentelemetry::{ metrics::{AsyncInstrument, SyncInstrument}, - Key, KeyValue, + InstrumentationScope, Key, KeyValue, }; -use crate::{ - instrumentation::Scope, - metrics::{aggregation::Aggregation, internal::Measure}, -}; +use crate::metrics::{aggregation::Aggregation, internal::Measure}; use super::data::Temporality; @@ -96,7 +93,7 @@ pub struct Instrument { /// Unit is the unit of measurement recorded by the instrument. pub unit: Cow<'static, str>, /// The instrumentation that created the instrument. - pub scope: Scope, + pub scope: InstrumentationScope, } impl Instrument { @@ -124,7 +121,7 @@ impl Instrument { } /// Set the instrument scope. - pub fn scope(mut self, scope: Scope) -> Self { + pub fn scope(mut self, scope: InstrumentationScope) -> Self { self.scope = scope; self } @@ -135,7 +132,7 @@ impl Instrument { && self.description == "" && self.kind.is_none() && self.unit == "" - && self.scope == Scope::default() + && self.scope == InstrumentationScope::default() } pub(crate) fn matches(&self, other: &Instrument) -> bool { diff --git a/opentelemetry-sdk/src/metrics/meter.rs b/opentelemetry-sdk/src/metrics/meter.rs index 8cab6e1b68..0772c80107 100644 --- a/opentelemetry-sdk/src/metrics/meter.rs +++ b/opentelemetry-sdk/src/metrics/meter.rs @@ -8,10 +8,9 @@ use opentelemetry::{ InstrumentProvider, MetricsError, ObservableCounter, ObservableGauge, ObservableUpDownCounter, Result, UpDownCounter, }, - otel_error, + otel_error, InstrumentationScope, }; -use crate::instrumentation::Scope; use crate::metrics::{ instrument::{Instrument, InstrumentKind, Observable, ResolvedMeasures}, internal::{self, Number}, @@ -46,7 +45,7 @@ const INSTRUMENT_UNIT_INVALID_CHAR: &str = "characters in instrument unit must b /// /// [Meter API]: opentelemetry::metrics::Meter pub(crate) struct SdkMeter { - scope: Scope, + scope: InstrumentationScope, pipes: Arc, u64_resolver: Resolver, i64_resolver: Resolver, @@ -54,7 +53,7 @@ pub(crate) struct SdkMeter { } impl SdkMeter { - pub(crate) fn new(scope: Scope, pipes: Arc) -> Self { + pub(crate) fn new(scope: InstrumentationScope, pipes: Arc) -> Self { let view_cache = Default::default(); SdkMeter { diff --git a/opentelemetry-sdk/src/metrics/meter_provider.rs b/opentelemetry-sdk/src/metrics/meter_provider.rs index c91773434b..2450328401 100644 --- a/opentelemetry-sdk/src/metrics/meter_provider.rs +++ b/opentelemetry-sdk/src/metrics/meter_provider.rs @@ -9,10 +9,10 @@ use std::{ use opentelemetry::{ metrics::{Meter, MeterProvider, MetricsError, Result}, - otel_debug, otel_error, KeyValue, + otel_debug, otel_error, InstrumentationScope, }; -use crate::{instrumentation::Scope, Resource}; +use crate::Resource; use super::{ meter::SdkMeter, noop::NoopMeter, pipeline::Pipelines, reader::MetricReader, view::View, @@ -36,7 +36,7 @@ pub struct SdkMeterProvider { #[derive(Debug)] struct SdkMeterProviderInner { pipes: Arc, - meters: Mutex>>, + meters: Mutex>>, is_shutdown: AtomicBool, } @@ -151,32 +151,24 @@ impl Drop for SdkMeterProviderInner { } } +/// Default meter name if empty string is provided. +const DEFAULT_COMPONENT_NAME: &str = "rust.opentelemetry.io/sdk/meter"; + impl MeterProvider for SdkMeterProvider { - fn versioned_meter( - &self, - name: &'static str, - version: Option<&'static str>, - schema_url: Option<&'static str>, - attributes: Option>, - ) -> Meter { - if self.inner.is_shutdown.load(Ordering::Relaxed) { - return Meter::new(Arc::new(NoopMeter::new())); - } + fn meter(&self, mut name: &'static str) -> Meter { + if name.is_empty() { + name = DEFAULT_COMPONENT_NAME + }; - let mut builder = Scope::builder(name); + let scope = InstrumentationScope::builder(name).build(); + self.meter_with_scope(scope) + } - if let Some(v) = version { - builder = builder.with_version(v); - } - if let Some(s) = schema_url { - builder = builder.with_schema_url(s); - } - if let Some(a) = attributes { - builder = builder.with_attributes(a); + fn meter_with_scope(&self, scope: InstrumentationScope) -> Meter { + if self.inner.is_shutdown.load(Ordering::Relaxed) { + return Meter::new(Arc::new(NoopMeter::new())); } - let scope = builder.build(); - if let Ok(mut meters) = self.inner.meters.lock() { let meter = meters .entry(scope) @@ -267,8 +259,8 @@ mod tests { }; use crate::testing::metrics::metric_reader::TestMetricReader; use crate::Resource; - use opentelemetry::global; use opentelemetry::metrics::MeterProvider; + use opentelemetry::{global, InstrumentationScope}; use opentelemetry::{Key, KeyValue, Value}; use std::env; @@ -461,21 +453,31 @@ mod tests { let _meter1 = provider.meter("test"); let _meter2 = provider.meter("test"); assert_eq!(provider.inner.meters.lock().unwrap().len(), 1); - let _meter3 = - provider.versioned_meter("test", Some("1.0.0"), Some("http://example.com"), None); - let _meter4 = - provider.versioned_meter("test", Some("1.0.0"), Some("http://example.com"), None); - let _meter5 = - provider.versioned_meter("test", Some("1.0.0"), Some("http://example.com"), None); + + let scope = InstrumentationScope::builder("test") + .with_version("1.0.0") + .with_schema_url("http://example.com") + .build(); + + let _meter3 = provider.meter_with_scope(scope.clone()); + let _meter4 = provider.meter_with_scope(scope.clone()); + let _meter5 = provider.meter_with_scope(scope); assert_eq!(provider.inner.meters.lock().unwrap().len(), 2); - // the below are different meters, as meter names are case sensitive - let _meter6 = - provider.versioned_meter("ABC", Some("1.0.0"), Some("http://example.com"), None); - let _meter7 = - provider.versioned_meter("Abc", Some("1.0.0"), Some("http://example.com"), None); - let _meter8 = - provider.versioned_meter("abc", Some("1.0.0"), Some("http://example.com"), None); + // these are different meters because meter names are case sensitive + let mut library = InstrumentationScope::builder("ABC") + .with_version("1.0.0") + .with_schema_url("http://example.com") + .build(); + + let _meter6 = provider.meter_with_scope(library.clone()); + + library.name = "Abc".into(); + let _meter7 = provider.meter_with_scope(library.clone()); + + library.name = "abc".into(); + let _meter8 = provider.meter_with_scope(library); + assert_eq!(provider.inner.meters.lock().unwrap().len(), 5); } } diff --git a/opentelemetry-sdk/src/metrics/mod.rs b/opentelemetry-sdk/src/metrics/mod.rs index f2ac7a1a3d..d161d1846b 100644 --- a/opentelemetry-sdk/src/metrics/mod.rs +++ b/opentelemetry-sdk/src/metrics/mod.rs @@ -134,6 +134,7 @@ mod tests { use crate::testing::metrics::InMemoryMetricsExporterBuilder; use crate::{runtime, testing::metrics::InMemoryMetricsExporter}; use opentelemetry::metrics::{Counter, Meter, UpDownCounter}; + use opentelemetry::InstrumentationScope; use opentelemetry::{metrics::MeterProvider as _, KeyValue}; use rand::{rngs, Rng, SeedableRng}; use std::borrow::Cow; @@ -637,18 +638,17 @@ mod tests { // Act // Meters are identical except for scope attributes, but scope attributes are not an identifying property. // Hence there should be a single metric stream output for this test. - let meter1 = meter_provider.versioned_meter( - "test.meter", - Some("v0.1.0"), - Some("schema_url"), - Some(vec![KeyValue::new("key", "value1")]), - ); - let meter2 = meter_provider.versioned_meter( - "test.meter", - Some("v0.1.0"), - Some("schema_url"), - Some(vec![KeyValue::new("key", "value2")]), - ); + let mut scope = InstrumentationScope::builder("test.meter") + .with_version("v0.1.0") + .with_schema_url("http://example.com") + .with_attributes(vec![KeyValue::new("key", "value1")]) + .build(); + + let meter1 = meter_provider.meter_with_scope(scope.clone()); + + scope.attributes = vec![KeyValue::new("key", "value2")]; + let meter2 = meter_provider.meter_with_scope(scope); + let counter1 = meter1 .u64_counter("my_counter") .with_unit("my_unit") @@ -684,7 +684,7 @@ mod tests { let scope = &resource_metrics[0].scope_metrics[0].scope; assert_eq!(scope.name, "test.meter"); assert_eq!(scope.version, Some(Cow::Borrowed("v0.1.0"))); - assert_eq!(scope.schema_url, Some(Cow::Borrowed("schema_url"))); + assert_eq!(scope.schema_url, Some(Cow::Borrowed("http://example.com"))); // This is validating current behavior, but it is not guaranteed to be the case in the future, // as this is a user error and SDK reserves right to change this behavior. diff --git a/opentelemetry-sdk/src/metrics/pipeline.rs b/opentelemetry-sdk/src/metrics/pipeline.rs index a140f65dec..e02e35ea2c 100644 --- a/opentelemetry-sdk/src/metrics/pipeline.rs +++ b/opentelemetry-sdk/src/metrics/pipeline.rs @@ -8,11 +8,10 @@ use std::{ use opentelemetry::{ global, metrics::{MetricsError, Result}, - KeyValue, + InstrumentationScope, KeyValue, }; use crate::{ - instrumentation::Scope, metrics::{ aggregation, data::{Metric, ResourceMetrics, ScopeMetrics}, @@ -55,7 +54,7 @@ type GenericCallback = Arc; #[derive(Default)] struct PipelineInner { - aggregations: HashMap>, + aggregations: HashMap>, callbacks: Vec, } @@ -74,7 +73,7 @@ impl Pipeline { /// This method is not idempotent. Duplicate calls will result in duplicate /// additions, it is the callers responsibility to ensure this is called with /// unique values. - fn add_sync(&self, scope: Scope, i_sync: InstrumentSync) { + fn add_sync(&self, scope: InstrumentationScope, i_sync: InstrumentSync) { let _ = self.inner.lock().map(|mut inner| { inner.aggregations.entry(scope).or_default().push(i_sync); }); @@ -341,7 +340,7 @@ where /// is returned. fn cached_aggregator( &self, - scope: &Scope, + scope: &InstrumentationScope, kind: InstrumentKind, mut stream: Stream, ) -> Result>>> { diff --git a/opentelemetry-sdk/src/testing/logs/in_memory_exporter.rs b/opentelemetry-sdk/src/testing/logs/in_memory_exporter.rs index 958ab11fe1..0db7913adc 100644 --- a/opentelemetry-sdk/src/testing/logs/in_memory_exporter.rs +++ b/opentelemetry-sdk/src/testing/logs/in_memory_exporter.rs @@ -3,7 +3,7 @@ use crate::logs::LogRecord; use crate::Resource; use async_trait::async_trait; use opentelemetry::logs::{LogError, LogResult}; -use opentelemetry::InstrumentationLibrary; +use opentelemetry::InstrumentationScope; use std::borrow::Cow; use std::sync::{Arc, Mutex}; @@ -56,17 +56,17 @@ pub struct OwnedLogData { /// Log record, which can be borrowed or owned. pub record: LogRecord, /// Instrumentation details for the emitter who produced this `LogEvent`. - pub instrumentation: InstrumentationLibrary, + pub instrumentation: InstrumentationScope, } /// `LogDataWithResource` associates a [`LogRecord`] with a [`Resource`] and -/// [`InstrumentationLibrary`]. +/// [`InstrumentationScope`]. #[derive(Clone, Debug)] pub struct LogDataWithResource { /// Log record pub record: LogRecord, /// Instrumentation details for the emitter who produced this `LogData`. - pub instrumentation: InstrumentationLibrary, + pub instrumentation: InstrumentationScope, /// Resource for the emitter who produced this `LogData`. pub resource: Cow<'static, Resource>, } diff --git a/opentelemetry-sdk/src/testing/trace/span_exporters.rs b/opentelemetry-sdk/src/testing/trace/span_exporters.rs index c92a64f399..f8a0776318 100644 --- a/opentelemetry-sdk/src/testing/trace/span_exporters.rs +++ b/opentelemetry-sdk/src/testing/trace/span_exporters.rs @@ -4,12 +4,12 @@ use crate::{ ExportError, }, trace::{SpanEvents, SpanLinks}, - InstrumentationLibrary, }; use futures_util::future::BoxFuture; pub use opentelemetry::testing::trace::TestSpan; -use opentelemetry::trace::{ - SpanContext, SpanId, SpanKind, Status, TraceFlags, TraceId, TraceState, +use opentelemetry::{ + trace::{SpanContext, SpanId, SpanKind, Status, TraceFlags, TraceId, TraceState}, + InstrumentationScope, }; use std::fmt::{Display, Formatter}; @@ -32,7 +32,7 @@ pub fn new_test_export_span_data() -> SpanData { events: SpanEvents::default(), links: SpanLinks::default(), status: Status::Unset, - instrumentation_lib: InstrumentationLibrary::default(), + instrumentation_scope: InstrumentationScope::default(), } } diff --git a/opentelemetry-sdk/src/trace/mod.rs b/opentelemetry-sdk/src/trace/mod.rs index ccaae00638..7ce5e7b977 100644 --- a/opentelemetry-sdk/src/trace/mod.rs +++ b/opentelemetry-sdk/src/trace/mod.rs @@ -40,15 +40,16 @@ mod runtime_tests; #[cfg(all(test, feature = "testing"))] mod tests { + use super::*; use crate::{ testing::trace::InMemorySpanExporterBuilder, trace::span_limit::{DEFAULT_MAX_EVENT_PER_SPAN, DEFAULT_MAX_LINKS_PER_SPAN}, }; - use opentelemetry::testing::trace::TestSpan; use opentelemetry::trace::{ SamplingDecision, SamplingResult, SpanKind, Status, TraceContextExt, TraceState, }; + use opentelemetry::{testing::trace::TestSpan, InstrumentationScope}; use opentelemetry::{ trace::{ Event, Link, Span, SpanBuilder, SpanContext, SpanId, TraceFlags, TraceId, Tracer, @@ -82,7 +83,7 @@ mod tests { assert_eq!(exported_spans.len(), 1); let span = &exported_spans[0]; assert_eq!(span.name, "span_name_updated"); - assert_eq!(span.instrumentation_lib.name, "test_tracer"); + assert_eq!(span.instrumentation_scope.name, "test_tracer"); assert_eq!(span.attributes.len(), 1); assert_eq!(span.events.len(), 1); assert_eq!(span.events[0].name, "test-event"); @@ -117,7 +118,7 @@ mod tests { assert_eq!(exported_spans.len(), 1); let span = &exported_spans[0]; assert_eq!(span.name, "span_name"); - assert_eq!(span.instrumentation_lib.name, "test_tracer"); + assert_eq!(span.instrumentation_scope.name, "test_tracer"); assert_eq!(span.attributes.len(), 1); assert_eq!(span.events.len(), 1); assert_eq!(span.events[0].name, "test-event"); @@ -154,7 +155,7 @@ mod tests { let span = &exported_spans[0]; assert_eq!(span.name, "span_name"); assert_eq!(span.span_kind, SpanKind::Server); - assert_eq!(span.instrumentation_lib.name, "test_tracer"); + assert_eq!(span.instrumentation_scope.name, "test_tracer"); assert_eq!(span.attributes.len(), 1); assert_eq!(span.events.len(), 1); assert_eq!(span.events[0].name, "test-event"); @@ -326,35 +327,13 @@ mod tests { #[test] fn tracer_attributes() { let provider = TracerProvider::builder().build(); - let tracer = provider - .tracer_builder("test_tracer") + let scope = InstrumentationScope::builder("basic") .with_attributes(vec![KeyValue::new("test_k", "test_v")]) .build(); - let instrumentation_library = tracer.instrumentation_library(); - let attributes = &instrumentation_library.attributes; - assert_eq!(attributes.len(), 1); - assert_eq!(attributes[0].key, "test_k".into()); - assert_eq!(attributes[0].value, "test_v".into()); - } - #[test] - #[allow(deprecated)] - fn versioned_tracer_options() { - let provider = TracerProvider::builder().build(); - let tracer = provider.versioned_tracer( - "test_tracer", - Some(String::from("v1.2.3")), - Some(String::from("https://opentelemetry.io/schema/1.0.0")), - Some(vec![(KeyValue::new("test_k", "test_v"))]), - ); - let instrumentation_library = tracer.instrumentation_library(); - let attributes = &instrumentation_library.attributes; - assert_eq!(instrumentation_library.name, "test_tracer"); - assert_eq!(instrumentation_library.version, Some("v1.2.3".into())); - assert_eq!( - instrumentation_library.schema_url, - Some("https://opentelemetry.io/schema/1.0.0".into()) - ); + let tracer = provider.tracer_with_scope(scope); + let instrumentation_scope = tracer.instrumentation_scope(); + let attributes = &instrumentation_scope.attributes; assert_eq!(attributes.len(), 1); assert_eq!(attributes[0].key, "test_k".into()); assert_eq!(attributes[0].value, "test_v".into()); diff --git a/opentelemetry-sdk/src/trace/provider.rs b/opentelemetry-sdk/src/trace/provider.rs index 31a0ae3129..26ddf0864b 100644 --- a/opentelemetry-sdk/src/trace/provider.rs +++ b/opentelemetry-sdk/src/trace/provider.rs @@ -66,17 +66,16 @@ use crate::runtime::RuntimeChannel; use crate::trace::{ BatchSpanProcessor, Config, RandomIdGenerator, Sampler, SimpleSpanProcessor, SpanLimits, Tracer, }; +use crate::Resource; use crate::{export::trace::SpanExporter, trace::SpanProcessor}; -use crate::{InstrumentationLibrary, Resource}; use once_cell::sync::{Lazy, OnceCell}; use opentelemetry::trace::TraceError; +use opentelemetry::InstrumentationScope; use opentelemetry::{otel_debug, trace::TraceResult}; use std::borrow::Cow; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; -/// Default tracer name if empty string is provided. -const DEFAULT_COMPONENT_NAME: &str = "rust.opentelemetry.io/sdk/tracer"; static PROVIDER_RESOURCE: OnceCell = OnceCell::new(); // a no nop tracer provider used as placeholder when the provider is shutdown @@ -248,46 +247,29 @@ impl TracerProvider { } } +/// Default tracer name if empty string is provided. +const DEFAULT_COMPONENT_NAME: &str = "rust.opentelemetry.io/sdk/tracer"; + impl opentelemetry::trace::TracerProvider for TracerProvider { /// This implementation of `TracerProvider` produces `Tracer` instances. type Tracer = Tracer; - /// Create a new versioned `Tracer` instance. - fn versioned_tracer( - &self, - name: impl Into>, - version: Option>>, - schema_url: Option>>, - attributes: Option>, - ) -> Self::Tracer { - // Use default value if name is invalid empty string - let name = name.into(); - let component_name = if name.is_empty() { - Cow::Borrowed(DEFAULT_COMPONENT_NAME) - } else { - name - }; - - let mut builder = self.tracer_builder(component_name); + fn tracer(&self, name: impl Into>) -> Self::Tracer { + let mut name = name.into(); - if let Some(v) = version { - builder = builder.with_version(v); - } - if let Some(s) = schema_url { - builder = builder.with_schema_url(s); - } - if let Some(a) = attributes { - builder = builder.with_attributes(a); - } + if name.is_empty() { + name = Cow::Borrowed(DEFAULT_COMPONENT_NAME) + }; - builder.build() + let scope = InstrumentationScope::builder(name).build(); + self.tracer_with_scope(scope) } - fn library_tracer(&self, library: Arc) -> Self::Tracer { + fn tracer_with_scope(&self, scope: InstrumentationScope) -> Self::Tracer { if self.inner.is_shutdown.load(Ordering::Relaxed) { - return Tracer::new(library, NOOP_TRACER_PROVIDER.clone()); + return Tracer::new(scope, NOOP_TRACER_PROVIDER.clone()); } - Tracer::new(library, self.clone()) + Tracer::new(scope, self.clone()) } } diff --git a/opentelemetry-sdk/src/trace/span.rs b/opentelemetry-sdk/src/trace/span.rs index ea03d9ab53..25a5df0da1 100644 --- a/opentelemetry-sdk/src/trace/span.rs +++ b/opentelemetry-sdk/src/trace/span.rs @@ -263,7 +263,7 @@ fn build_export_data( events: data.events, links: data.links, status: data.status, - instrumentation_lib: tracer.instrumentation_library().clone(), + instrumentation_scope: tracer.instrumentation_scope().clone(), } } diff --git a/opentelemetry-sdk/src/trace/span_processor.rs b/opentelemetry-sdk/src/trace/span_processor.rs index e49ec9ee60..be0921c51d 100644 --- a/opentelemetry-sdk/src/trace/span_processor.rs +++ b/opentelemetry-sdk/src/trace/span_processor.rs @@ -741,7 +741,7 @@ mod tests { events: SpanEvents::default(), links: SpanLinks::default(), status: Status::Unset, - instrumentation_lib: Default::default(), + instrumentation_scope: Default::default(), }; processor.on_end(unsampled); assert!(exporter.get_finished_spans().unwrap().is_empty()); diff --git a/opentelemetry-sdk/src/trace/tracer.rs b/opentelemetry-sdk/src/trace/tracer.rs index f3182d388e..2004fdf2cd 100644 --- a/opentelemetry-sdk/src/trace/tracer.rs +++ b/opentelemetry-sdk/src/trace/tracer.rs @@ -7,25 +7,21 @@ //! and exposes methods for creating and activating new `Spans`. //! //! Docs: -use crate::{ - trace::{ - provider::TracerProvider, - span::{Span, SpanData}, - IdGenerator, ShouldSample, SpanEvents, SpanLimits, SpanLinks, - }, - InstrumentationLibrary, +use crate::trace::{ + provider::TracerProvider, + span::{Span, SpanData}, + IdGenerator, ShouldSample, SpanEvents, SpanLimits, SpanLinks, }; use opentelemetry::{ trace::{SamplingDecision, SpanBuilder, SpanContext, SpanKind, TraceContextExt, TraceFlags}, - Context, KeyValue, + Context, InstrumentationScope, KeyValue, }; use std::fmt; -use std::sync::Arc; /// `Tracer` implementation to create and manage spans #[derive(Clone)] pub struct Tracer { - instrumentation_lib: Arc, + scope: InstrumentationScope, provider: TracerProvider, } @@ -34,22 +30,16 @@ impl fmt::Debug for Tracer { /// Omitting `provider` here is necessary to avoid cycles. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("Tracer") - .field("name", &self.instrumentation_lib.name) - .field("version", &self.instrumentation_lib.version) + .field("name", &self.scope.name) + .field("version", &self.scope.version) .finish() } } impl Tracer { /// Create a new tracer (used internally by `TracerProvider`s). - pub(crate) fn new( - instrumentation_lib: Arc, - provider: TracerProvider, - ) -> Self { - Tracer { - instrumentation_lib, - provider, - } + pub(crate) fn new(scope: InstrumentationScope, provider: TracerProvider) -> Self { + Tracer { scope, provider } } /// TracerProvider associated with this tracer. @@ -57,9 +47,9 @@ impl Tracer { &self.provider } - /// Instrumentation library information of this tracer. - pub(crate) fn instrumentation_library(&self) -> &InstrumentationLibrary { - &self.instrumentation_lib + /// Instrumentation scope of this tracer. + pub(crate) fn instrumentation_scope(&self) -> &InstrumentationScope { + &self.scope } fn build_recording_span( diff --git a/opentelemetry-stdout/examples/basic.rs b/opentelemetry-stdout/examples/basic.rs index eb429061ab..05380e9afe 100644 --- a/opentelemetry-stdout/examples/basic.rs +++ b/opentelemetry-stdout/examples/basic.rs @@ -64,16 +64,17 @@ fn init_logs() -> opentelemetry_sdk::logs::LoggerProvider { #[cfg(feature = "trace")] fn emit_span() { - use opentelemetry::trace::{ - SpanContext, SpanId, TraceFlags, TraceId, TraceState, TracerProvider, + use opentelemetry::{ + trace::{SpanContext, SpanId, TraceFlags, TraceId, TraceState}, + InstrumentationScope, }; - let tracer = global::tracer_provider() - .tracer_builder("stdout-example") + let scope = InstrumentationScope::builder("stdout-example") .with_version("v1") - .with_schema_url("schema_url") .with_attributes([KeyValue::new("scope_key", "scope_value")]) .build(); + + let tracer = global::tracer_with_scope(scope); let mut span = tracer.start("example-span"); span.set_attribute(KeyValue::new("attribute_key1", "attribute_value1")); span.set_attribute(KeyValue::new("attribute_key2", "attribute_value2")); diff --git a/opentelemetry-stdout/src/common.rs b/opentelemetry-stdout/src/common.rs index a05c42112f..83685d3f03 100644 --- a/opentelemetry-stdout/src/common.rs +++ b/opentelemetry-stdout/src/common.rs @@ -233,8 +233,8 @@ pub(crate) struct Scope { dropped_attributes_count: u64, } -impl From for Scope { - fn from(value: opentelemetry_sdk::Scope) -> Self { +impl From for Scope { + fn from(value: opentelemetry::InstrumentationScope) -> Self { Scope { name: value.name, version: value.version, diff --git a/opentelemetry-stdout/src/trace/exporter.rs b/opentelemetry-stdout/src/trace/exporter.rs index a5c057ca46..798e6b4247 100644 --- a/opentelemetry-stdout/src/trace/exporter.rs +++ b/opentelemetry-stdout/src/trace/exporter.rs @@ -72,14 +72,14 @@ fn print_spans(batch: Vec) { for (i, span) in batch.into_iter().enumerate() { println!("Span #{}", i); println!("\tInstrumentation Scope"); - println!("\t\tName : {:?}", &span.instrumentation_lib.name); - if let Some(version) = &span.instrumentation_lib.version { + println!("\t\tName : {:?}", &span.instrumentation_scope.name); + if let Some(version) = &span.instrumentation_scope.version { println!("\t\tVersion : {:?}", version); } - if let Some(schema_url) = &span.instrumentation_lib.schema_url { + if let Some(schema_url) = &span.instrumentation_scope.schema_url { println!("\t\tSchemaUrl: {:?}", schema_url); } - span.instrumentation_lib + span.instrumentation_scope .attributes .iter() .enumerate() diff --git a/opentelemetry-zipkin/src/exporter/mod.rs b/opentelemetry-zipkin/src/exporter/mod.rs index 88edcfb025..e7466c6a2d 100644 --- a/opentelemetry-zipkin/src/exporter/mod.rs +++ b/opentelemetry-zipkin/src/exporter/mod.rs @@ -6,7 +6,7 @@ use async_trait::async_trait; use futures_core::future::BoxFuture; use http::Uri; use model::endpoint::Endpoint; -use opentelemetry::{global, trace::TraceError, KeyValue}; +use opentelemetry::{global, trace::TraceError, InstrumentationScope, KeyValue}; use opentelemetry_http::HttpClient; use opentelemetry_sdk::{ export::{trace, ExportError}, @@ -144,11 +144,11 @@ impl ZipkinPipelineBuilder { let mut provider_builder = TracerProvider::builder().with_simple_exporter(exporter); provider_builder = provider_builder.with_config(config); let provider = provider_builder.build(); - let tracer = - opentelemetry::trace::TracerProvider::tracer_builder(&provider, "opentelemetry-zipkin") - .with_version(env!("CARGO_PKG_VERSION")) - .with_schema_url(semcov::SCHEMA_URL) - .build(); + let scope = InstrumentationScope::builder("opentelemetry-zipkin") + .with_version(env!("CARGO_PKG_VERSION")) + .with_schema_url(semcov::SCHEMA_URL) + .build(); + let tracer = opentelemetry::trace::TracerProvider::tracer_with_scope(&provider, scope); let _ = global::set_tracer_provider(provider); Ok(tracer) } @@ -161,11 +161,11 @@ impl ZipkinPipelineBuilder { let mut provider_builder = TracerProvider::builder().with_batch_exporter(exporter, runtime); provider_builder = provider_builder.with_config(config); let provider = provider_builder.build(); - let tracer = - opentelemetry::trace::TracerProvider::tracer_builder(&provider, "opentelemetry-zipkin") - .with_version(env!("CARGO_PKG_VERSION")) - .with_schema_url(semcov::SCHEMA_URL) - .build(); + let scope = InstrumentationScope::builder("opentelemetry-zipkin") + .with_version(env!("CARGO_PKG_VERSION")) + .with_schema_url(semcov::SCHEMA_URL) + .build(); + let tracer = opentelemetry::trace::TracerProvider::tracer_with_scope(&provider, scope); let _ = global::set_tracer_provider(provider); Ok(tracer) } diff --git a/opentelemetry-zipkin/src/exporter/model/mod.rs b/opentelemetry-zipkin/src/exporter/model/mod.rs index b143848f31..15646429c9 100644 --- a/opentelemetry-zipkin/src/exporter/model/mod.rs +++ b/opentelemetry-zipkin/src/exporter/model/mod.rs @@ -46,11 +46,11 @@ pub(crate) fn into_zipkin_span(local_endpoint: Endpoint, span_data: SpanData) -> [ ( INSTRUMENTATION_LIBRARY_NAME, - Some(span_data.instrumentation_lib.name), + Some(span_data.instrumentation_scope.name), ), ( INSTRUMENTATION_LIBRARY_VERSION, - span_data.instrumentation_lib.version, + span_data.instrumentation_scope.version, ), ] .into_iter() diff --git a/opentelemetry-zipkin/src/exporter/model/span.rs b/opentelemetry-zipkin/src/exporter/model/span.rs index 8c9c7fd5a1..51223be92b 100644 --- a/opentelemetry-zipkin/src/exporter/model/span.rs +++ b/opentelemetry-zipkin/src/exporter/model/span.rs @@ -165,7 +165,7 @@ mod tests { events: SpanEvents::default(), links: SpanLinks::default(), status, - instrumentation_lib: Default::default(), + instrumentation_scope: Default::default(), }; let local_endpoint = Endpoint::new("test".into(), None); let span = into_zipkin_span(local_endpoint, span_data); diff --git a/opentelemetry/CHANGELOG.md b/opentelemetry/CHANGELOG.md index 2719417650..feb62933ae 100644 --- a/opentelemetry/CHANGELOG.md +++ b/opentelemetry/CHANGELOG.md @@ -23,6 +23,15 @@ Now: ```rust let counter = meter.u64_counter("my_counter").build(); ``` +- **Breaking change**: [#2220](https://github.com/open-telemetry/opentelemetry-rust/pull/2220) + - Removed deprecated method `InstrumentationLibrary::new` + - Renamed `InstrumentationLibrary` to `InstrumentationScope` + - Renamed `InstrumentationLibraryBuilder` to `InstrumentationScopeBuilder` + - Removed deprecated methods `LoggerProvider::versioned_logger` and `TracerProvider::versioned_tracer` + - Removed methods `LoggerProvider::logger_builder`, `TracerProvider::tracer_builder` and `MeterProvider::versioned_meter` + - Replaced these methods with `LoggerProvider::logger_with_scope`, `TracerProvider::logger_with_scope`, `MeterProvider::meter_with_scope` + - Replaced `global::meter_with_version` with `global::meter_with_scope` + - Added `global::tracer_with_scope` ## v0.26.0 Released 2024-Sep-30 diff --git a/opentelemetry/src/common.rs b/opentelemetry/src/common.rs index 6e046afd4c..f152826b23 100644 --- a/opentelemetry/src/common.rs +++ b/opentelemetry/src/common.rs @@ -407,7 +407,7 @@ pub trait ExportError: std::error::Error + Send + Sync + 'static { /// Information about a library or crate providing instrumentation. /// -/// An instrumentation library should be named to follow any naming conventions +/// An instrumentation scope should be named to follow any naming conventions /// of the instrumented library (e.g. 'middleware' for a web framework). /// /// See the [instrumentation libraries] spec for more information. @@ -415,37 +415,28 @@ pub trait ExportError: std::error::Error + Send + Sync + 'static { /// [instrumentation libraries]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/overview.md#instrumentation-libraries #[derive(Debug, Default, Clone)] #[non_exhaustive] -pub struct InstrumentationLibrary { +pub struct InstrumentationScope { /// The library name. /// /// This should be the name of the crate providing the instrumentation. pub name: Cow<'static, str>, /// The library version. - /// - /// # Examples - /// - /// ``` - /// let library = opentelemetry::InstrumentationLibrary::builder("my-crate"). - /// with_version(env!("CARGO_PKG_VERSION")). - /// with_schema_url("https://opentelemetry.io/schemas/1.17.0"). - /// build(); - /// ``` pub version: Option>, - /// [Schema url] used by this library. + /// [Schema URL] used by this library. /// - /// [Schema url]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/schemas/overview.md#schema-url + /// [Schema URL]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/schemas/overview.md#schema-url pub schema_url: Option>, /// Specifies the instrumentation scope attributes to associate with emitted telemetry. pub attributes: Vec, } -// Uniqueness for InstrumentationLibrary/InstrumentationScope does not depend on attributes -impl Eq for InstrumentationLibrary {} +// Uniqueness for InstrumentationScope does not depend on attributes +impl Eq for InstrumentationScope {} -impl PartialEq for InstrumentationLibrary { +impl PartialEq for InstrumentationScope { fn eq(&self, other: &Self) -> bool { self.name == other.name && self.version == other.version @@ -453,7 +444,7 @@ impl PartialEq for InstrumentationLibrary { } } -impl hash::Hash for InstrumentationLibrary { +impl hash::Hash for InstrumentationScope { fn hash(&self, state: &mut H) { self.name.hash(state); self.version.hash(state); @@ -461,28 +452,10 @@ impl hash::Hash for InstrumentationLibrary { } } -impl InstrumentationLibrary { - /// Deprecated, use [`InstrumentationLibrary::builder()`] - /// - /// Create an new instrumentation library. - #[deprecated(since = "0.23.0", note = "Please use builder() instead")] - pub fn new( - name: impl Into>, - version: Option>>, - schema_url: Option>>, - attributes: Option>, - ) -> InstrumentationLibrary { - InstrumentationLibrary { - name: name.into(), - version: version.map(Into::into), - schema_url: schema_url.map(Into::into), - attributes: attributes.unwrap_or_default(), - } - } - - /// Create a new builder to create an [InstrumentationLibrary] - pub fn builder>>(name: T) -> InstrumentationLibraryBuilder { - InstrumentationLibraryBuilder { +impl InstrumentationScope { + /// Create a new builder to create an [InstrumentationScope] + pub fn builder>>(name: T) -> InstrumentationScopeBuilder { + InstrumentationScopeBuilder { name: name.into(), version: None, schema_url: None, @@ -491,9 +464,9 @@ impl InstrumentationLibrary { } } -/// Configuration options for [InstrumentationLibrary]. +/// Configuration options for [InstrumentationScope]. /// -/// An instrumentation library is a library or crate providing instrumentation. +/// An instrumentation scope is a library or crate providing instrumentation. /// It should be named to follow any naming conventions of the instrumented /// library (e.g. 'middleware' for a web framework). /// @@ -503,7 +476,7 @@ impl InstrumentationLibrary { /// /// [instrumentation libraries]: https://github.com/open-telemetry/opentelemetry-specification/blob/v1.9.0/specification/overview.md#instrumentation-libraries #[derive(Debug)] -pub struct InstrumentationLibraryBuilder { +pub struct InstrumentationScopeBuilder { name: Cow<'static, str>, version: Option>, @@ -513,13 +486,13 @@ pub struct InstrumentationLibraryBuilder { attributes: Option>, } -impl InstrumentationLibraryBuilder { - /// Configure the version for the instrumentation library +impl InstrumentationScopeBuilder { + /// Configure the version for the instrumentation scope /// /// # Examples /// /// ``` - /// let library = opentelemetry::InstrumentationLibrary::builder("my-crate") + /// let scope = opentelemetry::InstrumentationScope::builder("my-crate") /// .with_version("v0.1.0") /// .build(); /// ``` @@ -528,12 +501,12 @@ impl InstrumentationLibraryBuilder { self } - /// Configure the Schema URL for the instrumentation library + /// Configure the Schema URL for the instrumentation scope /// /// # Examples /// /// ``` - /// let library = opentelemetry::InstrumentationLibrary::builder("my-crate") + /// let scope = opentelemetry::InstrumentationScope::builder("my-crate") /// .with_schema_url("https://opentelemetry.io/schemas/1.17.0") /// .build(); /// ``` @@ -542,14 +515,14 @@ impl InstrumentationLibraryBuilder { self } - /// Configure the attributes for the instrumentation library + /// Configure the attributes for the instrumentation scope /// /// # Examples /// /// ``` /// use opentelemetry::KeyValue; /// - /// let library = opentelemetry::InstrumentationLibrary::builder("my-crate") + /// let scope = opentelemetry::InstrumentationScope::builder("my-crate") /// .with_attributes([KeyValue::new("k", "v")]) /// .build(); /// ``` @@ -561,9 +534,9 @@ impl InstrumentationLibraryBuilder { self } - /// Create a new [InstrumentationLibrary] from this configuration - pub fn build(self) -> InstrumentationLibrary { - InstrumentationLibrary { + /// Create a new [InstrumentationScope] from this configuration + pub fn build(self) -> InstrumentationScope { + InstrumentationScope { name: self.name, version: self.version, schema_url: self.schema_url, diff --git a/opentelemetry/src/global/metrics.rs b/opentelemetry/src/global/metrics.rs index e23a746966..142a5c2f69 100644 --- a/opentelemetry/src/global/metrics.rs +++ b/opentelemetry/src/global/metrics.rs @@ -1,5 +1,5 @@ use crate::metrics::{self, Meter, MeterProvider}; -use crate::KeyValue; +use crate::InstrumentationScope; use once_cell::sync::Lazy; use std::sync::{Arc, RwLock}; @@ -38,32 +38,26 @@ pub fn meter(name: &'static str) -> Meter { meter_provider().meter(name) } -/// Creates a [`Meter`] with the name, version and schema url. +/// Creates a [`Meter`] with the given instrumentation scope. /// -/// - name SHOULD uniquely identify the instrumentation scope, such as the instrumentation library (e.g. io.opentelemetry.contrib.mongodb), package, module or class name. -/// - version specifies the version of the instrumentation scope if the scope has a version -/// - schema url specifies the Schema URL that should be recorded in the emitted telemetry. -/// -/// This is a convenient way of `global::meter_provider().versioned_meter(...)` +/// This is a simpler alternative to `global::meter_provider().meter_with_scope(...)` /// /// # Example /// /// ``` -/// use opentelemetry::global::meter_with_version; +/// use std::sync::Arc; +/// use opentelemetry::global::meter_with_scope; +/// use opentelemetry::InstrumentationScope; /// use opentelemetry::KeyValue; /// -/// let meter = meter_with_version( -/// "io.opentelemetry", -/// Some("0.17"), -/// Some("https://opentelemetry.io/schemas/1.2.0"), -/// Some(vec![KeyValue::new("key", "value")]), -/// ); +/// let scope = InstrumentationScope::builder("io.opentelemetry") +/// .with_version("0.17") +/// .with_schema_url("https://opentelemetry.io/schema/1.2.0") +/// .with_attributes(vec![(KeyValue::new("key", "value"))]) +/// .build(); +/// +/// let meter = meter_with_scope(scope); /// ``` -pub fn meter_with_version( - name: &'static str, - version: Option<&'static str>, - schema_url: Option<&'static str>, - attributes: Option>, -) -> Meter { - meter_provider().versioned_meter(name, version, schema_url, attributes) +pub fn meter_with_scope(scope: InstrumentationScope) -> Meter { + meter_provider().meter_with_scope(scope) } diff --git a/opentelemetry/src/global/mod.rs b/opentelemetry/src/global/mod.rs index 2148215212..4fada1123a 100644 --- a/opentelemetry/src/global/mod.rs +++ b/opentelemetry/src/global/mod.rs @@ -50,16 +50,21 @@ //! ``` //! # #[cfg(feature="trace")] //! # { -//! use opentelemetry::trace::{Tracer, TracerProvider}; +//! use std::sync::Arc; +//! use opentelemetry::trace::Tracer; //! use opentelemetry::global; +//! use opentelemetry::InstrumentationScope; //! //! pub fn my_traced_library_function() { //! // End users of your library will configure their global tracer provider //! // so you can use the global tracer without any setup -//! let tracer = global::tracer_provider().tracer_builder("my-library-name"). -//! with_version(env!("CARGO_PKG_VERSION")). -//! with_schema_url("https://opentelemetry.io/schemas/1.17.0"). -//! build(); +//! +//! let scope = InstrumentationScope::builder("my_library-name") +//! .with_version(env!("CARGO_PKG_VERSION")) +//! .with_schema_url("https://opentelemetry.io/schemas/1.17.0") +//! .build(); +//! +//! let tracer = global::tracer_with_scope(scope); //! //! tracer.in_span("doing_library_work", |cx| { //! // Traced library logic here... diff --git a/opentelemetry/src/global/trace.rs b/opentelemetry/src/global/trace.rs index d3058dc533..bb9100bd15 100644 --- a/opentelemetry/src/global/trace.rs +++ b/opentelemetry/src/global/trace.rs @@ -1,5 +1,5 @@ use crate::trace::{noop::NoopTracerProvider, SpanContext, Status}; -use crate::InstrumentationLibrary; +use crate::InstrumentationScope; use crate::{trace, trace::TracerProvider, Context, KeyValue}; use once_cell::sync::Lazy; use std::borrow::Cow; @@ -305,10 +305,7 @@ where pub trait ObjectSafeTracerProvider { /// Creates a versioned named tracer instance that is a trait object through the underlying /// `TracerProvider`. - fn boxed_tracer( - &self, - library: Arc, - ) -> Box; + fn boxed_tracer(&self, scope: InstrumentationScope) -> Box; } impl ObjectSafeTracerProvider for P @@ -318,11 +315,8 @@ where P: trace::TracerProvider, { /// Return a versioned boxed tracer - fn boxed_tracer( - &self, - library: Arc, - ) -> Box { - Box::new(self.library_tracer(library)) + fn boxed_tracer(&self, scope: InstrumentationScope) -> Box { + Box::new(self.tracer_with_scope(scope)) } } @@ -360,8 +354,8 @@ impl trace::TracerProvider for GlobalTracerProvider { type Tracer = BoxedTracer; /// Create a tracer using the global provider. - fn library_tracer(&self, library: Arc) -> Self::Tracer { - BoxedTracer(self.provider.boxed_tracer(library)) + fn tracer_with_scope(&self, scope: InstrumentationScope) -> Self::Tracer { + BoxedTracer(self.provider.boxed_tracer(scope)) } } @@ -395,6 +389,33 @@ pub fn tracer(name: impl Into>) -> BoxedTracer { tracer_provider().tracer(name.into()) } +/// Creates a [`Tracer`] with the given instrumentation scope +/// via the configured [`GlobalTracerProvider`]. +/// +/// This is a simpler alternative to `global::tracer_provider().tracer_with_scope(...)` +/// +/// # Example +/// +/// ``` +/// use std::sync::Arc; +/// use opentelemetry::global::tracer_with_scope; +/// use opentelemetry::InstrumentationScope; +/// use opentelemetry::KeyValue; +/// +/// let scope = InstrumentationScope::builder("io.opentelemetry") +/// .with_version("0.17") +/// .with_schema_url("https://opentelemetry.io/schema/1.2.0") +/// .with_attributes(vec![(KeyValue::new("key", "value"))]) +/// .build(); +/// +/// let tracer = tracer_with_scope(scope); +/// ``` +/// +/// [`Tracer`]: crate::trace::Tracer +pub fn tracer_with_scope(scope: InstrumentationScope) -> BoxedTracer { + tracer_provider().tracer_with_scope(scope) +} + /// Sets the given [`TracerProvider`] instance as the current global provider. /// /// It returns the [`TracerProvider`] instance that was previously mounted as global provider diff --git a/opentelemetry/src/lib.rs b/opentelemetry/src/lib.rs index fd69b40114..1c8d07caf7 100644 --- a/opentelemetry/src/lib.rs +++ b/opentelemetry/src/lib.rs @@ -204,7 +204,7 @@ mod common; pub mod testing; pub use common::{ - Array, ExportError, InstrumentationLibrary, InstrumentationLibraryBuilder, Key, KeyValue, + Array, ExportError, InstrumentationScope, InstrumentationScopeBuilder, Key, KeyValue, StringValue, Value, }; diff --git a/opentelemetry/src/logs/logger.rs b/opentelemetry/src/logs/logger.rs index fd4e18e043..4f87f01731 100644 --- a/opentelemetry/src/logs/logger.rs +++ b/opentelemetry/src/logs/logger.rs @@ -1,6 +1,6 @@ -use std::{borrow::Cow, sync::Arc}; +use std::borrow::Cow; -use crate::{logs::LogRecord, InstrumentationLibrary, InstrumentationLibraryBuilder, KeyValue}; +use crate::{logs::LogRecord, InstrumentationScope}; #[cfg(feature = "logs_level_enabled")] use super::Severity; @@ -30,90 +30,29 @@ pub trait LoggerProvider { /// The [`Logger`] type that this provider will return. type Logger: Logger; - /// Deprecated, use [`LoggerProvider::logger_builder()`] - /// - /// Returns a new versioned logger with a given name. - /// - /// The `name` should be the application name or the name of the library - /// providing instrumentation. If the name is empty, then an - /// implementation-defined default name may be used instead. - /// Create a new versioned `Logger` instance. - #[deprecated(since = "0.23.0", note = "Please use logger_builder() instead")] - fn versioned_logger( - &self, - name: impl Into>, - version: Option>, - schema_url: Option>, - attributes: Option>, - ) -> Self::Logger { - let mut builder = self.logger_builder(name); - if let Some(v) = version { - builder = builder.with_version(v); - } - if let Some(s) = schema_url { - builder = builder.with_schema_url(s); - } - if let Some(a) = attributes { - builder = builder.with_attributes(a); - } - builder.build() - } - - /// Returns a new builder for creating a [`Logger`] instance - /// - /// The `name` should be the application name or the name of the library - /// providing instrumentation. If the name is empty, then an - /// implementation-defined default name may be used instead. + /// Returns a new logger with the given instrumentation scope. /// /// # Examples /// /// ``` - /// use opentelemetry::InstrumentationLibrary; - /// use crate::opentelemetry::logs::LoggerProvider; + /// use opentelemetry::InstrumentationScope; + /// use opentelemetry::logs::LoggerProvider; /// use opentelemetry_sdk::logs::LoggerProvider as SdkLoggerProvider; /// /// let provider = SdkLoggerProvider::builder().build(); /// /// // logger used in applications/binaries - /// let logger = provider.logger_builder("my_app").build(); + /// let logger = provider.logger("my_app"); /// /// // logger used in libraries/crates that optionally includes version and schema url - /// let logger = provider.logger_builder("my_library") + /// let scope = InstrumentationScope::builder(env!("CARGO_PKG_NAME")) /// .with_version(env!("CARGO_PKG_VERSION")) /// .with_schema_url("https://opentelemetry.io/schema/1.0.0") /// .build(); - /// ``` - fn logger_builder(&self, name: impl Into>) -> LoggerBuilder<'_, Self> { - LoggerBuilder { - provider: self, - library_builder: InstrumentationLibrary::builder(name), - } - } - - /// Returns a new versioned logger with the given instrumentation library. - /// - /// # Examples /// + /// let logger = provider.logger_with_scope(scope); /// ``` - /// use opentelemetry::InstrumentationLibrary; - /// use crate::opentelemetry::logs::LoggerProvider; - /// use opentelemetry_sdk::logs::LoggerProvider as SdkLoggerProvider; - /// - /// let provider = SdkLoggerProvider::builder().build(); - /// - /// // logger used in applications/binaries - /// let logger = provider.logger("my_app"); - /// - /// // logger used in libraries/crates that optionally includes version and schema url - /// let library = std::sync::Arc::new( - /// InstrumentationLibrary::builder(env!("CARGO_PKG_NAME")) - /// .with_version(env!("CARGO_PKG_VERSION")) - /// .with_schema_url("https://opentelemetry.io/schema/1.0.0") - /// .build(), - /// ); - /// let logger = provider.library_logger(library); - /// ``` - fn library_logger(&self, library: Arc) -> Self::Logger; + fn logger_with_scope(&self, scope: InstrumentationScope) -> Self::Logger; /// Returns a new logger with the given name. /// @@ -121,37 +60,7 @@ pub trait LoggerProvider { /// providing instrumentation. If the name is empty, then an /// implementation-defined default name may be used instead. fn logger(&self, name: impl Into>) -> Self::Logger { - self.logger_builder(name).build() - } -} - -#[derive(Debug)] -pub struct LoggerBuilder<'a, T: LoggerProvider + ?Sized> { - provider: &'a T, - library_builder: InstrumentationLibraryBuilder, -} - -impl<'a, T: LoggerProvider + ?Sized> LoggerBuilder<'a, T> { - pub fn with_version(mut self, version: impl Into>) -> Self { - self.library_builder = self.library_builder.with_version(version); - self - } - - pub fn with_schema_url(mut self, schema_url: impl Into>) -> Self { - self.library_builder = self.library_builder.with_schema_url(schema_url); - self - } - - pub fn with_attributes(mut self, attributes: I) -> Self - where - I: IntoIterator, - { - self.library_builder = self.library_builder.with_attributes(attributes); - self - } - - pub fn build(self) -> T::Logger { - self.provider - .library_logger(Arc::new(self.library_builder.build())) + let scope = InstrumentationScope::builder(name).build(); + self.logger_with_scope(scope) } } diff --git a/opentelemetry/src/logs/noop.rs b/opentelemetry/src/logs/noop.rs index 8c31328e5d..ce94a379a3 100644 --- a/opentelemetry/src/logs/noop.rs +++ b/opentelemetry/src/logs/noop.rs @@ -1,8 +1,8 @@ -use std::{borrow::Cow, sync::Arc, time::SystemTime}; +use std::{borrow::Cow, time::SystemTime}; use crate::{ logs::{AnyValue, LogRecord, Logger, LoggerProvider, Severity}, - InstrumentationLibrary, Key, KeyValue, + InstrumentationScope, Key, }; /// A no-op implementation of a [`LoggerProvider`]. @@ -19,17 +19,7 @@ impl NoopLoggerProvider { impl LoggerProvider for NoopLoggerProvider { type Logger = NoopLogger; - fn library_logger(&self, _library: Arc) -> Self::Logger { - NoopLogger(()) - } - - fn versioned_logger( - &self, - _name: impl Into>, - _version: Option>, - _schema_url: Option>, - _attributes: Option>, - ) -> Self::Logger { + fn logger_with_scope(&self, _scope: InstrumentationScope) -> Self::Logger { NoopLogger(()) } } diff --git a/opentelemetry/src/metrics/meter.rs b/opentelemetry/src/metrics/meter.rs index 7bca5db607..15846865e1 100644 --- a/opentelemetry/src/metrics/meter.rs +++ b/opentelemetry/src/metrics/meter.rs @@ -6,7 +6,7 @@ use crate::metrics::{ AsyncInstrumentBuilder, Gauge, InstrumentBuilder, InstrumentProvider, ObservableCounter, ObservableGauge, ObservableUpDownCounter, UpDownCounter, }; -use crate::KeyValue; +use crate::InstrumentationScope; use super::{Counter, Histogram, HistogramBuilder}; @@ -32,32 +32,36 @@ pub trait MeterProvider { /// /// // meter used in applications /// let meter = provider.meter("my_app"); - /// - /// // meter used in libraries/crates that optionally includes version and schema url - /// let meter = provider.versioned_meter( - /// "my_library", - /// Some(env!("CARGO_PKG_VERSION")), - /// Some("https://opentelemetry.io/schema/1.0.0"), - /// Some(vec![KeyValue::new("key", "value")]), - /// ); /// ``` fn meter(&self, name: &'static str) -> Meter { - self.versioned_meter(name, None, None, None) + let scope = InstrumentationScope::builder(name).build(); + self.meter_with_scope(scope) } - /// Returns a new versioned meter with a given name. + /// Returns a new [Meter] with the given instrumentation scope. /// - /// The instrumentation name must be the name of the library providing instrumentation. This - /// name may be the same as the instrumented code only if that code provides built-in - /// instrumentation. If the instrumentation name is empty, then a implementation defined - /// default name will be used instead. - fn versioned_meter( - &self, - name: &'static str, - version: Option<&'static str>, - schema_url: Option<&'static str>, - attributes: Option>, - ) -> Meter; + /// # Examples + /// + /// ``` + /// use std::sync::Arc; + /// use opentelemetry::InstrumentationScope; + /// use opentelemetry::metrics::MeterProvider; + /// use opentelemetry_sdk::metrics::SdkMeterProvider; + /// + /// let provider = SdkMeterProvider::default(); + /// + /// // meter used in applications/binaries + /// let meter = provider.meter("my_app"); + /// + /// // meter used in libraries/crates that optionally includes version and schema url + /// let scope = InstrumentationScope::builder(env!("CARGO_PKG_NAME")) + /// .with_version(env!("CARGO_PKG_VERSION")) + /// .with_schema_url("https://opentelemetry.io/schema/1.0.0") + /// .build(); + /// + /// let meter = provider.meter_with_scope(scope); + /// ``` + fn meter_with_scope(&self, scope: InstrumentationScope) -> Meter; } /// Provides the ability to create instruments for recording measurements or diff --git a/opentelemetry/src/metrics/noop.rs b/opentelemetry/src/metrics/noop.rs index dbe0726515..80201ad06a 100644 --- a/opentelemetry/src/metrics/noop.rs +++ b/opentelemetry/src/metrics/noop.rs @@ -25,13 +25,7 @@ impl NoopMeterProvider { } impl MeterProvider for NoopMeterProvider { - fn versioned_meter( - &self, - _name: &'static str, - _version: Option<&'static str>, - _schema_url: Option<&'static str>, - _attributes: Option>, - ) -> Meter { + fn meter_with_scope(&self, _scope: crate::InstrumentationScope) -> Meter { Meter::new(Arc::new(NoopMeter::new())) } } diff --git a/opentelemetry/src/trace/mod.rs b/opentelemetry/src/trace/mod.rs index 85b8029e3c..3f0f74e90e 100644 --- a/opentelemetry/src/trace/mod.rs +++ b/opentelemetry/src/trace/mod.rs @@ -44,6 +44,8 @@ //! //! ``` //! use opentelemetry::{global, trace::{Span, Tracer, TracerProvider}}; +//! use opentelemetry::InstrumentationScope; +//! use std::sync::Arc; //! //! fn my_library_function() { //! // Use the global tracer provider to get access to the user-specified @@ -51,10 +53,12 @@ //! let tracer_provider = global::tracer_provider(); //! //! // Get a tracer for this library -//! let tracer = tracer_provider.tracer_builder("my_name"). -//! with_version(env!("CARGO_PKG_VERSION")). -//! with_schema_url("https://opentelemetry.io/schemas/1.17.0"). -//! build(); +//! let scope = InstrumentationScope::builder("my_name") +//! .with_version(env!("CARGO_PKG_VERSION")) +//! .with_schema_url("https://opentelemetry.io/schemas/1.17.0") +//! .build(); +//! +//! let tracer = tracer_provider.tracer_with_scope(scope); //! //! // Create spans //! let mut span = tracer.start("doing_work"); diff --git a/opentelemetry/src/trace/noop.rs b/opentelemetry/src/trace/noop.rs index d46a657a2e..4cb8ac4513 100644 --- a/opentelemetry/src/trace/noop.rs +++ b/opentelemetry/src/trace/noop.rs @@ -6,9 +6,9 @@ use crate::{ propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator}, trace::{self, TraceContextExt as _}, - Context, InstrumentationLibrary, KeyValue, + Context, InstrumentationScope, KeyValue, }; -use std::{borrow::Cow, sync::Arc, time::SystemTime}; +use std::{borrow::Cow, time::SystemTime}; /// A no-op instance of a `TracerProvider`. #[derive(Clone, Debug, Default)] @@ -27,7 +27,7 @@ impl trace::TracerProvider for NoopTracerProvider { type Tracer = NoopTracer; /// Returns a new `NoopTracer` instance. - fn library_tracer(&self, _library: Arc) -> Self::Tracer { + fn tracer_with_scope(&self, _scope: InstrumentationScope) -> Self::Tracer { NoopTracer::new() } } diff --git a/opentelemetry/src/trace/tracer_provider.rs b/opentelemetry/src/trace/tracer_provider.rs index c17c3fdd58..8e48da8796 100644 --- a/opentelemetry/src/trace/tracer_provider.rs +++ b/opentelemetry/src/trace/tracer_provider.rs @@ -1,5 +1,5 @@ -use crate::{trace::Tracer, InstrumentationLibrary, InstrumentationLibraryBuilder, KeyValue}; -use std::{borrow::Cow, sync::Arc}; +use crate::{trace::Tracer, InstrumentationScope}; +use std::borrow::Cow; /// Types that can create instances of [`Tracer`]. /// @@ -27,101 +27,18 @@ pub trait TracerProvider { /// /// // tracer used in applications/binaries /// let tracer = provider.tracer("my_app"); - /// - /// // tracer used in libraries/crates that optionally includes version and schema url - /// let tracer = provider.tracer_builder("my_library"). - /// with_version(env!("CARGO_PKG_VERSION")). - /// with_schema_url("https://opentelemetry.io/schema/1.0.0"). - /// with_attributes([KeyValue::new("key", "value")]). - /// build(); /// ``` fn tracer(&self, name: impl Into>) -> Self::Tracer { - self.tracer_builder(name).build() - } - - /// Deprecated, use [`TracerProvider::tracer_builder()`] - /// - /// Returns a new versioned tracer with a given name. - /// - /// The `name` should be the application name or the name of the library - /// providing instrumentation. If the name is empty, then an - /// implementation-defined default name may be used instead. - /// - /// # Examples - /// - /// ``` - /// use opentelemetry::{global, trace::TracerProvider}; - /// - /// let provider = global::tracer_provider(); - /// - /// // tracer used in applications/binaries - /// let tracer = provider.tracer("my_app"); - /// - /// // tracer used in libraries/crates that optionally includes version and schema url - /// let tracer = provider.versioned_tracer( - /// "my_library", - /// Some(env!("CARGO_PKG_VERSION")), - /// Some("https://opentelemetry.io/schema/1.0.0"), - /// None, - /// ); - /// ``` - #[deprecated(since = "0.23.0", note = "Please use tracer_builder() instead")] - fn versioned_tracer( - &self, - name: impl Into>, - version: Option>>, - schema_url: Option>>, - attributes: Option>, - ) -> Self::Tracer { - let mut builder = self.tracer_builder(name); - if let Some(v) = version { - builder = builder.with_version(v); - } - if let Some(s) = schema_url { - builder = builder.with_version(s); - } - if let Some(a) = attributes { - builder = builder.with_attributes(a); - } - - builder.build() - } - - /// Returns a new builder for creating a [`Tracer`] instance - /// - /// The `name` should be the application name or the name of the library - /// providing instrumentation. If the name is empty, then an - /// implementation-defined default name may be used instead. - /// - /// # Examples - /// - /// ``` - /// use opentelemetry::{global, trace::TracerProvider}; - /// - /// let provider = global::tracer_provider(); - /// - /// // tracer used in applications/binaries - /// let tracer = provider.tracer_builder("my_app").build(); - /// - /// // tracer used in libraries/crates that optionally includes version and schema url - /// let tracer = provider.tracer_builder("my_library") - /// .with_version(env!("CARGO_PKG_VERSION")) - /// .with_schema_url("https://opentelemetry.io/schema/1.0.0") - /// .build(); - /// ``` - fn tracer_builder(&self, name: impl Into>) -> TracerBuilder<'_, Self> { - TracerBuilder { - provider: self, - library_builder: InstrumentationLibrary::builder(name), - } + let scope = InstrumentationScope::builder(name).build(); + self.tracer_with_scope(scope) } - /// Returns a new versioned tracer with the given instrumentation library. + /// Returns a new versioned tracer with the given instrumentation scope. /// /// # Examples /// /// ``` - /// use opentelemetry::{global, InstrumentationLibrary, trace::TracerProvider}; + /// use opentelemetry::{global, InstrumentationScope, trace::TracerProvider}; /// /// let provider = global::tracer_provider(); /// @@ -129,45 +46,13 @@ pub trait TracerProvider { /// let tracer = provider.tracer("my_app"); /// /// // tracer used in libraries/crates that optionally includes version and schema url - /// let library = std::sync::Arc::new( - /// InstrumentationLibrary::builder(env!("CARGO_PKG_NAME")) + /// let scope = + /// InstrumentationScope::builder(env!("CARGO_PKG_NAME")) /// .with_version(env!("CARGO_PKG_VERSION")) /// .with_schema_url("https://opentelemetry.io/schema/1.0.0") - /// .build(), - /// ); + /// .build(); /// - /// let tracer = provider.library_tracer(library); + /// let tracer = provider.tracer_with_scope(scope); /// ``` - fn library_tracer(&self, library: Arc) -> Self::Tracer; -} - -#[derive(Debug)] -pub struct TracerBuilder<'a, T: TracerProvider + ?Sized> { - provider: &'a T, - library_builder: InstrumentationLibraryBuilder, -} - -impl<'a, T: TracerProvider + ?Sized> TracerBuilder<'a, T> { - pub fn with_version(mut self, version: impl Into>) -> Self { - self.library_builder = self.library_builder.with_version(version); - self - } - - pub fn with_schema_url(mut self, schema_url: impl Into>) -> Self { - self.library_builder = self.library_builder.with_schema_url(schema_url); - self - } - - pub fn with_attributes(mut self, attributes: I) -> Self - where - I: IntoIterator, - { - self.library_builder = self.library_builder.with_attributes(attributes); - self - } - - pub fn build(self) -> T::Tracer { - self.provider - .library_tracer(Arc::new(self.library_builder.build())) - } + fn tracer_with_scope(&self, scope: InstrumentationScope) -> Self::Tracer; } diff --git a/stress/src/logs.rs b/stress/src/logs.rs index 7744708db9..17fcf2833e 100644 --- a/stress/src/logs.rs +++ b/stress/src/logs.rs @@ -9,7 +9,7 @@ ~44 M /sec */ -use opentelemetry::InstrumentationLibrary; +use opentelemetry::InstrumentationScope; use opentelemetry_appender_tracing::layer; use opentelemetry_sdk::logs::{LogProcessor, LoggerProvider}; use tracing::error; @@ -24,7 +24,7 @@ impl LogProcessor for NoOpLogProcessor { fn emit( &self, _record: &mut opentelemetry_sdk::logs::LogRecord, - _library: &InstrumentationLibrary, + _scope: &InstrumentationScope, ) { } From b90c9fb09aff02007ce54f447a9adbf835599917 Mon Sep 17 00:00:00 2001 From: Lalit Kumar Bhasin Date: Thu, 24 Oct 2024 22:14:36 -0700 Subject: [PATCH 5/5] Global error handler cleanup - PeriodicReader (#2243) Co-authored-by: Cijo Thomas --- .../src/metrics/periodic_reader.rs | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/opentelemetry-sdk/src/metrics/periodic_reader.rs b/opentelemetry-sdk/src/metrics/periodic_reader.rs index 4f565bedb0..bebac2cff5 100644 --- a/opentelemetry-sdk/src/metrics/periodic_reader.rs +++ b/opentelemetry-sdk/src/metrics/periodic_reader.rs @@ -12,9 +12,8 @@ use futures_util::{ StreamExt, }; use opentelemetry::{ - global, metrics::{MetricsError, Result}, - otel_error, + otel_debug, otel_error, }; use crate::runtime::Runtime; @@ -245,13 +244,7 @@ impl PeriodicReaderWorker { Either::Left((res, _)) => { res // return the status of export. } - Either::Right(_) => { - otel_error!( - name: "collect_and_export", - status = "timed_out" - ); - Err(MetricsError::Other("export timed out".into())) - } + Either::Right(_) => Err(MetricsError::Other("export timed out".into())), } } @@ -259,20 +252,31 @@ impl PeriodicReaderWorker { match message { Message::Export => { if let Err(err) = self.collect_and_export().await { - global::handle_error(err) + otel_error!( + name: "PeriodicReader.ExportFailed", + message = "Failed to export metrics", + reason = format!("{}", err)); } } Message::Flush(ch) => { let res = self.collect_and_export().await; - if ch.send(res).is_err() { - global::handle_error(MetricsError::Other("flush channel closed".into())) + if let Err(send_error) = ch.send(res) { + otel_debug!( + name: "PeriodicReader.Flush.SendResultError", + message = "Failed to send flush result", + reason = format!("{:?}", send_error), + ); } } Message::Shutdown(ch) => { let res = self.collect_and_export().await; let _ = self.reader.exporter.shutdown(); - if ch.send(res).is_err() { - global::handle_error(MetricsError::Other("shutdown channel closed".into())) + if let Err(send_error) = ch.send(res) { + otel_debug!( + name: "PeriodicReader.Shutdown.SendResultError", + message = "Failed to send shutdown result", + reason = format!("{:?}", send_error), + ); } return false; } @@ -300,9 +304,8 @@ impl MetricReader for PeriodicReader { let worker = match &mut inner.sdk_producer_or_worker { ProducerOrWorker::Producer(_) => { // Only register once. If producer is already set, do nothing. - global::handle_error(MetricsError::Other( - "duplicate meter registration, did not register manual reader".into(), - )); + otel_debug!(name: "PeriodicReader.DuplicateRegistration", + message = "duplicate registration found, did not register periodic reader."); return; } ProducerOrWorker::Worker(w) => mem::replace(w, Box::new(|_| {})),