Skip to content

Commit

Permalink
Implement record of tagged span data in tracing integration (#696)
Browse files Browse the repository at this point in the history
  • Loading branch information
DoumanAsh authored Oct 29, 2024
1 parent a1481d4 commit d3e2ca0
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 7 deletions.
27 changes: 27 additions & 0 deletions sentry-core/src/performance.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::collections::BTreeMap;
use std::ops::{Deref, DerefMut};
use std::sync::{Arc, Mutex, MutexGuard};
Expand Down Expand Up @@ -433,6 +434,20 @@ impl<'a> TransactionData<'a> {
Box::new(std::iter::empty())
}
}

/// Set some extra information to be sent with this Transaction.
pub fn set_data(&mut self, key: Cow<'a, str>, value: protocol::Value) {
if let Some(transaction) = self.0.transaction.as_mut() {
transaction.extra.insert(key.into(), value);
}
}

/// Set some extra information to be sent with this Transaction.
pub fn set_tag(&mut self, key: Cow<'_, str>, value: String) {
if let Some(transaction) = self.0.transaction.as_mut() {
transaction.tags.insert(key.into(), value);
}
}
}

impl Transaction {
Expand Down Expand Up @@ -627,6 +642,18 @@ impl Transaction {
/// A smart pointer to a span's [`data` field](protocol::Span::data).
pub struct Data<'a>(MutexGuard<'a, protocol::Span>);

impl<'a> Data<'a> {
/// Set some extra information to be sent with this Span.
pub fn set_data(&mut self, key: String, value: protocol::Value) {
self.0.data.insert(key, value);
}

/// Set some tag to be sent with this Span.
pub fn set_tag(&mut self, key: String, value: String) {
self.0.tags.insert(key, value);
}
}

impl<'a> Deref for Data<'a> {
type Target = BTreeMap<String, protocol::Value>;

Expand Down
3 changes: 2 additions & 1 deletion sentry-tracing/src/converters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use tracing_subscriber::layer::Context;
use tracing_subscriber::registry::LookupSpan;

use super::layer::SentrySpanData;
use crate::TAGS_PREFIX;

/// Converts a [`tracing_core::Level`] to a Sentry [`Level`]
fn convert_tracing_level(level: &tracing_core::Level) -> Level {
Expand Down Expand Up @@ -156,7 +157,7 @@ fn tags_from_event(fields: &mut BTreeMap<String, Value>) -> BTreeMap<String, Str
let mut tags = BTreeMap::new();

fields.retain(|key, value| {
let Some(key) = key.strip_prefix("tags.") else {
let Some(key) = key.strip_prefix(TAGS_PREFIX) else {
return true;
};
let string = match value {
Expand Down
57 changes: 51 additions & 6 deletions sentry-tracing/src/layer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::BTreeMap;

Expand All @@ -9,6 +10,7 @@ use tracing_subscriber::layer::{Context, Layer};
use tracing_subscriber::registry::LookupSpan;

use crate::converters::*;
use crate::TAGS_PREFIX;

/// The action that Sentry should perform for a [`Metadata`]
#[derive(Debug, Clone, Copy)]
Expand Down Expand Up @@ -142,6 +144,53 @@ where
}
}

#[inline(always)]
fn record_fields<'a, K: AsRef<str> + Into<Cow<'a, str>>>(
span: &TransactionOrSpan,
data: BTreeMap<K, Value>,
) {
match span {
TransactionOrSpan::Span(span) => {
let mut span = span.data();
for (key, value) in data {
if let Some(stripped_key) = key.as_ref().strip_prefix(TAGS_PREFIX) {
match value {
Value::Bool(value) => {
span.set_tag(stripped_key.to_owned(), value.to_string())
}
Value::Number(value) => {
span.set_tag(stripped_key.to_owned(), value.to_string())
}
Value::String(value) => span.set_tag(stripped_key.to_owned(), value),
_ => span.set_data(key.into().into_owned(), value),
}
} else {
span.set_data(key.into().into_owned(), value);
}
}
}
TransactionOrSpan::Transaction(transaction) => {
let mut transaction = transaction.data();
for (key, value) in data {
if let Some(stripped_key) = key.as_ref().strip_prefix(TAGS_PREFIX) {
match value {
Value::Bool(value) => {
transaction.set_tag(stripped_key.into(), value.to_string())
}
Value::Number(value) => {
transaction.set_tag(stripped_key.into(), value.to_string())
}
Value::String(value) => transaction.set_tag(stripped_key.into(), value),
_ => transaction.set_data(key.into(), value),
}
} else {
transaction.set_data(key.into(), value);
}
}
}
}
}

/// Data that is attached to the tracing Spans `extensions`, in order to
/// `finish` the corresponding sentry span `on_close`, and re-set its parent as
/// the *current* span.
Expand Down Expand Up @@ -217,9 +266,7 @@ where
};
// Add the data from the original span to the sentry span.
// This comes from typically the `fields` in `tracing::instrument`.
for (key, value) in data {
sentry_span.set_data(key, value);
}
record_fields(&sentry_span, data);

sentry_core::configure_scope(|scope| scope.set_span(Some(sentry_span.clone())));

Expand Down Expand Up @@ -267,9 +314,7 @@ where
let mut data = FieldVisitor::default();
values.record(&mut data);

for (key, value) in data.json_values {
span.set_data(&key, value);
}
record_fields(span, data.json_values);
}
}

Expand Down
2 changes: 2 additions & 0 deletions sentry-tracing/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,5 @@ mod layer;

pub use converters::*;
pub use layer::*;

const TAGS_PREFIX: &str = "tags.";

0 comments on commit d3e2ca0

Please sign in to comment.