Skip to content
Merged
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
8 changes: 4 additions & 4 deletions datadog-opentelemetry/src/text_map_propagator.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
// SPDX-License-Identifier: Apache-2.0

use std::{collections::HashMap, str::FromStr, sync::Arc};
use std::{collections::HashMap, sync::Arc};

use dd_trace::{catch_panic, sampling::priority, Config};
use opentelemetry::{
Expand All @@ -10,7 +10,7 @@ use opentelemetry::{
};

use dd_trace_propagation::{
context::{InjectSpanContext, Sampling, SpanContext, SpanLink, Tracestate},
context::{InjectSpanContext, InjectTraceState, Sampling, SpanContext, SpanLink},
DatadogCompositePropagator,
};

Expand Down Expand Up @@ -113,7 +113,7 @@ impl DatadogPropagator {
let tracestate = if *otel_tracestate == opentelemetry::trace::TraceState::NONE {
None
} else {
Tracestate::from_str(&otel_tracestate.header()).ok()
Some(InjectTraceState::from_header(otel_tracestate.header()))
};

let tags = if let Some(propagation_tags) = &mut propagation_data.tags {
Expand All @@ -129,7 +129,7 @@ impl DatadogPropagator {
sampling,
origin: propagation_data.origin.as_deref(),
tags,
tracestate: tracestate.as_ref(),
tracestate,
};

self.inner.inject(dd_span_context, &mut injector)
Expand Down
2 changes: 1 addition & 1 deletion dd-trace-propagation/benches/inject_benchmark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ fn span_context_to_inject(c: &mut SpanContext) -> InjectSpanContext<'_> {
origin: c.origin.as_deref(),
tags: &mut c.tags,
is_remote: c.is_remote,
tracestate: c.tracestate.as_ref(),
tracestate: None,
}
}

Expand Down
41 changes: 36 additions & 5 deletions dd-trace-propagation/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ pub struct InjectSpanContext<'a> {
// tags needs to be mutable because we insert the error meta field
pub tags: &'a mut HashMap<String, String>,
pub is_remote: bool,
pub tracestate: Option<&'a Tracestate>,
pub tracestate: Option<InjectTraceState>,
}

#[cfg(test)]
Expand All @@ -89,7 +89,17 @@ pub(crate) fn span_context_to_inject(c: &mut SpanContext) -> InjectSpanContext<'
origin: c.origin.as_deref(),
tags: &mut c.tags,
is_remote: c.is_remote,
tracestate: c.tracestate.as_ref(),
tracestate: c.tracestate.as_ref().map(|ts| {
InjectTraceState::from_header(ts.additional_values.as_ref().map_or(
String::new(),
|v| {
v.iter()
.map(|(k, v)| format!("{k}={v}"))
.collect::<Vec<_>>()
.join(",")
},
))
}),
}
}

Expand All @@ -105,6 +115,29 @@ pub struct SpanContext {
pub tracestate: Option<Tracestate>,
}

/// A tracestate we grab from the parent span
///
/// Only non-dd keys in the tracestate are injected
pub struct InjectTraceState {
header: String,
}

impl InjectTraceState {
pub fn from_header(header: String) -> Self {
Self { header }
}

pub fn additional_values(&self) -> impl Iterator<Item = &str> {
self.header.split(',').filter(|part| {
let (key, value) = part.split_once('=').unwrap_or((part, ""));
key != "dd"
&& !value.is_empty()
&& Tracestate::valid_key(key)
&& Tracestate::valid_value(value)
})
}
}

#[derive(Clone, Debug, PartialEq)]
pub struct Traceparent {
pub sampling_priority: SamplingPriority,
Expand Down Expand Up @@ -171,9 +204,7 @@ impl FromStr for Tracestate {
let mut additional_values = vec![];

for v in ts_v {
let mut parts = v.splitn(2, '=');
let key = parts.next().unwrap_or_default();
let value = parts.next().unwrap_or_default();
let (key, value) = v.split_once('=').unwrap_or(("", ""));

if !Tracestate::valid_key(key) || value.is_empty() || !Tracestate::valid_value(value) {
dd_debug!("Tracestate: invalid key or header value: {v}");
Expand Down
26 changes: 13 additions & 13 deletions dd-trace-propagation/src/tracecontext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,14 +249,10 @@ fn inject_tracestate(context: &InjectSpanContext, carrier: &mut dyn Injector) {
}

// Add additional tracestate values if present
if let Some(ts) = context.tracestate {
if let Some(ref additional) = ts.additional_values {
for (key, value) in additional.iter().take(31) {
tracestate.push_str(TRACESTATE_VALUES_SEPARATOR);
tracestate.push_str(key);
tracestate.push('=');
tracestate.push_str(value);
}
if let Some(ts) = &context.tracestate {
for part in ts.additional_values().take(31) {
tracestate.push_str(TRACESTATE_VALUES_SEPARATOR);
tracestate.push_str(part)
}
}

Expand Down Expand Up @@ -509,7 +505,10 @@ pub fn keys() -> &'static [String] {
mod test {
use dd_trace::{configuration::TracePropagationStyle, sampling::priority, Config};

use crate::{context::span_context_to_inject, Propagator};
use crate::{
context::{span_context_to_inject, InjectTraceState},
Propagator,
};

use super::*;

Expand Down Expand Up @@ -716,7 +715,6 @@ mod test {

#[test]
fn test_inject_traceparent() {
let ts = Tracestate::from_str("other=bleh,atel=test,dd=s:2;o:foo_bar_;t.dm:-4").unwrap();
let mut context = InjectSpanContext {
trace_id: u128::from_str_radix("1111aaaa2222bbbb3333cccc4444dddd", 16).unwrap(),
span_id: u64::from_str_radix("5555eeee6666ffff", 16).unwrap(),
Expand All @@ -730,7 +728,9 @@ mod test {
"abc~!@#$%^&*()_+`-=".to_string(),
)]),
is_remote: false,
tracestate: Some(&ts),
tracestate: Some(InjectTraceState::from_header(
"other=bleh,atel=test,dd=s:2;o:foo_bar_;t.dm:-4".to_owned(),
)),
};

let mut carrier: HashMap<String, String> = HashMap::new();
Expand Down Expand Up @@ -791,7 +791,7 @@ mod test {
for index in 0..35 {
tracestate.push(format!("state{index}=value-{index}"));
}
let tracestate = Tracestate::from_str(&tracestate.join(",")).unwrap();
let tracestate = tracestate.join(",");

let mut context = InjectSpanContext {
trace_id: u128::from_str_radix("1111aaaa2222bbbb3333cccc4444dddd", 16).unwrap(),
Expand All @@ -803,7 +803,7 @@ mod test {
origin: Some("rum"),
tags: &mut HashMap::from([("_dd.p.foo".to_string(), "abc".to_string())]),
is_remote: false,
tracestate: Some(&tracestate),
tracestate: Some(InjectTraceState::from_header(tracestate)),
};

let mut carrier: HashMap<String, String> = HashMap::new();
Expand Down
Loading