Skip to content

Commit 7f77ec6

Browse files
authored
feat: make trace state can be propagated for dropped sampler (#1435)
1 parent 09ae384 commit 7f77ec6

File tree

2 files changed

+231
-159
lines changed

2 files changed

+231
-159
lines changed

opentelemetry-sdk/src/trace/mod.rs

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,16 @@ mod tests {
4343
testing::trace::InMemorySpanExporterBuilder,
4444
trace::span_limit::{DEFAULT_MAX_EVENT_PER_SPAN, DEFAULT_MAX_LINKS_PER_SPAN},
4545
};
46+
use opentelemetry::testing::trace::TestSpan;
47+
use opentelemetry::trace::{
48+
SamplingDecision, SamplingResult, SpanKind, TraceContextExt, TraceState,
49+
};
4650
use opentelemetry::{
4751
trace::{
4852
Event, Link, Span, SpanBuilder, SpanContext, SpanId, TraceFlags, TraceId, Tracer,
4953
TracerProvider as _,
5054
},
51-
KeyValue,
55+
Context, KeyValue,
5256
};
5357

5458
#[test]
@@ -176,4 +180,92 @@ mod tests {
176180
assert_eq!(span.events.len(), DEFAULT_MAX_EVENT_PER_SPAN as usize);
177181
assert_eq!(span.events.dropped_count, DEFAULT_MAX_EVENT_PER_SPAN + 2);
178182
}
183+
184+
#[test]
185+
fn trace_state_for_dropped_sampler() {
186+
let exporter = InMemorySpanExporterBuilder::new().build();
187+
let provider = TracerProvider::builder()
188+
.with_config(config().with_sampler(Sampler::AlwaysOff))
189+
.with_span_processor(SimpleSpanProcessor::new(Box::new(exporter.clone())))
190+
.build();
191+
192+
let tracer = provider.tracer("test");
193+
let trace_state = TraceState::from_key_value(vec![("foo", "bar")]).unwrap();
194+
195+
let parent_context = Context::new().with_span(TestSpan(SpanContext::new(
196+
TraceId::from_u128(10000),
197+
SpanId::from_u64(20),
198+
TraceFlags::SAMPLED,
199+
true,
200+
trace_state.clone(),
201+
)));
202+
203+
let span = tracer.start_with_context("span", &parent_context);
204+
assert_eq!(
205+
span.span_context().trace_state().get("foo"),
206+
trace_state.get("foo")
207+
)
208+
}
209+
210+
#[derive(Clone, Debug, Default)]
211+
struct TestRecordOnlySampler {}
212+
213+
impl ShouldSample for TestRecordOnlySampler {
214+
fn should_sample(
215+
&self,
216+
parent_context: Option<&Context>,
217+
_trace_id: TraceId,
218+
_name: &str,
219+
_span_kind: &SpanKind,
220+
_attributes: &[KeyValue],
221+
_links: &[Link],
222+
) -> SamplingResult {
223+
let trace_state = parent_context
224+
.unwrap()
225+
.span()
226+
.span_context()
227+
.trace_state()
228+
.clone();
229+
SamplingResult {
230+
decision: SamplingDecision::RecordOnly,
231+
attributes: vec![KeyValue::new("record_only_key", "record_only_value")],
232+
trace_state,
233+
}
234+
}
235+
}
236+
237+
#[test]
238+
fn trace_state_for_record_only_sampler() {
239+
let exporter = InMemorySpanExporterBuilder::new().build();
240+
let provider = TracerProvider::builder()
241+
.with_config(config().with_sampler(TestRecordOnlySampler::default()))
242+
.with_span_processor(SimpleSpanProcessor::new(Box::new(exporter.clone())))
243+
.build();
244+
245+
let tracer = provider.tracer("test");
246+
let trace_state = TraceState::from_key_value(vec![("foo", "bar")]).unwrap();
247+
248+
let parent_context = Context::new().with_span(TestSpan(SpanContext::new(
249+
TraceId::from_u128(10000),
250+
SpanId::from_u64(20),
251+
TraceFlags::SAMPLED,
252+
true,
253+
trace_state.clone(),
254+
)));
255+
256+
let span = tracer.build_with_context(
257+
SpanBuilder::from_name("span")
258+
.with_attributes(vec![KeyValue::new("extra_attr_key", "extra_attr_value")]),
259+
&parent_context,
260+
);
261+
assert!(!span.span_context().trace_flags().is_sampled());
262+
assert_eq!(
263+
span.exported_data().unwrap().attributes,
264+
vec![
265+
KeyValue::new("extra_attr_key", "extra_attr_value"),
266+
KeyValue::new("record_only_key", "record_only_value")
267+
]
268+
);
269+
assert_eq!(span.span_context().trace_state().get("foo"), Some("bar"));
270+
}
179271
}

0 commit comments

Comments
 (0)