Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5f049d6
feat: added setting of the is_remote_mask in exporter span flags
nikhilmantri0902 Sep 7, 2025
480911e
chore: updated Changelog
nikhilmantri0902 Sep 7, 2025
2b3140b
chore: added lint checks
nikhilmantri0902 Sep 7, 2025
e128856
fix: lint checks and coverage errors
nikhilmantri0902 Sep 7, 2025
a29cf84
fix: unused import remove
nikhilmantri0902 Sep 7, 2025
8e24aaa
fix: unused import remove
nikhilmantri0902 Sep 7, 2025
6222815
fix: fixing a failing lint check
nikhilmantri0902 Sep 7, 2025
74dec5b
refactor: replace parent_span_context with parent_span_is_remote boolean
nikhilmantri0902 Sep 9, 2025
9008ada
fix: format build_span_flags function signature
nikhilmantri0902 Sep 9, 2025
e5394b8
fix: remove unused variables in test functions
nikhilmantri0902 Sep 9, 2025
b52597f
chore: made function build_span_flags as private
nikhilmantri0902 Sep 10, 2025
f8fc795
fix: resolved conflicts with main
nikhilmantri0902 Sep 10, 2025
8897bda
fix: updated visibility for crate module
nikhilmantri0902 Sep 10, 2025
3bbe32f
Merge branch 'main' into fix/exporter_is_remote_span
nikhilmantri0902 Sep 12, 2025
64163ed
fix: batchspanprocessor_handles_dropped_spans test case
nikhilmantri0902 Sep 12, 2025
4fbce77
fix: batchspanprocessor_handles_dropped_spans test case - comment fix
nikhilmantri0902 Sep 12, 2025
cc0ae9f
fix: batchspanprocessor_handles_dropped_spans test case - comment fix
nikhilmantri0902 Sep 12, 2025
3f6cf4e
fix: batchspanprocessor_handles_dropped_spans test case - comment fix
nikhilmantri0902 Sep 12, 2025
54a69b4
Merge branch 'main' into fix/exporter_is_remote_span
lalitb Sep 16, 2025
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-otlp/src/exporter/http/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1047,6 +1047,7 @@ mod tests {
SpanData {
span_context,
parent_span_id: SpanId::from(0),
parent_span_context: None,
span_kind: SpanKind::Internal,
name: Cow::Borrowed("test_span"),
start_time: SystemTime::UNIX_EPOCH,
Expand Down
4 changes: 4 additions & 0 deletions opentelemetry-proto/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

## vNext

- **Feature**: Add span flags support for `isRemote` property in OTLP trace transformation ([#3153](https://github.com/open-telemetry/opentelemetry-rust/pull/3153))
- Implemented `build_span_flags` function that sets OTLP span flags based on parent span's `isRemote` property
- Updated span and link transformations to properly set flags field (0x100 for local, 0x300 for remote)
- Added comprehensive tests for span flags functionality
- Update proto definitions to v1.7.0.
- Added Rust generated protos for profiles collector. [#3077](https://github.com/open-telemetry/opentelemetry-rust/pull/3077)
- **Breaking change**: package opentelemetry_proto::tonic::profiles::v1 renamed to opentelemetry_proto::tonic::profiles::v1development. [#3077](https://github.com/open-telemetry/opentelemetry-rust/pull/3077)
Expand Down
169 changes: 166 additions & 3 deletions opentelemetry-proto/src/transform/trace.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
#[cfg(feature = "gen-tonic-messages")]
/// Builds span flags based on the parent span context's remote property.
/// This follows the OTLP specification for span flags.
pub fn build_span_flags(
parent_span_context: Option<&opentelemetry::trace::SpanContext>,
base_flags: u32,
) -> u32 {
use crate::proto::tonic::trace::v1::SpanFlags;
let mut flags = base_flags;
flags |= SpanFlags::ContextHasIsRemoteMask as u32;
if let Some(parent_ctx) = parent_span_context {
if parent_ctx.is_remote() {
flags |= SpanFlags::ContextIsRemoteMask as u32;
}
}
flags
}

#[cfg(feature = "gen-tonic-messages")]
pub mod tonic {
use crate::proto::tonic::resource::v1::Resource;
Expand Down Expand Up @@ -41,7 +59,10 @@ pub mod tonic {
trace_state: link.span_context.trace_state().header(),
attributes: Attributes::from(link.attributes).0,
dropped_attributes_count: link.dropped_attributes_count,
flags: link.span_context.trace_flags().to_u8() as u32,
flags: super::build_span_flags(
Some(&link.span_context),
link.span_context.trace_flags().to_u8() as u32,
),
}
}
}
Expand All @@ -59,7 +80,10 @@ pub mod tonic {
vec![]
}
},
flags: source_span.span_context.trace_flags().to_u8() as u32,
flags: super::build_span_flags(
source_span.parent_span_context.as_ref(),
source_span.span_context.trace_flags().to_u8() as u32,
),
name: source_span.name.into_owned(),
kind: span_kind as i32,
start_time_unix_nano: to_nanos(source_span.start_time),
Expand Down Expand Up @@ -118,7 +142,10 @@ pub mod tonic {
vec![]
}
},
flags: source_span.span_context.trace_flags().to_u8() as u32,
flags: super::build_span_flags(
source_span.parent_span_context.as_ref(),
source_span.span_context.trace_flags().to_u8() as u32,
),
name: source_span.name.into_owned(),
kind: span_kind as i32,
start_time_unix_nano: to_nanos(source_span.start_time),
Expand Down Expand Up @@ -191,6 +218,141 @@ pub mod tonic {
}
}

#[cfg(all(test, feature = "gen-tonic-messages"))]
mod span_flags_tests {
use crate::proto::tonic::trace::v1::{Span, SpanFlags};
use opentelemetry::trace::{SpanContext, SpanId, TraceFlags, TraceId, TraceState};
use opentelemetry::InstrumentationScope;
use opentelemetry_sdk::trace::SpanData;
use std::borrow::Cow;

#[test]
fn test_build_span_flags_local_parent() {
let local_parent = SpanContext::new(
TraceId::from(123),
SpanId::from(456),
TraceFlags::default(),
false, // is_remote = false
TraceState::default(),
);

let flags = super::build_span_flags(Some(&local_parent), 0);
assert_eq!(flags, SpanFlags::ContextHasIsRemoteMask as u32); // 0x100
}

#[test]
fn test_build_span_flags_remote_parent() {
let remote_parent = SpanContext::new(
TraceId::from(123),
SpanId::from(456),
TraceFlags::default(),
true, // is_remote = true
TraceState::default(),
);

let flags = super::build_span_flags(Some(&remote_parent), 0);
assert_eq!(
flags,
(SpanFlags::ContextHasIsRemoteMask as u32) | (SpanFlags::ContextIsRemoteMask as u32)
); // 0x300
}

#[test]
fn test_build_span_flags_no_parent() {
let flags = super::build_span_flags(None, 0);
assert_eq!(flags, SpanFlags::ContextHasIsRemoteMask as u32); // 0x100
}

#[test]
fn test_build_span_flags_preserves_base_flags() {
let local_parent = SpanContext::new(
TraceId::from(123),
SpanId::from(456),
TraceFlags::default(),
false,
TraceState::default(),
);

let flags = super::build_span_flags(Some(&local_parent), 0x01); // SAMPLED flag
assert_eq!(flags, 0x01 | (SpanFlags::ContextHasIsRemoteMask as u32)); // 0x101
}

#[test]
fn test_span_transformation_with_flags() {
let local_parent = SpanContext::new(
TraceId::from(123),
SpanId::from(456),
TraceFlags::default(),
false,
TraceState::default(),
);

let span_data = SpanData {
span_context: SpanContext::new(
TraceId::from(789),
SpanId::from(101112),
TraceFlags::default(),
false,
TraceState::default(),
),
parent_span_id: SpanId::from(456),
parent_span_context: Some(local_parent),
span_kind: opentelemetry::trace::SpanKind::Internal,
name: Cow::Borrowed("test_span"),
start_time: std::time::SystemTime::now(),
end_time: std::time::SystemTime::now(),
attributes: vec![],
dropped_attributes_count: 0,
events: opentelemetry_sdk::trace::SpanEvents::default(),
links: opentelemetry_sdk::trace::SpanLinks::default(),
status: opentelemetry::trace::Status::Unset,
instrumentation_scope: InstrumentationScope::builder("test").build(),
};

let otlp_span: Span = span_data.into();
assert_eq!(otlp_span.flags, SpanFlags::ContextHasIsRemoteMask as u32); // 0x100
}

#[test]
fn test_span_transformation_with_remote_parent() {
let remote_parent = SpanContext::new(
TraceId::from(123),
SpanId::from(456),
TraceFlags::default(),
true, // is_remote = true
TraceState::default(),
);

let span_data = SpanData {
span_context: SpanContext::new(
TraceId::from(789),
SpanId::from(101112),
TraceFlags::default(),
false,
TraceState::default(),
),
parent_span_id: SpanId::from(456),
parent_span_context: Some(remote_parent),
span_kind: opentelemetry::trace::SpanKind::Internal,
name: Cow::Borrowed("test_span"),
start_time: std::time::SystemTime::now(),
end_time: std::time::SystemTime::now(),
attributes: vec![],
dropped_attributes_count: 0,
events: opentelemetry_sdk::trace::SpanEvents::default(),
links: opentelemetry_sdk::trace::SpanLinks::default(),
status: opentelemetry::trace::Status::Unset,
instrumentation_scope: InstrumentationScope::builder("test").build(),
};

let otlp_span: Span = span_data.into();
assert_eq!(
otlp_span.flags,
(SpanFlags::ContextHasIsRemoteMask as u32) | (SpanFlags::ContextIsRemoteMask as u32)
); // 0x300
}
}

#[cfg(test)]
mod tests {
use crate::tonic::common::v1::any_value::Value;
Expand Down Expand Up @@ -219,6 +381,7 @@ mod tests {
SpanData {
span_context,
parent_span_id: SpanId::from(0),
parent_span_context: None,
span_kind: SpanKind::Internal,
name: Cow::Borrowed("test_span"),
start_time: now(),
Expand Down
5 changes: 5 additions & 0 deletions opentelemetry-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

## vNext

- **Feature**: Add span flags support for `isRemote` property in OTLP exporter ([#3153](https://github.com/open-telemetry/opentelemetry-rust/pull/3153))
- Added `parent_span_context` field to `SpanData` to store parent span context information
- Implemented `build_span_flags` function that sets OTLP span flags based on parent span's `isRemote` property
- Updated span and link transformations to properly set flags field (0x100 for local, 0x300 for remote)
- Added comprehensive tests for span flags functionality
- TODO: Placeholder for Span processor related things
- *Fix* SpanProcessor::on_start is no longer called on non recording spans
- **Fix**: Restore true parallel exports in the async-native `BatchSpanProcessor` by honoring `OTEL_BSP_MAX_CONCURRENT_EXPORTS` ([#2959](https://github.com/open-telemetry/opentelemetry-rust/pull/3028)). A regression in [#2685](https://github.com/open-telemetry/opentelemetry-rust/pull/2685) inadvertently awaited the `export()` future directly in `opentelemetry-sdk/src/trace/span_processor_with_async_runtime.rs` instead of spawning it on the runtime, forcing all exports to run sequentially.
Expand Down
1 change: 1 addition & 0 deletions opentelemetry-sdk/benches/batch_span_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ fn get_span_data() -> Vec<SpanData> {
TraceState::default(),
),
parent_span_id: SpanId::from(12),
parent_span_context: None,
span_kind: SpanKind::Client,
name: Default::default(),
start_time: now(),
Expand Down
1 change: 1 addition & 0 deletions opentelemetry-sdk/src/testing/trace/span_exporters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub fn new_test_export_span_data() -> SpanData {
TraceState::default(),
),
parent_span_id: SpanId::INVALID,
parent_span_context: None,
span_kind: SpanKind::Internal,
name: "opentelemetry".into(),
start_time: opentelemetry::time::now(),
Expand Down
2 changes: 2 additions & 0 deletions opentelemetry-sdk/src/trace/export.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ pub struct SpanData {
pub span_context: SpanContext,
/// Span parent id
pub parent_span_id: SpanId,
/// Parent span context (for span flags)
pub parent_span_context: Option<SpanContext>,
/// Span kind
pub span_kind: SpanKind,
/// Span name
Expand Down
4 changes: 4 additions & 0 deletions opentelemetry-sdk/src/trace/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ pub struct Span {
pub(crate) struct SpanData {
/// Span parent id
pub(crate) parent_span_id: SpanId,
/// Parent span context (for span flags)
pub(crate) parent_span_context: Option<SpanContext>,
/// Span kind
pub(crate) span_kind: SpanKind,
/// Span name
Expand Down Expand Up @@ -254,6 +256,7 @@ fn build_export_data(
crate::trace::SpanData {
span_context,
parent_span_id: data.parent_span_id,
parent_span_context: data.parent_span_context,
span_kind: data.span_kind,
name: data.name,
start_time: data.start_time,
Expand Down Expand Up @@ -286,6 +289,7 @@ mod tests {
let tracer = provider.tracer("opentelemetry");
let data = SpanData {
parent_span_id: SpanId::from(0),
parent_span_context: None,
span_kind: trace::SpanKind::Internal,
name: "opentelemetry".into(),
start_time: opentelemetry::time::now(),
Expand Down
2 changes: 2 additions & 0 deletions opentelemetry-sdk/src/trace/span_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,7 @@ mod tests {
let unsampled = SpanData {
span_context: SpanContext::empty_context(),
parent_span_id: SpanId::INVALID,
parent_span_context: None,
span_kind: SpanKind::Internal,
name: "opentelemetry".into(),
start_time: opentelemetry::time::now(),
Expand Down Expand Up @@ -1129,6 +1130,7 @@ mod tests {
SpanData {
span_context: SpanContext::empty_context(),
parent_span_id: SpanId::INVALID,
parent_span_context: None,
span_kind: SpanKind::Internal,
name: name.to_string().into(),
start_time: opentelemetry::time::now(),
Expand Down
5 changes: 5 additions & 0 deletions opentelemetry-sdk/src/trace/tracer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ impl SdkTracer {
sc,
Some(SpanData {
parent_span_id: psc.span_id(),
parent_span_context: if psc.is_valid() {
Some(psc.clone())
} else {
None
},
span_kind: builder.span_kind.take().unwrap_or(SpanKind::Internal),
name,
start_time,
Expand Down
1 change: 1 addition & 0 deletions opentelemetry-zipkin/src/exporter/model/span.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ mod tests {
Default::default(),
),
parent_span_id: SpanId::from(1),
parent_span_context: None,
span_kind: SpanKind::Client,
name: "".into(),
start_time: now(),
Expand Down
Loading