diff --git a/opentelemetry-jaeger/src/exporter/thrift/mod.rs b/opentelemetry-jaeger/src/exporter/thrift/mod.rs index 3679862608..118a126daf 100644 --- a/opentelemetry-jaeger/src/exporter/thrift/mod.rs +++ b/opentelemetry-jaeger/src/exporter/thrift/mod.rs @@ -42,6 +42,14 @@ impl From for jaeger::Log { fields.push(Key::new("event").string(event.name).into()); } + if event.dropped_attributes_count != 0 { + fields.push( + Key::new("otel.event.dropped_attributes_count") + .i64(i64::from(event.dropped_attributes_count)) + .into(), + ); + } + jaeger::Log::new(timestamp, fields) } } diff --git a/opentelemetry-otlp/src/transform/traces.rs b/opentelemetry-otlp/src/transform/traces.rs index 6f9491f865..305cb9f576 100644 --- a/opentelemetry-otlp/src/transform/traces.rs +++ b/opentelemetry-otlp/src/transform/traces.rs @@ -50,7 +50,7 @@ mod tonic { .to_vec(), trace_state: link.span_context().trace_state().header(), attributes: Attributes::from(link.attributes().clone()).0, - dropped_attributes_count: 0, + dropped_attributes_count: link.dropped_attributes_count(), } } } @@ -103,7 +103,7 @@ mod tonic { time_unix_nano: to_nanos(event.timestamp), name: event.name.into(), attributes: Attributes::from(event.attributes).0, - dropped_attributes_count: 0, + dropped_attributes_count: event.dropped_attributes_count, }) .collect(), dropped_links_count: source_span.links.dropped_count(), @@ -179,7 +179,7 @@ mod prost { .to_vec(), trace_state: link.span_context().trace_state().header(), attributes: Attributes::from(link.attributes().clone()).0, - dropped_attributes_count: 0, + dropped_attributes_count: link.dropped_attributes_count(), } } } @@ -232,7 +232,7 @@ mod prost { time_unix_nano: to_nanos(event.timestamp), name: event.name.into(), attributes: Attributes::from(event.attributes).0, - dropped_attributes_count: 0, + dropped_attributes_count: event.dropped_attributes_count, }) .collect(), dropped_links_count: source_span.links.dropped_count(), @@ -311,7 +311,7 @@ mod grpcio { .to_vec(), trace_state: link.span_context().trace_state().header(), attributes: Attributes::from(link.attributes().clone()).0, - dropped_attributes_count: 0, + dropped_attributes_count: link.dropped_attributes_count(), ..Default::default() } } @@ -367,7 +367,7 @@ mod grpcio { time_unix_nano: to_nanos(event.timestamp), name: event.name.into(), attributes: Attributes::from(event.attributes).0, - dropped_attributes_count: 0, + dropped_attributes_count: event.dropped_attributes_count, ..Default::default() }) .collect(), diff --git a/opentelemetry/src/sdk/trace/config.rs b/opentelemetry/src/sdk/trace/config.rs index 54ca40f77d..199b644645 100644 --- a/opentelemetry/src/sdk/trace/config.rs +++ b/opentelemetry/src/sdk/trace/config.rs @@ -20,8 +20,8 @@ pub struct Config { pub sampler: Box, /// The id generator that the sdk should use pub id_generator: Box, - /// span limit - pub span_limit: SpanLimits, + /// span limits + pub span_limits: SpanLimits, /// Contains attributes representing an entity that produces telemetry. pub resource: Option>, } @@ -41,37 +41,37 @@ impl Config { /// Specify the number of events to be recorded per span. pub fn with_max_events_per_span(mut self, max_events: u32) -> Self { - self.span_limit.max_events_per_span = max_events; + self.span_limits.max_events_per_span = max_events; self } /// Specify the number of attributes to be recorded per span. pub fn with_max_attributes_per_span(mut self, max_attributes: u32) -> Self { - self.span_limit.max_attributes_per_span = max_attributes; + self.span_limits.max_attributes_per_span = max_attributes; self } /// Specify the number of events to be recorded per span. pub fn with_max_links_per_span(mut self, max_links: u32) -> Self { - self.span_limit.max_links_per_span = max_links; + self.span_limits.max_links_per_span = max_links; self } /// Specify the number of attributes one event can have. pub fn with_max_attributes_per_event(mut self, max_attributes: u32) -> Self { - self.span_limit.max_attributes_per_event = max_attributes; + self.span_limits.max_attributes_per_event = max_attributes; self } /// Specify the number of attributes one link can have. pub fn with_max_attributes_per_link(mut self, max_attributes: u32) -> Self { - self.span_limit.max_attributes_per_link = max_attributes; + self.span_limits.max_attributes_per_link = max_attributes; self } - /// Specify all limit via the span_limit - pub fn with_span_limit(mut self, span_limit: SpanLimits) -> Self { - self.span_limit = span_limit; + /// Specify all limit via the span_limits + pub fn with_span_limits(mut self, span_limits: SpanLimits) -> Self { + self.span_limits = span_limits; self } @@ -88,7 +88,7 @@ impl Default for Config { let mut config = Config { sampler: Box::new(Sampler::ParentBased(Box::new(Sampler::AlwaysOn))), id_generator: Box::new(sdk::trace::IdGenerator::default()), - span_limit: SpanLimits::default(), + span_limits: SpanLimits::default(), resource: None, }; @@ -96,21 +96,21 @@ impl Default for Config { .ok() .and_then(|count_limit| u32::from_str(&count_limit).ok()) { - config.span_limit.max_attributes_per_span = max_attributes_per_span; + config.span_limits.max_attributes_per_span = max_attributes_per_span; } if let Some(max_events_per_span) = env::var("OTEL_SPAN_EVENT_COUNT_LIMIT") .ok() .and_then(|max_events| u32::from_str(&max_events).ok()) { - config.span_limit.max_events_per_span = max_events_per_span; + config.span_limits.max_events_per_span = max_events_per_span; } if let Some(max_links_per_span) = env::var("OTEL_SPAN_LINK_COUNT_LIMIT") .ok() .and_then(|max_links| u32::from_str(&max_links).ok()) { - config.span_limit.max_links_per_span = max_links_per_span; + config.span_limits.max_links_per_span = max_links_per_span; } config diff --git a/opentelemetry/src/sdk/trace/span.rs b/opentelemetry/src/sdk/trace/span.rs index a27a9e5fbf..42c112e142 100644 --- a/opentelemetry/src/sdk/trace/span.rs +++ b/opentelemetry/src/sdk/trace/span.rs @@ -21,7 +21,7 @@ pub struct Span { span_context: SpanContext, data: Option, tracer: sdk::trace::Tracer, - span_limit: SpanLimits, + span_limits: SpanLimits, } #[derive(Clone, Debug, PartialEq)] @@ -59,7 +59,7 @@ impl Span { span_context, data, tracer, - span_limit, + span_limits: span_limit, } } @@ -84,14 +84,17 @@ impl crate::trace::Span for Span { timestamp: SystemTime, mut attributes: Vec, ) { - let max_attributes_per_event = self.span_limit.max_attributes_per_event as usize; + let event_attributes_limit = self.span_limits.max_attributes_per_event as usize; self.with_data(|data| { - if attributes.len() > max_attributes_per_event { - attributes.truncate(max_attributes_per_event); - } - - data.message_events - .push_back(Event::new(name, timestamp, attributes)) + let dropped_attributes_count = attributes.len().saturating_sub(event_attributes_limit); + attributes.truncate(event_attributes_limit); + + data.message_events.push_back(Event::new( + name, + timestamp, + attributes, + dropped_attributes_count as u32, + )) }); } @@ -231,11 +234,11 @@ mod tests { start_time: crate::time::now(), end_time: crate::time::now(), attributes: sdk::trace::EvictedHashMap::new( - config.span_limit.max_attributes_per_span, + config.span_limits.max_attributes_per_span, 0, ), - message_events: sdk::trace::EvictedQueue::new(config.span_limit.max_events_per_span), - links: sdk::trace::EvictedQueue::new(config.span_limit.max_links_per_span), + message_events: sdk::trace::EvictedQueue::new(config.span_limits.max_events_per_span), + links: sdk::trace::EvictedQueue::new(config.span_limits.max_links_per_span), status_code: StatusCode::Unset, status_message: "".into(), }; @@ -531,7 +534,7 @@ mod tests { Vec::new(), ); for i in 0..(DEFAULT_MAX_ATTRIBUTES_PER_LINK * 2) { - link.attributes_mut() + link.attributes .push(KeyValue::new(format!("key {}", i), i.to_string())); } diff --git a/opentelemetry/src/sdk/trace/tracer.rs b/opentelemetry/src/sdk/trace/tracer.rs index 1a5a5eed1f..6002f06339 100644 --- a/opentelemetry/src/sdk/trace/tracer.rs +++ b/opentelemetry/src/sdk/trace/tracer.rs @@ -178,7 +178,7 @@ impl crate::trace::Tracer for Tracer { let provider = provider.unwrap(); let config = provider.config(); - let span_limit = config.span_limit; + let span_limits = config.span_limits; let span_id = builder .span_id .take() @@ -265,30 +265,33 @@ impl crate::trace::Tracer for Tracer { span_trace_state = trace_state; attribute_options.append(&mut extra_attrs); let mut attributes = - EvictedHashMap::new(span_limit.max_attributes_per_span, attribute_options.len()); + EvictedHashMap::new(span_limits.max_attributes_per_span, attribute_options.len()); for attribute in attribute_options { attributes.insert(attribute); } - let mut links = EvictedQueue::new(span_limit.max_links_per_span); + let mut links = EvictedQueue::new(span_limits.max_links_per_span); if let Some(link_options) = &mut link_options { + let link_attributes_limit = span_limits.max_attributes_per_link as usize; for link in link_options.iter_mut() { - // make sure the attributes is less than max_attribute_per_link - let attributes = link.attributes_mut(); - if attributes.len() > span_limit.max_attributes_per_link as usize { - attributes.truncate(span_limit.max_attributes_per_link as usize); - } + let dropped_attributes_count = + link.attributes.len().saturating_sub(link_attributes_limit); + link.attributes.truncate(link_attributes_limit); + link.dropped_attributes_count = dropped_attributes_count as u32; } links.append_vec(link_options); } let start_time = start_time.unwrap_or_else(crate::time::now); let end_time = end_time.unwrap_or(start_time); - let mut message_events_queue = EvictedQueue::new(span_limit.max_events_per_span); + let mut message_events_queue = EvictedQueue::new(span_limits.max_events_per_span); if let Some(mut events) = message_events { + let event_attributes_limit = span_limits.max_attributes_per_event as usize; for event in events.iter_mut() { - let attributes = &mut event.attributes; - if attributes.len() > span_limit.max_attributes_per_event as usize { - attributes.truncate(span_limit.max_attributes_per_event as usize); - } + let dropped_attributes_count = event + .attributes + .len() + .saturating_sub(event_attributes_limit); + event.attributes.truncate(event_attributes_limit); + event.dropped_attributes_count = dropped_attributes_count as u32; } message_events_queue.append_vec(&mut events); } @@ -310,7 +313,7 @@ impl crate::trace::Tracer for Tracer { }); let span_context = SpanContext::new(trace_id, span_id, flags, false, span_trace_state); - let span = Span::new(span_context, inner, self.clone(), span_limit); + let span = Span::new(span_context, inner, self.clone(), span_limits); // Call `on_start` for all processors for processor in provider.span_processors() { diff --git a/opentelemetry/src/testing/trace.rs b/opentelemetry/src/testing/trace.rs index dca9ce7aaf..bb57722d10 100644 --- a/opentelemetry/src/testing/trace.rs +++ b/opentelemetry/src/testing/trace.rs @@ -46,9 +46,9 @@ pub fn new_test_export_span_data() -> SpanData { name: "opentelemetry".into(), start_time: crate::time::now(), end_time: crate::time::now(), - attributes: EvictedHashMap::new(config.span_limit.max_attributes_per_span, 0), - message_events: EvictedQueue::new(config.span_limit.max_events_per_span), - links: EvictedQueue::new(config.span_limit.max_links_per_span), + attributes: EvictedHashMap::new(config.span_limits.max_attributes_per_span, 0), + message_events: EvictedQueue::new(config.span_limits.max_events_per_span), + links: EvictedQueue::new(config.span_limits.max_links_per_span), status_code: StatusCode::Unset, status_message: "".into(), resource: config.resource, diff --git a/opentelemetry/src/trace/event.rs b/opentelemetry/src/trace/event.rs index fddede9368..8d60e52c0a 100644 --- a/opentelemetry/src/trace/event.rs +++ b/opentelemetry/src/trace/event.rs @@ -17,6 +17,8 @@ pub struct Event { pub timestamp: SystemTime, /// Event attributes pub attributes: Vec, + /// Number of dropped attributes + pub dropped_attributes_count: u32, } impl Event { @@ -25,11 +27,13 @@ impl Event { name: T, timestamp: SystemTime, attributes: Vec, + dropped_attributes_count: u32, ) -> Self { Event { name: name.into(), timestamp, attributes, + dropped_attributes_count, } } @@ -39,6 +43,7 @@ impl Event { name: name.into(), timestamp: crate::time::now(), attributes: Vec::new(), + dropped_attributes_count: 0, } } } diff --git a/opentelemetry/src/trace/link.rs b/opentelemetry/src/trace/link.rs index 465ac7a9d6..d4847e6bb7 100644 --- a/opentelemetry/src/trace/link.rs +++ b/opentelemetry/src/trace/link.rs @@ -9,7 +9,8 @@ use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq)] pub struct Link { span_context: SpanContext, - attributes: Vec, + pub(crate) attributes: Vec, + pub(crate) dropped_attributes_count: u32, } impl Link { @@ -18,6 +19,7 @@ impl Link { Link { span_context, attributes, + dropped_attributes_count: 0, } } @@ -31,8 +33,8 @@ impl Link { &self.attributes } - /// Mutable attributes of the link - pub(crate) fn attributes_mut(&mut self) -> &mut Vec { - self.attributes.as_mut() + /// Dropped attributes count + pub fn dropped_attributes_count(&self) -> u32 { + self.dropped_attributes_count } }