Skip to content

Commit

Permalink
feat(spans): Filter spans based on module (#2511)
Browse files Browse the repository at this point in the history
  • Loading branch information
phacops authored Sep 14, 2023
1 parent d6bb35d commit cb88f12
Show file tree
Hide file tree
Showing 8 changed files with 1,727 additions and 774 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- Rename the envelope item type for StatsD payloads to "statsd". ([#2470](https://github.com/getsentry/relay/pull/2470))
- Add a nanojoule unit for profile measurements. ([#2478](https://github.com/getsentry/relay/pull/2478))
- Add a timestamp field to report profile's start time on Android. ([#2486](https://github.com/getsentry/relay/pull/2486))
- Filter span metrics extraction based on features. ([#2511](https://github.com/getsentry/relay/pull/2511))

## 23.8.0

Expand Down
41 changes: 38 additions & 3 deletions relay-dynamic-config/src/defaults.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use relay_base_schema::data_category::DataCategory;
use relay_common::glob2::LazyGlob;
use relay_sampling::condition::{EqCondition, RuleCondition};
use relay_common::glob3::GlobPatterns;
use relay_sampling::condition::{
AndCondition, EqCondition, GlobCondition, NotCondition, RuleCondition,
};
use serde_json::Value;

use crate::feature::Feature;
Expand All @@ -25,12 +28,44 @@ pub fn add_span_metrics(project_config: &mut ProjectConfig) {
return;
}

// Add conditions to filter spans if a specific module is enabled.
// By default, this will extract all spans.
let span_op_field_name = "span.op";
let span_op_conditions = if project_config
.features
.has(Feature::SpanMetricsExtractionAllModules)
{
None
} else {
Some(RuleCondition::And(AndCondition {
inner: vec![
RuleCondition::Glob(GlobCondition {
name: span_op_field_name.into(),
value: GlobPatterns::new(vec!["db*".into()]),
}),
RuleCondition::Not(NotCondition {
inner: Box::new(RuleCondition::Glob(GlobCondition {
name: span_op_field_name.into(),
value: GlobPatterns::new(vec!["db*clickhouse".into()]),
})),
}),
RuleCondition::Not(NotCondition {
inner: Box::new(RuleCondition::Eq(EqCondition {
name: span_op_field_name.into(),
value: Value::String("db.redis".into()),
options: Default::default(),
})),
}),
],
}))
};

config.metrics.extend([
MetricSpec {
category: DataCategory::Span,
mri: "d:spans/exclusive_time@millisecond".into(),
field: Some("span.exclusive_time".into()),
condition: None,
condition: span_op_conditions.clone(),
tags: vec![TagSpec {
key: "transaction".into(),
field: Some("span.data.transaction".into()),
Expand All @@ -42,7 +77,7 @@ pub fn add_span_metrics(project_config: &mut ProjectConfig) {
category: DataCategory::Span,
mri: "d:spans/exclusive_time_light@millisecond".into(),
field: Some("span.exclusive_time".into()),
condition: None,
condition: span_op_conditions,
tags: Default::default(),
},
]);
Expand Down
3 changes: 3 additions & 0 deletions relay-dynamic-config/src/feature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ pub enum Feature {
/// Allow ingestion of metrics in the "custom" namespace.
#[serde(rename = "organizations:custom-metrics")]
CustomMetrics,
/// Enable extracting spans for all modules.
#[serde(rename = "projects:span-metrics-extraction-all-modules")]
SpanMetricsExtractionAllModules,

/// Deprecated, still forwarded for older downstream Relays.
#[serde(rename = "organizations:transaction-name-mark-scrubbed-as-sanitized")]
Expand Down
32 changes: 21 additions & 11 deletions relay-server/src/actors/processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2278,23 +2278,33 @@ impl EnvelopeProcessorService {
state.managed_envelope.envelope_mut().add_item(item);
};

let all_modules_enabled = state
.project_state
.has_feature(Feature::SpanMetricsExtractionAllModules);

// Add child spans as envelope items.
if let Some(child_spans) = event.spans.value() {
for span in child_spans {
// HACK: clone the span to set the segment_id. This should happen
// as part of normalization once standalone spans reach wider adoption.
let mut span = span.clone();
let Some(inner_span) = span.value_mut() else {
continue;
};
inner_span.segment_id = transaction_span.segment_id.clone();
inner_span.is_segment = Annotated::new(false);
add_span(span);
if let Some(inner_span) = span.value() {
// HACK: filter spans based on module until we figure out grouping.
let Some(span_op) = inner_span.op.value() else {
continue;
};
if all_modules_enabled || span_op.starts_with("db") {
// HACK: clone the span to set the segment_id. This should happen
// as part of normalization once standalone spans reach wider adoption.
let mut new_span = inner_span.clone();
new_span.segment_id = transaction_span.segment_id.clone();
new_span.is_segment = Annotated::new(false);
add_span(Annotated::new(new_span));
}
}
}
}

// Add transaction span as an envelope item.
add_span(transaction_span.into());
if all_modules_enabled {
add_span(transaction_span.into());
}
}

/// Computes the sampling decision on the incoming event
Expand Down
Loading

0 comments on commit cb88f12

Please sign in to comment.