diff --git a/opentelemetry-aws/src/lib.rs b/opentelemetry-aws/src/lib.rs index 27c32ca236..8f06947f13 100644 --- a/opentelemetry-aws/src/lib.rs +++ b/opentelemetry-aws/src/lib.rs @@ -38,10 +38,7 @@ pub mod trace { use opentelemetry::{ propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator}, - trace::{ - SpanContext, SpanId, TraceContextExt, TraceId, TraceState, TRACE_FLAG_DEFERRED, - TRACE_FLAG_NOT_SAMPLED, TRACE_FLAG_SAMPLED, - }, + trace::{SpanContext, SpanId, TraceContextExt, TraceFlags, TraceId, TraceState}, Context, }; use std::convert::{TryFrom, TryInto}; @@ -56,6 +53,8 @@ pub mod trace { const NOT_SAMPLED: &str = "0"; const REQUESTED_SAMPLE_DECISION: &str = "?"; + const TRACE_FLAG_DEFERRED: TraceFlags = TraceFlags::new(0x02); + lazy_static::lazy_static! { static ref AWS_XRAY_HEADER_FIELD: [String; 1] = [AWS_XRAY_TRACE_HEADER.to_string()]; } @@ -100,7 +99,7 @@ pub mod trace { let mut trace_id: TraceId = TraceId::invalid(); let mut parent_segment_id: SpanId = SpanId::invalid(); - let mut sampling_decision: u8 = TRACE_FLAG_DEFERRED; + let mut sampling_decision = TRACE_FLAG_DEFERRED; let mut kv_vec: Vec<(String, String)> = Vec::with_capacity(parts.len()); for (key, value) in parts { @@ -116,8 +115,8 @@ pub mod trace { HEADER_PARENT_KEY => parent_segment_id = SpanId::from_hex(value), HEADER_SAMPLED_KEY => { sampling_decision = match value { - NOT_SAMPLED => TRACE_FLAG_NOT_SAMPLED, - SAMPLED => TRACE_FLAG_SAMPLED, + NOT_SAMPLED => TraceFlags::default(), + SAMPLED => TraceFlags::SAMPLED, REQUESTED_SAMPLE_DECISION => TRACE_FLAG_DEFERRED, _ => TRACE_FLAG_DEFERRED, } @@ -151,13 +150,14 @@ pub mod trace { if span_context.is_valid() { let xray_trace_id: XrayTraceId = span_context.trace_id().into(); - let sampling_decision: &str = if span_context.is_deferred() { - REQUESTED_SAMPLE_DECISION - } else if span_context.is_sampled() { - SAMPLED - } else { - NOT_SAMPLED - }; + let sampling_decision: &str = + if span_context.trace_flags() & TRACE_FLAG_DEFERRED == TRACE_FLAG_DEFERRED { + REQUESTED_SAMPLE_DECISION + } else if span_context.is_sampled() { + SAMPLED + } else { + NOT_SAMPLED + }; let trace_state_header: String = span_context .trace_state() @@ -291,13 +291,13 @@ pub mod trace { ("Root=1-bogus-bad", SpanContext::empty_context()), ("Root=1-too-many-parts", SpanContext::empty_context()), ("Root=1-58406520-a006649127e371903a2de979;Parent=garbage", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::invalid(), TRACE_FLAG_DEFERRED, true, TraceState::default())), - ("Root=1-58406520-a006649127e371903a2de979;Sampled=1", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::invalid(), TRACE_FLAG_SAMPLED, true, TraceState::default())), - ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=0", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), - ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=1", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TRACE_FLAG_SAMPLED, true, TraceState::default())), + ("Root=1-58406520-a006649127e371903a2de979;Sampled=1", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::invalid(), TraceFlags::SAMPLED, true, TraceState::default())), + ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=0", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TraceFlags::default(), true, TraceState::default())), + ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=1", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TraceFlags::SAMPLED, true, TraceState::default())), ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TRACE_FLAG_DEFERRED, true, TraceState::default())), ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=?", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TRACE_FLAG_DEFERRED, true, TraceState::default())), - ("Root=1-58406520-a006649127e371903a2de979;Self=1-58406520-bf42676c05e20ba4a90e448e;Parent=4c721bf33e3caf8f;Sampled=1", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TRACE_FLAG_SAMPLED, true, TraceState::from_str("self=1-58406520-bf42676c05e20ba4a90e448e").unwrap())), - ("Root=1-58406520-a006649127e371903a2de979;Self=1-58406520-bf42676c05e20ba4a90e448e;Parent=4c721bf33e3caf8f;Sampled=1;RandomKey=RandomValue", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TRACE_FLAG_SAMPLED, true, TraceState::from_str("self=1-58406520-bf42676c05e20ba4a90e448e,randomkey=RandomValue").unwrap())), + ("Root=1-58406520-a006649127e371903a2de979;Self=1-58406520-bf42676c05e20ba4a90e448e;Parent=4c721bf33e3caf8f;Sampled=1", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TraceFlags::SAMPLED, true, TraceState::from_str("self=1-58406520-bf42676c05e20ba4a90e448e").unwrap())), + ("Root=1-58406520-a006649127e371903a2de979;Self=1-58406520-bf42676c05e20ba4a90e448e;Parent=4c721bf33e3caf8f;Sampled=1;RandomKey=RandomValue", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TraceFlags::SAMPLED, true, TraceState::from_str("self=1-58406520-bf42676c05e20ba4a90e448e,randomkey=RandomValue").unwrap())), ] } @@ -307,9 +307,9 @@ pub mod trace { ("", SpanContext::empty_context()), ("", SpanContext::new(TraceId::from_hex("garbage"), SpanId::invalid(), TRACE_FLAG_DEFERRED, true, TraceState::default())), ("", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::invalid(), TRACE_FLAG_DEFERRED, true, TraceState::default())), - ("", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::invalid(), TRACE_FLAG_SAMPLED, true, TraceState::default())), - ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=0", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), - ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=1", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TRACE_FLAG_SAMPLED, true, TraceState::default())), + ("", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::invalid(), TraceFlags::SAMPLED, true, TraceState::default())), + ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=0", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TraceFlags::default(), true, TraceState::default())), + ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=1", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TraceFlags::SAMPLED, true, TraceState::default())), ("Root=1-58406520-a006649127e371903a2de979;Parent=4c721bf33e3caf8f;Sampled=?;Self=1-58406520-bf42676c05e20ba4a90e448e;Randomkey=RandomValue", SpanContext::new(TraceId::from_hex("58406520a006649127e371903a2de979"), SpanId::from_hex("4c721bf33e3caf8f"), TRACE_FLAG_DEFERRED, true, TraceState::from_str("self=1-58406520-bf42676c05e20ba4a90e448e,randomkey=RandomValue").unwrap())), ] } diff --git a/opentelemetry-contrib/src/trace/propagator/binary/base64_format.rs b/opentelemetry-contrib/src/trace/propagator/binary/base64_format.rs index 6a36962c0e..5ba290d031 100644 --- a/opentelemetry-contrib/src/trace/propagator/binary/base64_format.rs +++ b/opentelemetry-contrib/src/trace/propagator/binary/base64_format.rs @@ -43,19 +43,19 @@ where mod tests { use super::*; use crate::trace::propagator::binary::binary_propagator::BinaryPropagator; - use opentelemetry::trace::{SpanId, TraceId, TraceState}; + use opentelemetry::trace::{SpanId, TraceFlags, TraceId, TraceState}; #[rustfmt::skip] fn to_base64_data() -> Vec<(SpanContext, String)> { vec![ (SpanContext::new( TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), - SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::default()), + SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::default()), "AABL+S81d7NNpqPOkp0ODkc2AQDwZ6oLqQK3AgE=".to_string() ), (SpanContext::new( TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), - SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 0, true, TraceState::default()), + SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::default(), true, TraceState::default()), "AABL+S81d7NNpqPOkp0ODkc2AQDwZ6oLqQK3AgA=".to_string() ), ] diff --git a/opentelemetry-contrib/src/trace/propagator/binary/binary_propagator.rs b/opentelemetry-contrib/src/trace/propagator/binary/binary_propagator.rs index e50a698931..675be8cfc9 100644 --- a/opentelemetry-contrib/src/trace/propagator/binary/binary_propagator.rs +++ b/opentelemetry-contrib/src/trace/propagator/binary/binary_propagator.rs @@ -5,7 +5,7 @@ //! //! `BinaryFormat` MUST expose the APIs that serializes values into bytes, //! and deserializes values from bytes. -use opentelemetry::trace::{SpanContext, SpanId, TraceId, TraceState}; +use opentelemetry::trace::{SpanContext, SpanId, TraceFlags, TraceId, TraceState}; use std::convert::TryInto; /// Used to serialize and deserialize `SpanContext`s to and from a binary @@ -40,7 +40,7 @@ impl BinaryFormat for BinaryPropagator { res[18] = 1; res[19..27].copy_from_slice(&context.span_id().to_u64().to_be_bytes()); res[27] = 2; - res[28] = context.trace_flags(); + res[28] = context.trace_flags().to_u8(); res } @@ -71,7 +71,7 @@ impl BinaryFormat for BinaryPropagator { let span_context = SpanContext::new( TraceId::from_u128(trace_id), SpanId::from_u64(span_id), - trace_flags, + TraceFlags::new(trace_flags), true, // TODO traceparent and tracestate should both begin with a 0 byte, figure out how to differentiate TraceState::default(), @@ -96,7 +96,7 @@ mod tests { // Context with sampled (SpanContext::new( TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), - SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::default()), [ + SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::default()), [ 0x00, 0x00, 0x4b, 0xf9, 0x2f, 0x35, 0x77, 0xb3, 0x4d, 0xa6, 0xa3, 0xce, 0x92, 0x9d, 0x0e, 0x0e, 0x47, 0x36, 0x01, 0x00, 0xf0, 0x67, 0xaa, 0x0b, 0xa9, 0x02, 0xb7, 0x02, 0x01, @@ -104,7 +104,7 @@ mod tests { // Context without sampled (SpanContext::new( TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), - SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 0, true, TraceState::default()), [ + SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::default(), true, TraceState::default()), [ 0x00, 0x00, 0x4b, 0xf9, 0x2f, 0x35, 0x77, 0xb3, 0x4d, 0xa6, 0xa3, 0xce, 0x92, 0x9d, 0x0e, 0x0e, 0x47, 0x36, 0x01, 0x00, 0xf0, 0x67, 0xaa, 0x0b, 0xa9, 0x02, 0xb7, 0x02, 0x00, @@ -118,19 +118,19 @@ mod tests { fn from_bytes_data() -> Vec<(SpanContext, Vec)> { vec![ // Future version of the proto - (SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736),SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::default()), vec![ + (SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736),SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::default()), vec![ 0x02, 0x00, 0x4b, 0xf9, 0x2f, 0x35, 0x77, 0xb3, 0x4d, 0xa6, 0xa3, 0xce, 0x92, 0x9d, 0x0e, 0x0e, 0x47, 0x36, 0x01, 0x00, 0xf0, 0x67, 0xaa, 0x0b, 0xa9, 0x02, 0xb7, 0x02, 0x01, ]), // current version with sampled - (SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736),SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::default()), vec![ + (SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736),SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::default()), vec![ 0x02, 0x00, 0x4b, 0xf9, 0x2f, 0x35, 0x77, 0xb3, 0x4d, 0xa6, 0xa3, 0xce, 0x92, 0x9d, 0x0e, 0x0e, 0x47, 0x36, 0x01, 0x00, 0xf0, 0x67, 0xaa, 0x0b, 0xa9, 0x02, 0xb7, 0x02, 0x01, ]), // valid context without option - (SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736),SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 0, true, TraceState::default()), vec![ + (SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736),SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::default(), true, TraceState::default()), vec![ 0x00, 0x00, 0x4b, 0xf9, 0x2f, 0x35, 0x77, 0xb3, 0x4d, 0xa6, 0xa3, 0xce, 0x92, 0x9d, 0x0e, 0x0e, 0x47, 0x36, 0x01, 0x00, 0xf0, 0x67, 0xaa, 0x0b, 0xa9, 0x02, 0xb7, ]), diff --git a/opentelemetry-datadog/src/exporter/model/mod.rs b/opentelemetry-datadog/src/exporter/model/mod.rs index ab810b2a06..ac3b3e8993 100644 --- a/opentelemetry-datadog/src/exporter/model/mod.rs +++ b/opentelemetry-datadog/src/exporter/model/mod.rs @@ -77,7 +77,7 @@ pub(crate) mod tests { use opentelemetry::sdk; use opentelemetry::sdk::InstrumentationLibrary; use opentelemetry::{ - trace::{SpanContext, SpanId, SpanKind, StatusCode, TraceId, TraceState}, + trace::{SpanContext, SpanId, SpanKind, StatusCode, TraceFlags, TraceId, TraceState}, Key, }; use std::time::{Duration, SystemTime}; @@ -90,7 +90,7 @@ pub(crate) mod tests { let span_context = SpanContext::new( TraceId::from_u128(trace_id), SpanId::from_u64(span_id), - 0, + TraceFlags::default(), false, TraceState::default(), ); diff --git a/opentelemetry-datadog/src/lib.rs b/opentelemetry-datadog/src/lib.rs index 49bdcef9a5..d0ff47e430 100644 --- a/opentelemetry-datadog/src/lib.rs +++ b/opentelemetry-datadog/src/lib.rs @@ -139,10 +139,7 @@ mod exporter; mod propagator { use opentelemetry::{ propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator}, - trace::{ - SpanContext, SpanId, TraceContextExt, TraceId, TraceState, TRACE_FLAG_DEFERRED, - TRACE_FLAG_NOT_SAMPLED, TRACE_FLAG_SAMPLED, - }, + trace::{SpanContext, SpanId, TraceContextExt, TraceFlags, TraceId, TraceState}, Context, }; @@ -150,6 +147,8 @@ mod propagator { const DATADOG_PARENT_ID_HEADER: &str = "x-datadog-parent-id"; const DATADOG_SAMPLING_PRIORITY_HEADER: &str = "x-datadog-sampling-priority"; + const TRACE_FLAG_DEFERRED: TraceFlags = TraceFlags::new(0x02); + lazy_static::lazy_static! { static ref DATADOG_HEADER_FIELDS: [String; 3] = [ DATADOG_TRACE_ID_HEADER.to_string(), @@ -247,10 +246,10 @@ mod propagator { ); let sampled = match sampling_priority { Ok(SamplingPriority::UserReject) | Ok(SamplingPriority::AutoReject) => { - TRACE_FLAG_NOT_SAMPLED + TraceFlags::default() } Ok(SamplingPriority::UserKeep) | Ok(SamplingPriority::AutoKeep) => { - TRACE_FLAG_SAMPLED + TraceFlags::SAMPLED } // Treat the sampling as DEFERRED instead of erroring on extracting the span context Err(_) => TRACE_FLAG_DEFERRED, @@ -282,7 +281,7 @@ mod propagator { span_context.span_id().to_u64().to_string(), ); - if !span_context.is_deferred() { + if span_context.trace_flags() & TRACE_FLAG_DEFERRED != TRACE_FLAG_DEFERRED { let sampling_priority = if span_context.is_sampled() { SamplingPriority::AutoKeep } else { @@ -325,8 +324,8 @@ mod propagator { (vec![(DATADOG_TRACE_ID_HEADER, "garbage")], SpanContext::empty_context()), (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "garbage")], SpanContext::new(TraceId::from_u128(1234), SpanId::invalid(), TRACE_FLAG_DEFERRED, true, TraceState::default())), (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TRACE_FLAG_DEFERRED, true, TraceState::default())), - (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12"), (DATADOG_SAMPLING_PRIORITY_HEADER, "0")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), - (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12"), (DATADOG_SAMPLING_PRIORITY_HEADER, "1")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TRACE_FLAG_SAMPLED, true, TraceState::default())), + (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12"), (DATADOG_SAMPLING_PRIORITY_HEADER, "0")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TraceFlags::default(), true, TraceState::default())), + (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12"), (DATADOG_SAMPLING_PRIORITY_HEADER, "1")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TraceFlags::SAMPLED, true, TraceState::default())), ] } @@ -336,10 +335,10 @@ mod propagator { (vec![], SpanContext::empty_context()), (vec![], SpanContext::new(TraceId::from_hex("garbage"), SpanId::invalid(), TRACE_FLAG_DEFERRED, true, TraceState::default())), (vec![], SpanContext::new(TraceId::from_hex("1234"), SpanId::invalid(), TRACE_FLAG_DEFERRED, true, TraceState::default())), - (vec![], SpanContext::new(TraceId::from_hex("1234"), SpanId::invalid(), TRACE_FLAG_SAMPLED, true, TraceState::default())), + (vec![], SpanContext::new(TraceId::from_hex("1234"), SpanId::invalid(), TraceFlags::SAMPLED, true, TraceState::default())), (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TRACE_FLAG_DEFERRED, true, TraceState::default())), - (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12"), (DATADOG_SAMPLING_PRIORITY_HEADER, "0")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), - (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12"), (DATADOG_SAMPLING_PRIORITY_HEADER, "1")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TRACE_FLAG_SAMPLED, true, TraceState::default())), + (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12"), (DATADOG_SAMPLING_PRIORITY_HEADER, "0")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TraceFlags::default(), true, TraceState::default())), + (vec![(DATADOG_TRACE_ID_HEADER, "1234"), (DATADOG_PARENT_ID_HEADER, "12"), (DATADOG_SAMPLING_PRIORITY_HEADER, "1")], SpanContext::new(TraceId::from_u128(1234), SpanId::from_u64(12), TraceFlags::SAMPLED, true, TraceState::default())), ] } diff --git a/opentelemetry-jaeger/src/exporter/mod.rs b/opentelemetry-jaeger/src/exporter/mod.rs index 58903ad2ef..492f5fd270 100644 --- a/opentelemetry-jaeger/src/exporter/mod.rs +++ b/opentelemetry-jaeger/src/exporter/mod.rs @@ -501,7 +501,7 @@ fn convert_otel_span_into_jaeger_span( parent_span_id: span.parent_span_id.to_u64() as i64, operation_name: span.name.into_owned(), references: links_to_references(span.links), - flags: span.span_context.trace_flags() as i32, + flags: span.span_context.trace_flags().to_u8() as i32, start_time: span .start_time .duration_since(SystemTime::UNIX_EPOCH) diff --git a/opentelemetry-jaeger/src/lib.rs b/opentelemetry-jaeger/src/lib.rs index a9d262ace7..6b2444e25b 100644 --- a/opentelemetry-jaeger/src/lib.rs +++ b/opentelemetry-jaeger/src/lib.rs @@ -201,10 +201,7 @@ mod propagator { //! [`Jaeger documentation`]: https://www.jaegertracing.io/docs/1.18/client-libraries/#propagation-format use opentelemetry::{ propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator}, - trace::{ - SpanContext, SpanId, TraceContextExt, TraceId, TraceState, TRACE_FLAG_DEBUG, - TRACE_FLAG_NOT_SAMPLED, TRACE_FLAG_SAMPLED, - }, + trace::{SpanContext, SpanId, TraceContextExt, TraceFlags, TraceId, TraceState}, Context, }; use std::borrow::Cow; @@ -214,6 +211,8 @@ mod propagator { const JAEGER_BAGGAGE_PREFIX: &str = "uberctx-"; const DEPRECATED_PARENT_SPAN: &str = "0"; + const TRACE_FLAG_DEBUG: TraceFlags = TraceFlags::new(0x04); + lazy_static::lazy_static! { static ref JAEGER_HEADER_FIELD: [String; 1] = [JAEGER_HEADER.to_string()]; } @@ -259,10 +258,10 @@ mod propagator { let trace_id = self.extract_trace_id(parts[0])?; let span_id = self.extract_span_id(parts[1])?; // Ignore parent span id since it's deprecated. - let flag = self.extract_flag(parts[3])?; - let trace_state = self.extract_trace_state(extractor)?; + let flags = self.extract_trace_flags(parts[3])?; + let state = self.extract_trace_state(extractor)?; - Ok(SpanContext::new(trace_id, span_id, flag, true, trace_state)) + Ok(SpanContext::new(trace_id, span_id, flags, true, state)) } /// Extract trace id from the header. @@ -296,21 +295,21 @@ mod propagator { /// Second bit control whether it's a debug trace /// Third bit is not used. /// Forth bit is firehose flag, which is not supported in OT now. - fn extract_flag(&self, flag: &str) -> Result { + fn extract_trace_flags(&self, flag: &str) -> Result { if flag.len() > 2 { return Err(()); } let flag = u8::from_str(flag).map_err(|_| ())?; if flag & 0x01 == 0x01 { if flag & 0x02 == 0x02 { - Ok(TRACE_FLAG_SAMPLED | TRACE_FLAG_DEBUG) + Ok(TraceFlags::SAMPLED | TRACE_FLAG_DEBUG) } else { - Ok(TRACE_FLAG_SAMPLED) + Ok(TraceFlags::SAMPLED) } } else { // Debug flag should only be set when sampled flag is set. // So if debug flag is set alone. We will just use not sampled flag - Ok(TRACE_FLAG_NOT_SAMPLED) + Ok(TraceFlags::default()) } } @@ -335,7 +334,7 @@ mod propagator { let span_context = span.span_context(); if span_context.is_valid() { let flag: u8 = if span_context.is_sampled() { - if span_context.is_debug() { + if span_context.trace_flags() & TRACE_FLAG_DEBUG == TRACE_FLAG_DEBUG { 0x03 } else { 0x01 @@ -372,10 +371,7 @@ mod propagator { use opentelemetry::{ propagation::{Injector, TextMapPropagator}, testing::trace::TestSpan, - trace::{ - SpanContext, SpanId, TraceContextExt, TraceId, TraceState, TRACE_FLAG_DEBUG, - TRACE_FLAG_NOT_SAMPLED, TRACE_FLAG_SAMPLED, - }, + trace::{SpanContext, SpanId, TraceContextExt, TraceFlags, TraceId, TraceState}, Context, }; use std::collections::HashMap; @@ -395,7 +391,7 @@ mod propagator { SpanContext::new( TraceId::from_u128(TRACE_ID), SpanId::from_u64(SPAN_ID), - TRACE_FLAG_SAMPLED, + TraceFlags::SAMPLED, true, TraceState::default(), ), @@ -407,7 +403,7 @@ mod propagator { SpanContext::new( TraceId::from_u128(TRACE_ID), SpanId::from_u64(SPAN_ID), - TRACE_FLAG_SAMPLED, + TraceFlags::SAMPLED, true, TraceState::default(), ), @@ -419,7 +415,7 @@ mod propagator { SpanContext::new( TraceId::from_u128(TRACE_ID), SpanId::from_u64(SPAN_ID), - TRACE_FLAG_DEBUG | TRACE_FLAG_SAMPLED, + TRACE_FLAG_DEBUG | TraceFlags::SAMPLED, true, TraceState::default(), ), @@ -431,7 +427,7 @@ mod propagator { SpanContext::new( TraceId::from_u128(TRACE_ID), SpanId::from_u64(SPAN_ID), - TRACE_FLAG_NOT_SAMPLED, + TraceFlags::default(), true, TraceState::default(), ), @@ -463,7 +459,7 @@ mod propagator { SpanContext::new( TraceId::from_u128(TRACE_ID), SpanId::from_u64(SPAN_ID), - TRACE_FLAG_SAMPLED, + TraceFlags::SAMPLED, true, TraceState::default(), ), @@ -473,7 +469,7 @@ mod propagator { SpanContext::new( TraceId::from_u128(TRACE_ID), SpanId::from_u64(SPAN_ID), - TRACE_FLAG_NOT_SAMPLED, + TraceFlags::default(), true, TraceState::default(), ), @@ -483,7 +479,7 @@ mod propagator { SpanContext::new( TraceId::from_u128(TRACE_ID), SpanId::from_u64(SPAN_ID), - TRACE_FLAG_DEBUG | TRACE_FLAG_SAMPLED, + TRACE_FLAG_DEBUG | TraceFlags::SAMPLED, true, TraceState::default(), ), @@ -552,7 +548,7 @@ mod propagator { &SpanContext::new( TraceId::from_u128(TRACE_ID), SpanId::from_u64(SPAN_ID), - 1, + TraceFlags::SAMPLED, true, TraceState::default(), ) diff --git a/opentelemetry-zipkin/src/exporter/model/span.rs b/opentelemetry-zipkin/src/exporter/model/span.rs index 774a30db4c..e1eea8b7eb 100644 --- a/opentelemetry-zipkin/src/exporter/model/span.rs +++ b/opentelemetry-zipkin/src/exporter/model/span.rs @@ -61,7 +61,7 @@ mod tests { use crate::exporter::model::{into_zipkin_span, OTEL_ERROR_DESCRIPTION, OTEL_STATUS_CODE}; use opentelemetry::sdk::export::trace::SpanData; use opentelemetry::sdk::trace::{EvictedHashMap, EvictedQueue}; - use opentelemetry::trace::{SpanContext, SpanId, SpanKind, StatusCode, TraceId}; + use opentelemetry::trace::{SpanContext, SpanId, SpanKind, StatusCode, TraceFlags, TraceId}; use std::collections::HashMap; use std::net::Ipv4Addr; use std::time::SystemTime; @@ -163,7 +163,7 @@ mod tests { span_context: SpanContext::new( TraceId::from_u128(1), SpanId::from_u64(1), - 0, + TraceFlags::default(), false, Default::default(), ), diff --git a/opentelemetry-zipkin/src/propagator/mod.rs b/opentelemetry-zipkin/src/propagator/mod.rs index c000365c46..5e524b9c92 100644 --- a/opentelemetry-zipkin/src/propagator/mod.rs +++ b/opentelemetry-zipkin/src/propagator/mod.rs @@ -15,23 +15,23 @@ //! and extract. Otherwise, separate headers are used to inject and extract. use opentelemetry::{ propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator}, - trace::{ - SpanContext, SpanId, TraceContextExt, TraceId, TraceState, TRACE_FLAG_DEBUG, - TRACE_FLAG_DEFERRED, TRACE_FLAG_NOT_SAMPLED, TRACE_FLAG_SAMPLED, - }, + trace::{SpanContext, SpanId, TraceContextExt, TraceFlags, TraceId, TraceState}, Context, }; -static B3_SINGLE_HEADER: &str = "b3"; +const B3_SINGLE_HEADER: &str = "b3"; /// As per spec, the multiple header should be case sensitive. But different protocol will use /// different formats. For example, HTTP will use X-B3-$name while gRPC will use x-b3-$name. So here /// we leave it to be lower case since we cannot tell what kind of protocol will be used. /// Go implementation also uses lower case. -static B3_DEBUG_FLAG_HEADER: &str = "x-b3-flags"; -static B3_TRACE_ID_HEADER: &str = "x-b3-traceid"; -static B3_SPAN_ID_HEADER: &str = "x-b3-spanid"; -static B3_SAMPLED_HEADER: &str = "x-b3-sampled"; -static B3_PARENT_SPAN_ID_HEADER: &str = "x-b3-parentspanid"; +const B3_DEBUG_FLAG_HEADER: &str = "x-b3-flags"; +const B3_TRACE_ID_HEADER: &str = "x-b3-traceid"; +const B3_SPAN_ID_HEADER: &str = "x-b3-spanid"; +const B3_SAMPLED_HEADER: &str = "x-b3-sampled"; +const B3_PARENT_SPAN_ID_HEADER: &str = "x-b3-parentspanid"; + +const TRACE_FLAG_DEFERRED: TraceFlags = TraceFlags::new(0x02); +const TRACE_FLAG_DEBUG: TraceFlags = TraceFlags::new(0x04); lazy_static::lazy_static! { static ref B3_SINGLE_FIELDS: [String; 1] = [B3_SINGLE_HEADER.to_string()]; @@ -117,22 +117,22 @@ impl Propagator { /// Extract sampled state from encoded &str value /// For legacy support and being lenient to other tracing implementations we /// allow "true" and "false" as inputs for interop purposes. - fn extract_sampled_state(&self, sampled: &str) -> Result { + fn extract_sampled_state(&self, sampled: &str) -> Result { match sampled { - "0" | "false" => Ok(TRACE_FLAG_NOT_SAMPLED), - "1" => Ok(TRACE_FLAG_SAMPLED), + "0" | "false" => Ok(TraceFlags::default()), + "1" => Ok(TraceFlags::SAMPLED), "true" if !self.inject_encoding.support(&B3Encoding::SingleHeader) => { - Ok(TRACE_FLAG_SAMPLED) + Ok(TraceFlags::SAMPLED) } "d" if self.inject_encoding.support(&B3Encoding::SingleHeader) => Ok(TRACE_FLAG_DEBUG), _ => Err(()), } } - fn extract_debug_flag(&self, debug: &str) -> Result { + fn extract_debug_flag(&self, debug: &str) -> Result { match debug { - "0" => Ok(TRACE_FLAG_NOT_SAMPLED), - "1" => Ok(TRACE_FLAG_DEBUG | TRACE_FLAG_SAMPLED), // debug implies sampled + "0" => Ok(TraceFlags::default()), + "1" => Ok(TRACE_FLAG_DEBUG | TraceFlags::SAMPLED), // debug implies sampled _ => Err(()), } } @@ -214,14 +214,17 @@ impl TextMapPropagator for Propagator { let span = context.span(); let span_context = span.span_context(); if span_context.is_valid() { + let is_deferred = + span_context.trace_flags() & TRACE_FLAG_DEFERRED == TRACE_FLAG_DEFERRED; + let is_debug = span_context.trace_flags() & TRACE_FLAG_DEBUG == TRACE_FLAG_DEBUG; if self.inject_encoding.support(&B3Encoding::SingleHeader) { let mut value = format!( "{:032x}-{:016x}", span_context.trace_id().to_u128(), span_context.span_id().to_u64(), ); - if !span_context.is_deferred() { - let flag = if span_context.is_debug() { + if !is_deferred { + let flag = if is_debug { "d" } else if span_context.is_sampled() { "1" @@ -246,9 +249,9 @@ impl TextMapPropagator for Propagator { format!("{:016x}", span_context.span_id().to_u64()), ); - if span_context.is_debug() { + if is_debug { injector.set(B3_DEBUG_FLAG_HEADER, "1".to_string()); - } else if !span_context.is_deferred() { + } else if !is_deferred { let sampled = if span_context.is_sampled() { "1" } else { "0" }; injector.set(B3_SAMPLED_HEADER, sampled.to_string()); } @@ -306,10 +309,7 @@ mod tests { use opentelemetry::{ propagation::TextMapPropagator, testing::trace::TestSpan, - trace::{ - SpanContext, SpanId, TraceId, TRACE_FLAG_DEBUG, TRACE_FLAG_DEFERRED, - TRACE_FLAG_NOT_SAMPLED, TRACE_FLAG_SAMPLED, - }, + trace::{SpanContext, SpanId, TraceFlags, TraceId}, }; use std::collections::HashMap; @@ -322,11 +322,11 @@ mod tests { fn single_header_extract_data() -> Vec<(&'static str, SpanContext)> { vec![ ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEFERRED, true, TraceState::default())), // deferred - ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-0", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), // not sampled - ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_SAMPLED, true, TraceState::default())), // sampled + ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-0", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::default(), true, TraceState::default())), // not sampled + ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::SAMPLED, true, TraceState::default())), // sampled ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-d", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEBUG, true, TraceState::default())), // debug - ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1-00000000000000cd", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), 1, true, TraceState::default())), // with parent span id - ("a3ce929d0e0e4736-00f067aa0ba902b7-1-00000000000000cd", SpanContext::new(TraceId::from_u128(0x0000_0000_0000_0000_a3ce_929d_0e0e_4736), SpanId::from_u64(SPAN_ID_HEX), 1, true, TraceState::default())), // padding 64 bit traceID + ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1-00000000000000cd", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::SAMPLED, true, TraceState::default())), // with parent span id + ("a3ce929d0e0e4736-00f067aa0ba902b7-1-00000000000000cd", SpanContext::new(TraceId::from_u128(0x0000_0000_0000_0000_a3ce_929d_0e0e_4736), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::SAMPLED, true, TraceState::default())), // padding 64 bit traceID ("0", SpanContext::empty_context()), ("-", SpanContext::empty_context()), ] @@ -338,13 +338,13 @@ mod tests { // (TraceId, SpanId, Sampled, FlagId, ParentSpanId) vec![ ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), None, None, None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEFERRED, true, TraceState::default())), // deferred - ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), None, None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), // not sampled - ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("1"), None, None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_SAMPLED, true, TraceState::default())), // sampled - ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("true"), None, None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_SAMPLED, true, TraceState::default())), - ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("false"), None, None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), // use true/false to set sample - ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), None, Some("1"), None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEBUG | TRACE_FLAG_SAMPLED, true, TraceState::default())), // debug - ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), Some("1"), Some("00f067aa0ba90200")), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEBUG | TRACE_FLAG_SAMPLED, true, TraceState::default())), // debug flag should override sample flag - ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("1"), Some("2"), Some("00f067aa0ba90200")), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_SAMPLED, true, TraceState::default())), // invalid debug flag, should ignore + ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), None, None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::default(), true, TraceState::default())), // not sampled + ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("1"), None, None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::SAMPLED, true, TraceState::default())), // sampled + ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("true"), None, None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::SAMPLED, true, TraceState::default())), + ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("false"), None, None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::default(), true, TraceState::default())), // use true/false to set sample + ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), None, Some("1"), None), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEBUG | TraceFlags::SAMPLED, true, TraceState::default())), // debug + ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), Some("1"), Some("00f067aa0ba90200")), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEBUG | TraceFlags::SAMPLED, true, TraceState::default())), // debug flag should override sample flag + ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("1"), Some("2"), Some("00f067aa0ba90200")), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::SAMPLED, true, TraceState::default())), // invalid debug flag, should ignore ((None, None, Some("0"), None, None), SpanContext::empty_context()), ] } @@ -392,21 +392,21 @@ mod tests { // (TraceId, SpanId, Sampled, FlagId, ParentSpanId), b3 vec![ ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), None, None, None), "4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-0", - SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), // single header take precedence - ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), None, None), "-", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), // when single header is invalid, fall back to multiple headers - ((Some("0"), Some("0"), Some("0"), None, None), "4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-0", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())) // invalid multiple header should go unnoticed since single header take precedence. + SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::default(), true, TraceState::default())), // single header take precedence + ((Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), None, None), "-", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::default(), true, TraceState::default())), // when single header is invalid, fall back to multiple headers + ((Some("0"), Some("0"), Some("0"), None, None), "4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-0", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::default(), true, TraceState::default())) // invalid multiple header should go unnoticed since single header take precedence. ] } #[rustfmt::skip] fn single_header_inject_data() -> Vec<(&'static str, SpanContext)> { vec![ - ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_SAMPLED, true, TraceState::default())), + ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::SAMPLED, true, TraceState::default())), ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-d", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEBUG, true, TraceState::default())), ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEFERRED, true, TraceState::default())), - ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-0", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), - ("1", SpanContext::new(TraceId::invalid(), SpanId::invalid(), TRACE_FLAG_SAMPLED, true, TraceState::default())), - ("0", SpanContext::new(TraceId::invalid(), SpanId::invalid(), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), + ("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-0", SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::default(), true, TraceState::default())), + ("1", SpanContext::new(TraceId::invalid(), SpanId::invalid(), TraceFlags::SAMPLED, true, TraceState::default())), + ("0", SpanContext::new(TraceId::invalid(), SpanId::invalid(), TraceFlags::default(), true, TraceState::default())), ] } @@ -415,12 +415,12 @@ mod tests { fn multi_header_inject_data() -> Vec<(Option<&'static str>, Option<&'static str>, Option<&'static str>, Option<&'static str>, SpanContext)> { // TraceId, SpanId, isSampled, isDebug vec![ - (Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("1"), None, SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_SAMPLED, true, TraceState::default())), + (Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("1"), None, SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::SAMPLED, true, TraceState::default())), (Some(TRACE_ID_STR), Some(SPAN_ID_STR), None, Some("1"), SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEBUG, true, TraceState::default())), (Some(TRACE_ID_STR), Some(SPAN_ID_STR), None, None, SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_DEFERRED, true, TraceState::default())), - (Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), None, SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), + (Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), None, SpanContext::new(TraceId::from_u128(TRACE_ID_HEX), SpanId::from_u64(SPAN_ID_HEX), TraceFlags::default(), true, TraceState::default())), (None, None, Some("0"), None, SpanContext::empty_context()), - (None, None, Some("1"), None, SpanContext::new(TraceId::invalid(), SpanId::invalid(), TRACE_FLAG_SAMPLED, true, TraceState::default())) + (None, None, Some("1"), None, SpanContext::new(TraceId::invalid(), SpanId::invalid(), TraceFlags::SAMPLED, true, TraceState::default())) ] } @@ -430,12 +430,12 @@ mod tests { let trace_id: TraceId = TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736); let span_id: SpanId = SpanId::from_u64(0x00f0_67aa_0ba9_02b7); vec![ - (Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("1"), None, Some("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1"), SpanContext::new(trace_id, span_id, TRACE_FLAG_SAMPLED, true, TraceState::default())), // sampled + (Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("1"), None, Some("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1"), SpanContext::new(trace_id, span_id, TraceFlags::SAMPLED, true, TraceState::default())), // sampled (Some(TRACE_ID_STR), Some(SPAN_ID_STR), None, Some("1"), Some("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-d"), SpanContext::new(trace_id, span_id, TRACE_FLAG_DEBUG, true, TraceState::default())), // debug - (Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), None, Some("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-0"), SpanContext::new(trace_id, span_id, TRACE_FLAG_NOT_SAMPLED, true, TraceState::default())), // not sampled + (Some(TRACE_ID_STR), Some(SPAN_ID_STR), Some("0"), None, Some("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-0"), SpanContext::new(trace_id, span_id, TraceFlags::default(), true, TraceState::default())), // not sampled (Some(TRACE_ID_STR), Some(SPAN_ID_STR), None, None, Some("4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7"), SpanContext::new(trace_id, span_id, TRACE_FLAG_DEFERRED, true, TraceState::default())), // unset sampled (None, None, Some("0"), None, Some("0"), SpanContext::empty_context()), - (None, None, Some("1"), None, Some("1"), SpanContext::new(TraceId::invalid(), SpanId::invalid(), TRACE_FLAG_SAMPLED, true, TraceState::default())), + (None, None, Some("1"), None, Some("1"), SpanContext::new(TraceId::invalid(), SpanId::invalid(), TraceFlags::SAMPLED, true, TraceState::default())), ] } diff --git a/opentelemetry/Cargo.toml b/opentelemetry/Cargo.toml index 4e525a5ab4..c904c3e79b 100644 --- a/opentelemetry/Cargo.toml +++ b/opentelemetry/Cargo.toml @@ -43,15 +43,13 @@ js-sys = "0.3" bincode = "1.2" criterion = "0.3.1" rand_distr = "0.4.0" -tokio = { version = "1.0", features = ["full"] } -tokio-stream = "0.1" [features] default = ["trace"] trace = ["crossbeam-channel", "rand", "pin-project", "async-trait", "percent-encoding"] metrics = ["dashmap", "fnv"] serialize = ["serde"] -testing = ["trace", "metrics", "rt-async-std", "rt-tokio", "rt-tokio-current-thread"] +testing = ["trace", "metrics", "rt-async-std", "rt-tokio", "rt-tokio-current-thread", "tokio/macros", "tokio/rt-multi-thread"] rt-tokio = ["tokio", "tokio-stream"] rt-tokio-current-thread = ["tokio", "tokio-stream"] rt-async-std = ["async-std"] diff --git a/opentelemetry/benches/batch_span_processor.rs b/opentelemetry/benches/batch_span_processor.rs index 5925502747..06af5adb1a 100644 --- a/opentelemetry/benches/batch_span_processor.rs +++ b/opentelemetry/benches/batch_span_processor.rs @@ -3,7 +3,7 @@ use opentelemetry::runtime::Tokio; use opentelemetry::sdk::export::trace::SpanData; use opentelemetry::sdk::trace::{BatchSpanProcessor, EvictedHashMap, EvictedQueue, SpanProcessor}; use opentelemetry::trace::{ - NoopSpanExporter, SpanContext, SpanId, SpanKind, StatusCode, TraceId, TraceState, + NoopSpanExporter, SpanContext, SpanId, SpanKind, StatusCode, TraceFlags, TraceId, TraceState, }; use std::sync::Arc; use std::time::SystemTime; @@ -16,7 +16,7 @@ fn get_span_data() -> Vec { span_context: SpanContext::new( TraceId::from_u128(12), SpanId::from_u64(12), - 0, + TraceFlags::default(), false, TraceState::default(), ), diff --git a/opentelemetry/src/global/trace.rs b/opentelemetry/src/global/trace.rs index b78ef8e45d..b8c5fddc87 100644 --- a/opentelemetry/src/global/trace.rs +++ b/opentelemetry/src/global/trace.rs @@ -332,7 +332,9 @@ mod tests { use crate::runtime; #[cfg(any(feature = "rt-tokio", feature = "rt-tokio-current-thread"))] use crate::sdk::trace::TraceRuntime; - use crate::trace::{NoopTracer, Tracer}; + use crate::trace::NoopTracer; + #[cfg(any(feature = "rt-tokio", feature = "rt-tokio-current-thread"))] + use crate::trace::Tracer; use std::{ fmt::Debug, io::Write, @@ -346,6 +348,7 @@ mod tests { buf: Arc>>, } + #[cfg(any(feature = "rt-tokio", feature = "rt-tokio-current-thread"))] impl AssertWriter { fn new() -> AssertWriter { AssertWriter { @@ -492,6 +495,7 @@ mod tests { .build() } + #[cfg(any(feature = "rt-tokio", feature = "rt-tokio-current-thread"))] fn build_simple_tracer_provider( assert_writer: AssertWriter, ) -> crate::sdk::trace::TracerProvider { @@ -551,6 +555,7 @@ mod tests { // Expected to see the spans being exported to buffer #[tokio::test] #[ignore = "requires --test-threads=1"] + #[cfg(feature = "rt-tokio")] async fn test_set_provider_single_thread_tokio_with_simple_processor() { let assert_writer = AssertWriter::new(); let _ = set_tracer_provider(build_simple_tracer_provider(assert_writer.clone())); diff --git a/opentelemetry/src/sdk/export/trace/mod.rs b/opentelemetry/src/sdk/export/trace/mod.rs index a3dce88c45..eca1828e12 100644 --- a/opentelemetry/src/sdk/export/trace/mod.rs +++ b/opentelemetry/src/sdk/export/trace/mod.rs @@ -91,14 +91,14 @@ pub struct SpanData { #[cfg(test)] mod tests { use super::*; - use crate::trace::{TraceId, TraceState}; + use crate::trace::{TraceFlags, TraceId, TraceState}; #[test] fn test_serialise() { let trace_id = 7; let span_id = 99; - let trace_flags = 0; + let trace_flags = TraceFlags::default(); let remote = false; let span_context = SpanContext::new( TraceId::from_u128(trace_id), diff --git a/opentelemetry/src/sdk/propagation/composite.rs b/opentelemetry/src/sdk/propagation/composite.rs index 672d772f02..a7d71ee84a 100644 --- a/opentelemetry/src/sdk/propagation/composite.rs +++ b/opentelemetry/src/sdk/propagation/composite.rs @@ -113,7 +113,7 @@ mod tests { use crate::testing::trace::TestSpan; use crate::{ propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator}, - trace::{SpanContext, SpanId, TraceContextExt, TraceId, TraceState}, + trace::{SpanContext, SpanId, TraceContextExt, TraceFlags, TraceId, TraceState}, Context, }; use std::collections::HashMap; @@ -143,7 +143,7 @@ mod tests { injector.set( "testheader", format!( - "{}-{}-{}", + "{}-{}-{:02x}", span_context.trace_id().to_u128(), span_context.span_id().to_u64(), span_context.trace_flags() @@ -160,7 +160,7 @@ mod tests { SpanContext::new( TraceId::from_u128(u128::from_str(parts[0]).unwrap_or(0)), SpanId::from_u64(u64::from_str(parts[1]).unwrap_or(0)), - u8::from_str(parts[2]).unwrap_or(0), + TraceFlags::new(u8::from_str(parts[2]).unwrap_or(0)), true, TraceState::default(), ) @@ -179,7 +179,7 @@ mod tests { fn test_data() -> Vec<(&'static str, &'static str)> { vec![ - ("testheader", "1-1-0"), + ("testheader", "1-1-00"), ( "traceparent", "00-00000000000000000000000000000001-0000000000000001-00", @@ -194,7 +194,7 @@ mod tests { let cx = Context::default().with_span(TestSpan(SpanContext::new( TraceId::from_u128(1), SpanId::from_u64(1), - 0, + TraceFlags::default(), false, TraceState::default(), ))); @@ -228,7 +228,7 @@ mod tests { let cx = Context::default().with_span(TestSpan(SpanContext::new( TraceId::from_u128(1), SpanId::from_u64(1), - 0, + TraceFlags::default(), false, TraceState::default(), ))); @@ -260,7 +260,7 @@ mod tests { &SpanContext::new( TraceId::from_u128(1), SpanId::from_u64(1), - 0, + TraceFlags::default(), true, TraceState::default(), ) diff --git a/opentelemetry/src/sdk/propagation/trace_context.rs b/opentelemetry/src/sdk/propagation/trace_context.rs index 7f4c65c83d..f6343ebb54 100644 --- a/opentelemetry/src/sdk/propagation/trace_context.rs +++ b/opentelemetry/src/sdk/propagation/trace_context.rs @@ -19,7 +19,7 @@ //! [w3c trace-context docs]: https://w3c.github.io/trace-context/ use crate::{ propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator}, - trace::{SpanContext, SpanId, TraceContextExt, TraceId, TraceState, TRACE_FLAG_SAMPLED}, + trace::{SpanContext, SpanId, TraceContextExt, TraceFlags, TraceId, TraceState}, Context, }; use std::str::FromStr; @@ -95,7 +95,7 @@ impl TraceContextPropagator { // Build trace flags clearing all flags other than the trace-context // supported sampling bit. - let trace_flags = opts & TRACE_FLAG_SAMPLED; + let trace_flags = TraceFlags::new(opts) & TraceFlags::SAMPLED; let trace_state: TraceState = TraceState::from_str(extractor.get(TRACESTATE_HEADER).unwrap_or("")) @@ -125,7 +125,7 @@ impl TextMapPropagator for TraceContextPropagator { SUPPORTED_VERSION, span_context.trace_id().to_u128(), span_context.span_id().to_u64(), - span_context.trace_flags() & TRACE_FLAG_SAMPLED + span_context.trace_flags() & TraceFlags::SAMPLED ); injector.set(TRACEPARENT_HEADER, header_value); injector.set(TRACESTATE_HEADER, span_context.trace_state().header()); @@ -161,14 +161,14 @@ mod tests { #[rustfmt::skip] fn extract_data() -> Vec<(&'static str, &'static str, SpanContext)> { vec![ - ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 0, true, TraceState::from_str("foo=bar").unwrap())), - ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::from_str("foo=bar").unwrap())), - ("02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::from_str("foo=bar").unwrap())), - ("02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::from_str("foo=bar").unwrap())), - ("02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-08", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 0, true, TraceState::from_str("foo=bar").unwrap())), - ("02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09-XYZxsf09", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::from_str("foo=bar").unwrap())), - ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01-", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::from_str("foo=bar").unwrap())), - ("01-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09-", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::from_str("foo=bar").unwrap())), + ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::default(), true, TraceState::from_str("foo=bar").unwrap())), + ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::from_str("foo=bar").unwrap())), + ("02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::from_str("foo=bar").unwrap())), + ("02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::from_str("foo=bar").unwrap())), + ("02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-08", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::default(), true, TraceState::from_str("foo=bar").unwrap())), + ("02-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09-XYZxsf09", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::from_str("foo=bar").unwrap())), + ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01-", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::from_str("foo=bar").unwrap())), + ("01-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-09-", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::from_str("foo=bar").unwrap())), ] } @@ -197,9 +197,9 @@ mod tests { #[rustfmt::skip] fn inject_data() -> Vec<(&'static str, &'static str, SpanContext)> { vec![ - ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 1, true, TraceState::from_str("foo=bar").unwrap())), - ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 0, true, TraceState::from_str("foo=bar").unwrap())), - ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), 0xff, true, TraceState::from_str("foo=bar").unwrap())), + ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::SAMPLED, true, TraceState::from_str("foo=bar").unwrap())), + ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::default(), true, TraceState::from_str("foo=bar").unwrap())), + ("00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01", "foo=bar", SpanContext::new(TraceId::from_u128(0x4bf9_2f35_77b3_4da6_a3ce_929d_0e0e_4736), SpanId::from_u64(0x00f0_67aa_0ba9_02b7), TraceFlags::new(0xff), true, TraceState::from_str("foo=bar").unwrap())), ("", "", SpanContext::empty_context()), ] } diff --git a/opentelemetry/src/sdk/trace/sampler.rs b/opentelemetry/src/sdk/trace/sampler.rs index c05c79d320..048c24c0a5 100644 --- a/opentelemetry/src/sdk/trace/sampler.rs +++ b/opentelemetry/src/sdk/trace/sampler.rs @@ -165,7 +165,7 @@ mod tests { use super::*; use crate::sdk::trace::{Sampler, SamplingDecision, ShouldSample}; use crate::testing::trace::TestSpan; - use crate::trace::{SpanContext, SpanId, TraceState, TRACE_FLAG_SAMPLED}; + use crate::trace::{SpanContext, SpanId, TraceFlags, TraceState}; use rand::Rng; #[rustfmt::skip] @@ -222,7 +222,11 @@ mod tests { let mut sampled = 0; for _ in 0..total { let parent_context = if parent { - let trace_flags = if sample_parent { TRACE_FLAG_SAMPLED } else { 0 }; + let trace_flags = if sample_parent { + TraceFlags::SAMPLED + } else { + TraceFlags::default() + }; let span_context = SpanContext::new( TraceId::from_u128(1), SpanId::from_u64(1), diff --git a/opentelemetry/src/sdk/trace/span.rs b/opentelemetry/src/sdk/trace/span.rs index 0830af6a93..188ea8f26b 100644 --- a/opentelemetry/src/sdk/trace/span.rs +++ b/opentelemetry/src/sdk/trace/span.rs @@ -219,7 +219,7 @@ mod tests { use crate::sdk::trace::span_limit::{ DEFAULT_MAX_ATTRIBUTES_PER_EVENT, DEFAULT_MAX_ATTRIBUTES_PER_LINK, }; - use crate::trace::{Link, NoopSpanExporter, TraceId, Tracer}; + use crate::trace::{Link, NoopSpanExporter, TraceFlags, TraceId, Tracer}; use crate::{core::KeyValue, trace::Span as _, trace::TracerProvider}; use std::time::Duration; @@ -525,7 +525,7 @@ mod tests { SpanContext::new( TraceId::from_u128(12), SpanId::from_u64(12), - 0, + TraceFlags::default(), false, Default::default(), ), diff --git a/opentelemetry/src/sdk/trace/tracer.rs b/opentelemetry/src/sdk/trace/tracer.rs index d038e10da5..b74d8cb4f0 100644 --- a/opentelemetry/src/sdk/trace/tracer.rs +++ b/opentelemetry/src/sdk/trace/tracer.rs @@ -17,8 +17,8 @@ use crate::sdk::{ InstrumentationLibrary, }; use crate::trace::{ - Link, SpanBuilder, SpanContext, SpanId, SpanKind, StatusCode, TraceContextExt, TraceId, - TraceState, TRACE_FLAG_SAMPLED, + Link, SpanBuilder, SpanContext, SpanId, SpanKind, StatusCode, TraceContextExt, TraceFlags, + TraceId, TraceState, }; use crate::{Context, KeyValue}; use std::borrow::Cow; @@ -76,7 +76,7 @@ impl Tracer { attributes: &[KeyValue], links: &[Link], config: &Config, - ) -> Option<(u8, Vec, TraceState)> { + ) -> Option<(TraceFlags, Vec, TraceState)> { let sampling_result = config.sampler.should_sample( Some(parent_cx), trace_id, @@ -93,7 +93,7 @@ impl Tracer { &self, sampling_result: SamplingResult, parent_cx: &Context, - ) -> Option<(u8, Vec, TraceState)> { + ) -> Option<(TraceFlags, Vec, TraceState)> { match sampling_result { SamplingResult { decision: SamplingDecision::Drop, @@ -105,7 +105,7 @@ impl Tracer { trace_state, } => { let trace_flags = parent_cx.span().span_context().trace_flags(); - Some((trace_flags & !TRACE_FLAG_SAMPLED, attributes, trace_state)) + Some((trace_flags.with_sampled(false), attributes, trace_state)) } SamplingResult { decision: SamplingDecision::RecordAndSample, @@ -113,7 +113,7 @@ impl Tracer { trace_state, } => { let trace_flags = parent_cx.span().span_context().trace_flags(); - Some((trace_flags | TRACE_FLAG_SAMPLED, attributes, trace_state)) + Some((trace_flags.with_sampled(true), attributes, trace_state)) } } } @@ -187,7 +187,7 @@ impl crate::trace::Tracer for Tracer { let span_kind = builder.span_kind.take().unwrap_or(SpanKind::Internal); let mut attribute_options = builder.attributes.take().unwrap_or_else(Vec::new); let mut link_options = builder.links.take(); - let mut flags = 0; + let mut flags = TraceFlags::default(); let mut span_trace_state = Default::default(); let parent_span = if builder.parent_context.has_active_span() { @@ -216,7 +216,7 @@ impl crate::trace::Tracer for Tracer { .unwrap_or_else(|| config.id_generator.new_trace_id()), SpanId::invalid(), false, - 0, + TraceFlags::default(), )); // There are 3 paths for sampling. @@ -333,8 +333,8 @@ mod tests { }, testing::trace::TestSpan, trace::{ - Link, Span, SpanBuilder, SpanContext, SpanId, SpanKind, TraceContextExt, TraceId, - TraceState, Tracer, TracerProvider, TRACE_FLAG_NOT_SAMPLED, TRACE_FLAG_SAMPLED, + Link, Span, SpanBuilder, SpanContext, SpanId, SpanKind, TraceContextExt, TraceFlags, + TraceId, TraceState, Tracer, TracerProvider, }, Context, KeyValue, }; @@ -380,7 +380,7 @@ mod tests { parent_context: Context::new().with_span(TestSpan(SpanContext::new( TraceId::from_u128(128), SpanId::from_u64(64), - TRACE_FLAG_SAMPLED, + TraceFlags::SAMPLED, true, trace_state, ))), @@ -426,7 +426,7 @@ mod tests { .with_remote_span_context(SpanContext::new( TraceId::from_u128(1), SpanId::from_u64(1), - TRACE_FLAG_NOT_SAMPLED, + TraceFlags::default(), true, Default::default(), )) diff --git a/opentelemetry/src/trace/mod.rs b/opentelemetry/src/trace/mod.rs index f41b78cae1..0797bc8276 100644 --- a/opentelemetry/src/trace/mod.rs +++ b/opentelemetry/src/trace/mod.rs @@ -189,10 +189,7 @@ pub use self::{ noop::{NoopSpan, NoopSpanExporter, NoopTracer, NoopTracerProvider}, provider::TracerProvider, span::{Span, SpanKind, StatusCode}, - span_context::{ - SpanContext, SpanId, TraceId, TraceState, TRACE_FLAG_DEBUG, TRACE_FLAG_DEFERRED, - TRACE_FLAG_NOT_SAMPLED, TRACE_FLAG_SAMPLED, - }, + span_context::{SpanContext, SpanId, TraceFlags, TraceId, TraceState}, tracer::{SpanBuilder, Tracer}, }; use crate::sdk::export::ExportError; diff --git a/opentelemetry/src/trace/noop.rs b/opentelemetry/src/trace/noop.rs index 267dcaad0d..951329f87d 100644 --- a/opentelemetry/src/trace/noop.rs +++ b/opentelemetry/src/trace/noop.rs @@ -7,7 +7,7 @@ use crate::trace::TraceResult; use crate::{ sdk::export::trace::{ExportResult, SpanData, SpanExporter}, trace, - trace::{SpanBuilder, TraceContextExt, TraceState}, + trace::{SpanBuilder, TraceContextExt, TraceFlags, TraceState}, Context, KeyValue, }; use async_trait::async_trait; @@ -59,7 +59,7 @@ impl NoopSpan { span_context: trace::SpanContext::new( trace::TraceId::invalid(), trace::SpanId::invalid(), - 0, + TraceFlags::default(), false, TraceState::default(), ), @@ -201,7 +201,7 @@ mod tests { trace::SpanContext::new( trace::TraceId::from_u128(42), trace::SpanId::from_u64(42), - 0, + trace::TraceFlags::default(), true, TraceState::default(), ) diff --git a/opentelemetry/src/trace/span_context.rs b/opentelemetry/src/trace/span_context.rs index bbbe58620f..c226e12536 100644 --- a/opentelemetry/src/trace/span_context.rs +++ b/opentelemetry/src/trace/span_context.rs @@ -13,19 +13,84 @@ #[cfg(feature = "serialize")] use serde::{Deserialize, Serialize}; use std::collections::VecDeque; +use std::fmt; +use std::ops::{BitAnd, BitOr, Not}; use std::str::FromStr; -/// A SpanContext with TRACE_FLAG_NOT_SAMPLED means the span is not sampled. -pub const TRACE_FLAG_NOT_SAMPLED: u8 = 0x00; -/// TRACE_FLAG_SAMPLED is a bitmask with the sampled bit set. A SpanContext -/// with the sampling bit set means the span is sampled. -pub const TRACE_FLAG_SAMPLED: u8 = 0x01; -/// TRACE_FLAGS_DEFERRED is a bitmask with the deferred bit set. A SpanContext -/// with the deferred bit set means the sampling decision has been -/// defered to the receiver. -pub const TRACE_FLAG_DEFERRED: u8 = 0x02; -/// TRACE_FLAGS_DEBUG is a bitmask with the debug bit set. -pub const TRACE_FLAG_DEBUG: u8 = 0x04; +/// Flags that can be set on a [`SpanContext`]. +/// +/// The current version of the specification only supports a single flag called `sampled`. +/// +/// See the W3C TraceContext specification's [trace-flags] section for more details. +/// +/// [trace-flags]: https://www.w3.org/TR/trace-context/#trace-flags +#[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))] +#[derive(Clone, Debug, Default, PartialEq, Eq, Copy, Hash)] +pub struct TraceFlags(u8); + +impl TraceFlags { + /// Trace flags with the `sampled` flag set to `1`. + /// + /// Spans that are not sampled will be ignored by most tracing tools. + /// See the `sampled` section of the [W3C TraceContext specification] for details. + /// + /// [W3C TraceContext specification]: https://www.w3.org/TR/trace-context/#sampled-flag + pub const SAMPLED: TraceFlags = TraceFlags(0x01); + + /// Construct new trace flags + pub const fn new(flags: u8) -> Self { + TraceFlags(flags) + } + + /// Returns `true` if the `sampled` flag is set + pub fn is_sampled(&self) -> bool { + (*self & TraceFlags::SAMPLED) == TraceFlags::SAMPLED + } + + /// Returns copy of the current flags with the `sampled` flag set. + pub fn with_sampled(&self, sampled: bool) -> Self { + if sampled { + *self | TraceFlags::SAMPLED + } else { + *self & !TraceFlags::SAMPLED + } + } + + /// Returns the flags as a `u8` + pub fn to_u8(self) -> u8 { + self.0 + } +} + +impl BitAnd for TraceFlags { + type Output = Self; + + fn bitand(self, rhs: Self) -> Self::Output { + Self(self.0 & rhs.0) + } +} + +impl BitOr for TraceFlags { + type Output = Self; + + fn bitor(self, rhs: Self) -> Self::Output { + Self(self.0 | rhs.0) + } +} + +impl Not for TraceFlags { + type Output = Self; + + fn not(self) -> Self::Output { + Self(!self.0) + } +} + +impl fmt::LowerHex for TraceFlags { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + fmt::LowerHex::fmt(&self.0, f) + } +} /// TraceId is an 16-byte value which uniquely identifies a given trace /// The actual `u128` value is wrapped in a tuple struct in order to leverage the newtype pattern @@ -307,12 +372,15 @@ impl FromStr for TraceState { } /// Immutable portion of a `Span` which can be serialized and propagated. +/// +/// Spans that do not have the `sampled` flag set in their [`TraceFlags`] will +/// be ignored by most tracing tools. #[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))] #[derive(Clone, Debug, PartialEq)] pub struct SpanContext { trace_id: TraceId, span_id: SpanId, - trace_flags: u8, + trace_flags: TraceFlags, is_remote: bool, trace_state: TraceState, } @@ -323,7 +391,7 @@ impl SpanContext { SpanContext::new( TraceId::invalid(), SpanId::invalid(), - 0, + TraceFlags::default(), false, TraceState::default(), ) @@ -333,7 +401,7 @@ impl SpanContext { pub fn new( trace_id: TraceId, span_id: SpanId, - trace_flags: u8, + trace_flags: TraceFlags, is_remote: bool, trace_state: TraceState, ) -> Self { @@ -358,7 +426,7 @@ impl SpanContext { /// Returns details about the trace. Unlike `TraceState` values, these are /// present in all traces. Currently, the only option is a boolean sampled flag. - pub fn trace_flags(&self) -> u8 { + pub fn trace_flags(&self) -> TraceFlags { self.trace_flags } @@ -373,19 +441,11 @@ impl SpanContext { self.is_remote } - /// Returns if the deferred bit is set in the trace flags - pub fn is_deferred(&self) -> bool { - (self.trace_flags & TRACE_FLAG_DEFERRED) == TRACE_FLAG_DEFERRED - } - - /// Returns if the debug bit is set in the trace flags - pub fn is_debug(&self) -> bool { - (self.trace_flags & TRACE_FLAG_DEBUG) == TRACE_FLAG_DEBUG - } - - /// Returns true if the `SpanContext` is sampled. + /// Returns `true` if the `sampled` trace flag is set. + /// + /// Spans that are not sampled will be ignored by most tracing tools. pub fn is_sampled(&self) -> bool { - (self.trace_flags & TRACE_FLAG_SAMPLED) == TRACE_FLAG_SAMPLED + self.trace_flags.is_sampled() } /// Returns the context's `TraceState`. diff --git a/opentelemetry/src/util.rs b/opentelemetry/src/util.rs index 65d0ea2228..adad9cc6d5 100644 --- a/opentelemetry/src/util.rs +++ b/opentelemetry/src/util.rs @@ -1,7 +1,7 @@ //! Internal utilities /// Helper which wraps `tokio::time::interval` and makes it return a stream -#[cfg(any(test, feature = "rt-tokio", feature = "rt-tokio-current-thread"))] +#[cfg(any(feature = "rt-tokio", feature = "rt-tokio-current-thread"))] pub fn tokio_interval_stream( period: std::time::Duration, ) -> tokio_stream::wrappers::IntervalStream { diff --git a/scripts/lint.sh b/scripts/lint.sh index 648fcde876..4c080c20a3 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -14,7 +14,7 @@ if rustup component add clippy; then `# Exit with a nonzero code if there are clippy warnings` \ -Dwarnings - cargo_feature opentelemetry "trace,rt-tokio,rt-tokio-current-thread,rt-async-std" + cargo_feature opentelemetry "trace,rt-tokio,rt-tokio-current-thread,rt-async-std,testing" cargo_feature opentelemetry-otlp "default" cargo_feature opentelemetry-otlp "default,tls"