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

Add support for tracing::Span::recorded fields in metrics-tracing-context #408

Merged
merged 16 commits into from
Nov 29, 2023
17 changes: 8 additions & 9 deletions metrics-tracing-context/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,19 +55,18 @@
//!
//! # Implementation
//!
//! The integration layer works by capturing all fields present when a span is created and storing
//! them as an extension to the span. If a metric is emitted while a span is entered, we check that
//! span to see if it has any fields in the extension data, and if it does, we add those fields as
//! labels to the metric key.
//! The integration layer works by capturing all fields present when a span is
//! created or then new fields are recorded afterward, and storing them as an
//! extension to the span. If a metric is emitted while a span is entered, we
//! check that span to see if it has any fields in the extension data, and if
//! it does, we add those fields as labels to the metric key.
//!
//! There are two important behaviors to be aware of:
//! - we only capture the fields present when the span is created
//! - we store all fields that a span has, including the fields of its parent span(s)
//! Be aware that we store all fields that a span has, including the fields of its parent span(s).
zohnannor marked this conversation as resolved.
Show resolved Hide resolved
//!
//! ## Lack of dynamism
//! ## Support for dynamism
zohnannor marked this conversation as resolved.
Show resolved Hide resolved
//!
//! This means that if you use [`Span::record`][tracing::Span::record] to add fields to a span after
//! it has been created, those fields will not be captured and added to your metric key.
//! it has been created, those fields will be captured and added to your metric key.
//!
//! ## Span fields and ancestry
//!
Expand Down
23 changes: 20 additions & 3 deletions metrics-tracing-context/src/tracing_integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,8 @@ impl Visit for Labels {
}

impl Labels {
fn from_attributes(attrs: &Attributes<'_>) -> Labels {
fn from_record(record: &Record) -> Labels {
let mut labels = Labels::default();
let record = Record::new(attrs.values());
record.record(&mut labels);
labels
}
Expand Down Expand Up @@ -135,7 +134,7 @@ where
{
fn on_new_span(&self, attrs: &Attributes<'_>, id: &Id, cx: Context<'_, S>) {
let span = cx.span(id).expect("span must already exist!");
let mut labels = Labels::from_attributes(attrs);
let mut labels = Labels::from_record(&Record::new(attrs.values()));

if let Some(parent) = span.parent() {
if let Some(parent_labels) = parent.extensions().get::<Labels>() {
Expand All @@ -146,6 +145,24 @@ where
span.extensions_mut().insert(labels);
}

fn on_record(&self, id: &Id, values: &Record<'_>, cx: Context<'_, S>) {
let span = cx.span(id).expect("span must already exist!");
let mut labels = Labels::from_record(values);

if let Some(parent) = span.parent() {
if let Some(parent_labels) = parent.extensions().get::<Labels>() {
labels.extend_from_labels(parent_labels);
}
}
zohnannor marked this conversation as resolved.
Show resolved Hide resolved

let ext = &mut span.extensions_mut();
if let Some(existing) = ext.get_mut::<Labels>() {
existing.extend_from_labels(&labels);
} else {
ext.insert(labels);
}
}

unsafe fn downcast_raw(&self, id: TypeId) -> Option<*const ()> {
zohnannor marked this conversation as resolved.
Show resolved Hide resolved
match id {
id if id == TypeId::of::<Self>() => Some(self as *const _ as *const ()),
Expand Down
Loading
Loading