From 89479173be6246c659db33de46983d7e2ddcf95e Mon Sep 17 00:00:00 2001 From: Floris Bruynooghe Date: Fri, 4 Feb 2022 10:42:40 +0100 Subject: [PATCH] feat(tracing): Add line information from tracing (#430) This adds the line information that tracing provides back into the event. It also moves around the tags into a custom context instead of the "extra" grab-bag as this is less likely to step on the user's ad-hoc toes. --- CHANGELOG.md | 1 + sentry-tracing/src/converters.rs | 36 ++++++++++++++++++++++++++++++-- sentry/tests/test_tracing.rs | 35 +++++++++++++++++++++++++++++-- 3 files changed, 68 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cc4604d0..3d5c0919 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ - Remove unused `serde_json` feature from `curl` dependency. ([#420](http://github.com/getsentry/sentry-rust/pull/420)) - `sentry-tracing`: When converting a `tracing` event to a `sentry` event, don't create an exception if the original event doesn't have one ([#423](https://github.com/getsentry/sentry-rust/pull/423)) +- `sentry-tracing`: Add line numbers and tags into custom Contexts sections. ([#430](http://github.com/getsentry/sentry-rust/pull/430)) **Thank you**: diff --git a/sentry-tracing/src/converters.rs b/sentry-tracing/src/converters.rs index f6d3b7ee..8602e382 100644 --- a/sentry-tracing/src/converters.rs +++ b/sentry-tracing/src/converters.rs @@ -103,6 +103,38 @@ pub fn breadcrumb_from_event(event: &tracing_core::Event) -> Breadcrumb { } } +fn contexts_from_event( + event: &tracing_core::Event, + event_tags: BTreeMap, +) -> BTreeMap { + let event_meta = event.metadata(); + let mut location_map = BTreeMap::new(); + if let Some(module_path) = event_meta.module_path() { + location_map.insert("module_path".to_string(), module_path.into()); + } + if let Some(file) = event_meta.file() { + location_map.insert("file".to_string(), file.into()); + } + if let Some(line) = event_meta.line() { + location_map.insert("line".to_string(), line.into()); + } + + let mut context = BTreeMap::new(); + if !event_tags.is_empty() { + context.insert( + "Rust Tracing Tags".to_string(), + sentry_core::protocol::Context::Other(event_tags), + ); + } + if !location_map.is_empty() { + context.insert( + "Rust Tracing Location".to_string(), + sentry_core::protocol::Context::Other(location_map), + ); + } + context +} + /// Creates an [`Event`] from a given [`tracing_core::Event`] pub fn event_from_event(event: &tracing_core::Event, _ctx: Context) -> Event<'static> where @@ -114,7 +146,7 @@ where logger: Some(event.metadata().target().to_owned()), level: convert_tracing_level(event.metadata().level()), message, - extra: visitor.json_values, + contexts: contexts_from_event(event, visitor.json_values), ..Default::default() } } @@ -133,8 +165,8 @@ where logger: Some(event.metadata().target().to_owned()), level: convert_tracing_level(event.metadata().level()), message, - extra: visitor.json_values, exception: visitor.exceptions.into(), + contexts: contexts_from_event(event, visitor.json_values), ..Default::default() } } diff --git a/sentry/tests/test_tracing.rs b/sentry/tests/test_tracing.rs index c9145f2b..34c2ca6e 100644 --- a/sentry/tests/test_tracing.rs +++ b/sentry/tests/test_tracing.rs @@ -1,6 +1,7 @@ #![cfg(feature = "test")] use log_ as log; +use sentry::protocol::{Context, Value}; use tracing_ as tracing; use tracing_subscriber::prelude::*; @@ -17,14 +18,14 @@ fn test_tracing() { }); tracing::info!("Hello Tracing World!"); - tracing::error!("Shit's on fire yo"); + tracing::error!(tagname = "tagvalue", "Shit's on fire yo"); log::info!("Hello Logging World!"); log::error!("Shit's on fire yo"); let err = "NaN".parse::().unwrap_err(); let err: &dyn std::error::Error = &err; - tracing::error!(err); + tracing::error!(err, tagname = "tagvalue"); }); assert_eq!(events.len(), 3); @@ -40,6 +41,21 @@ fn test_tracing() { event.breadcrumbs[0].message, Some("Hello Tracing World!".into()) ); + match event.contexts.get("Rust Tracing Tags").unwrap() { + Context::Other(tags) => { + let value = Value::String("tagvalue".to_string()); + assert_eq!(*tags.get("tagname").unwrap(), value); + } + _ => panic!("Wrong context type"), + } + match event.contexts.get("Rust Tracing Location").unwrap() { + Context::Other(tags) => { + assert!(matches!(tags.get("module_path").unwrap(), Value::String(_))); + assert!(matches!(tags.get("file").unwrap(), Value::String(_))); + assert!(matches!(tags.get("line").unwrap(), Value::Number(_))); + } + _ => panic!("Wrong context type"), + } let event = events.next().unwrap(); assert_eq!(event.tags["worker"], "worker1"); @@ -64,6 +80,21 @@ fn test_tracing() { event.exception[0].value, Some("invalid digit found in string".into()) ); + match event.contexts.get("Rust Tracing Tags").unwrap() { + Context::Other(tags) => { + let value = Value::String("tagvalue".to_string()); + assert_eq!(*tags.get("tagname").unwrap(), value); + } + _ => panic!("Wrong context type"), + } + match event.contexts.get("Rust Tracing Location").unwrap() { + Context::Other(tags) => { + assert!(matches!(tags.get("module_path").unwrap(), Value::String(_))); + assert!(matches!(tags.get("file").unwrap(), Value::String(_))); + assert!(matches!(tags.get("line").unwrap(), Value::Number(_))); + } + _ => panic!("Wrong context type"), + } } #[tracing::instrument(fields(span_field))]