Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions opentelemetry-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## vNext

- Store `InstrumentationScope` in `Arc` internally in `SdkTracer`, making tracer clones cheaper (Arc refcount increment instead of deep copy). The multi-processor span export path now builds export data once instead of per processor.
- Add 32-bit platform support by using `portable-atomic` for `AtomicI64` and `AtomicU64` in the metrics module. This enables compilation on 32-bit ARM targets (e.g., `armv5te-unknown-linux-gnueabi`, `armv7-unknown-linux-gnueabihf`).
- `Aggregation` enum and `StreamBuilder::with_aggregation()` are now stable and no longer require the `spec_unstable_metrics_views` feature flag.
- Fix `service.name` Resource attribute fallback to follow OpenTelemetry
Expand Down
40 changes: 34 additions & 6 deletions opentelemetry-sdk/src/trace/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,13 +229,12 @@ impl Span {
));
}
processors => {
for processor in processors {
processor.on_end(build_export_data(
data.clone(),
self.span_context.clone(),
&self.tracer,
));
let export_data = build_export_data(data, self.span_context.clone(), &self.tracer);
let (last, rest) = processors.split_last().unwrap();
for processor in rest {
processor.on_end(export_data.clone());
}
last.on_end(export_data);
}
}
}
Expand Down Expand Up @@ -709,6 +708,35 @@ mod tests {
assert_eq!(event_vec.len(), DEFAULT_MAX_EVENT_PER_SPAN as usize);
}

#[test]
fn multiple_processors_receive_span_data() {
use crate::trace::InMemorySpanExporterBuilder;

let exporter1 = InMemorySpanExporterBuilder::new().build();
let exporter2 = InMemorySpanExporterBuilder::new().build();

let provider = crate::trace::SdkTracerProvider::builder()
.with_simple_exporter(exporter1.clone())
.with_simple_exporter(exporter2.clone())
.build();

let tracer = provider.tracer("test");
let mut span = tracer.start("multi_processor_span");
span.set_attribute(KeyValue::new("key", "value"));
span.end();

let spans1 = exporter1.get_finished_spans().unwrap();
let spans2 = exporter2.get_finished_spans().unwrap();

assert_eq!(spans1.len(), 1);
assert_eq!(spans2.len(), 1);
assert_eq!(spans1[0].name, "multi_processor_span");
assert_eq!(spans2[0].name, "multi_processor_span");
assert_eq!(spans1[0].attributes, spans2[0].attributes);

let _ = provider.shutdown();
}

#[test]
fn test_span_exported_data() {
let provider = crate::trace::SdkTracerProvider::builder()
Expand Down
8 changes: 6 additions & 2 deletions opentelemetry-sdk/src/trace/tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ use opentelemetry::{
Context, InstrumentationScope, KeyValue,
};
use std::fmt;
use std::sync::Arc;

/// `Tracer` implementation to create and manage spans
#[derive(Clone)]
pub struct SdkTracer {
scope: InstrumentationScope,
scope: Arc<InstrumentationScope>,
provider: SdkTracerProvider,
}

Expand All @@ -39,7 +40,10 @@ impl fmt::Debug for SdkTracer {
impl SdkTracer {
/// Create a new tracer (used internally by `TracerProvider`s).
pub(crate) fn new(scope: InstrumentationScope, provider: SdkTracerProvider) -> Self {
SdkTracer { scope, provider }
SdkTracer {
scope: Arc::new(scope),
provider,
}
}

/// TracerProvider associated with this tracer.
Expand Down
Loading