Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement record of tagged span data in tracing integration #696

Merged
merged 1 commit into from
Oct 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -425,6 +426,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 @@ -611,6 +626,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.";
Loading