From e0c86ee4e2595b4816c56c104b06418254e93d3e Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Wed, 9 Feb 2022 19:02:25 +0100 Subject: [PATCH] opentelemetry: forward event source locations (#1911) This branch adds the source code file, module path, and line number to OpenTelemetry events as the OpenTelemetry `code.filepath`, `code.namespace`, and `code.lineno` fields, respectively, if they are set in the `tracing` event's metadata. Fixes #1910 --- tracing-opentelemetry/src/layer.rs | 45 +++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/tracing-opentelemetry/src/layer.rs b/tracing-opentelemetry/src/layer.rs index 2abbb4a4d6..00678bf1a6 100644 --- a/tracing-opentelemetry/src/layer.rs +++ b/tracing-opentelemetry/src/layer.rs @@ -1,9 +1,11 @@ use crate::{OtelData, PreSampledTracer}; use opentelemetry::{ trace::{self as otel, noop, TraceContextExt}, - Context as OtelContext, Key, KeyValue, + Context as OtelContext, Key, KeyValue, Value, }; use std::any::TypeId; +#[cfg(not(feature = "tracing-log"))] +use std::borrow::Cow; use std::fmt; use std::marker; use std::time::{Instant, SystemTime}; @@ -27,6 +29,7 @@ const SPAN_STATUS_MESSAGE_FIELD: &str = "otel.status_message"; /// [tracing]: https://github.com/tokio-rs/tracing pub struct OpenTelemetryLayer { tracer: T, + event_location: bool, tracked_inactivity: bool, get_context: WithContext, _registry: marker::PhantomData, @@ -289,6 +292,7 @@ where pub fn new(tracer: T) -> Self { OpenTelemetryLayer { tracer, + event_location: true, tracked_inactivity: true, get_context: WithContext(Self::get_context), _registry: marker::PhantomData, @@ -327,12 +331,24 @@ where { OpenTelemetryLayer { tracer, + event_location: self.event_location, tracked_inactivity: self.tracked_inactivity, get_context: WithContext(OpenTelemetryLayer::::get_context), _registry: self._registry, } } + /// Sets whether or not event span's metadata should include detailed location + /// information, such as the file, module and line number. + /// + /// By default, event locations are enabled. + pub fn with_event_location(self, event_location: bool) -> Self { + Self { + event_location, + ..self + } + } + /// Sets whether or not spans metadata should include the _busy time_ /// (total time for which it was entered), and _idle time_ (total time /// the span existed but was not entered). @@ -555,6 +571,33 @@ where builder.status_code = Some(otel::StatusCode::Error); } + if self.event_location { + let builder_attrs = builder.attributes.get_or_insert(Vec::new()); + + #[cfg(not(feature = "tracing-log"))] + let normalized_meta = None; + let (file, module) = match &normalized_meta { + Some(meta) => ( + meta.file().map(|s| Value::from(s.to_owned())), + meta.module_path().map(|s| Value::from(s.to_owned())), + ), + None => ( + event.metadata().file().map(Value::from), + event.metadata().module_path().map(Value::from), + ), + }; + + if let Some(file) = file { + builder_attrs.push(KeyValue::new("code.filepath", file)); + } + if let Some(module) = module { + builder_attrs.push(KeyValue::new("code.namespace", module)); + } + if let Some(line) = meta.line() { + builder_attrs.push(KeyValue::new("code.lineno", line as i64)); + } + } + if let Some(ref mut events) = builder.events { events.push(otel_event); } else {