Skip to content
Closed
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
- Don't reject attributes that don't have values, but do have metadata. ([#6098](https://github.com/getsentry/relay/pull/6098))
- Infer span names PII-safely. ([#6112](https://github.com/getsentry/relay/pull/6112))
- Unset segment info for web vital spans. ([#6042](https://github.com/getsentry/relay/pull/6042))
- Dynamically sample V2 spans after normalization. ([#6121](https://github.com/getsentry/relay/pull/6121))

**Internal**:

Expand Down
10 changes: 5 additions & 5 deletions relay-server/src/processing/spans/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,16 @@ impl processing::Processor for SpansProcessor {

dynamic_sampling::validate_and_set_dsc(&mut spans, &ctx)?;

let mut spans = match dynamic_sampling::run(spans, ctx) {
Ok(spans) => spans,
Err(metrics) => return Ok(Output::metrics(metrics)),
};

process::normalize(&mut spans, &self.geo_lookup, ctx);
filter::filter(&mut spans, ctx);
process::scrub(&mut spans, ctx);
process::normalize_derived(&mut spans, ctx);

Comment thread
cursor[bot] marked this conversation as resolved.
let spans = match dynamic_sampling::run(spans, ctx) {
Ok(spans) => spans,
Err(metrics) => return Ok(Output::metrics(metrics)),
};

let spans = self.limiter.enforce_quotas(spans, ctx).await?;
let spans = match spans.transpose() {
Either::Left(spans) => spans,
Expand Down
134 changes: 134 additions & 0 deletions tests/integration/test_spans_standalone.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from datetime import datetime, timezone

from sentry_sdk.envelope import Envelope, Item, PayloadRef
from sentry_relay.consts import DataCategory

from .asserts import time_within_delta, time_within

from .test_dynamic_sampling import add_sampling_config

import pytest

# Some profiles from Sentry
Expand Down Expand Up @@ -1198,5 +1201,136 @@ def test_name_inference(
}


@pytest.mark.parametrize("sampled", [False, True])
def test_inp_span_is_segment_ds(
mini_sentry,
relay,
relay_with_processing,
Comment thread
jjbayer marked this conversation as resolved.
metrics_consumer,
outcomes_consumer,
sampled,
):
"""
Verifies that the `is_segment` tag on metrics is correctly unset
regardless of whether the span is sampled.

This is specifically related to https://github.com/getsentry/relay/pull/6042.
If we ever decide to get rid of the functionality introduced in that PR, this
test becomes obsolete.
"""
metrics_consumer = metrics_consumer()
outcomes_consumer = outcomes_consumer()

project_id = 42
project_config = mini_sentry.add_full_project_config(project_id)
project_config["config"]["performanceScore"] = {
"profiles": performance_score_profiles
}
project_config["config"].setdefault("features", []).append(
"organizations:relay-generate-billing-outcome"
)
project_config["config"].setdefault("features", []).append(
"projects:span-v2-experimental-processing"
)

add_sampling_config(
project_config, sample_rate=1.0 if sampled else 0.0, rule_type="project"
)

relay = relay_with_processing()

ts = datetime.now(timezone.utc)

envelope = envelope_with_spans(
{
"data": {
"sentry.op": "ui.interaction.click",
"release": "frontend@488531b11e6401fa530ac25554d44426e6ef0f0b",
"environment": "prod",
"replay_id": "3d76a6311de149b9b3f560827ea0ecf9",
"transaction": "/insights/projects/",
"user_agent.original": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Firefox/42.0",
"client.address": "{{auto}}",
"sentry.exclusive_time": 104,
},
"description": "<unknown>",
"op": "ui.interaction.click",
"parent_span_id": "8a6626cc9bdd5d9b",
"span_id": "a6f029fbe0e2389a",
"start_timestamp": ts.timestamp() - 0.5,
"timestamp": ts.timestamp(),
"trace_id": "d3d20f000885466b8c8f947c9b92b8d3",
"origin": "auto.http.browser.inp",
"exclusive_time": 104,
"measurements": {"inp": {"value": 104, "unit": "millisecond"}},
"segment_id": "8a6626cc9bdd5d9b",
"is_segment": True,
},
trace_info={
"trace_id": "d3d20f000885466b8c8f947c9b92b8d3",
"public_key": project_config["publicKeys"][0]["publicKey"],
"transaction": "/insights/projects/",
},
)

relay.send_envelope(project_id, envelope)

assert metrics_consumer.get_metrics(with_headers=False) == [
{
"org_id": 1,
"project_id": 42,
"name": "c:spans/count_per_root_project@none",
"type": "c",
"value": 1.0,
"timestamp": time_within_delta(ts),
"tags": {
"decision": "keep" if sampled else "drop",
"is_segment": "false",
"target_project_id": "42",
"transaction": "/insights/projects/",
},
"retention_days": 90,
"received_at": time_within(ts, precision="s"),
},
{
"org_id": 1,
"project_id": 42,
"name": "c:spans/usage@none",
"type": "c",
"value": 1.0,
"timestamp": time_within_delta(ts),
"tags": {"is_segment": "false", "billing_outcome_emitted": "true"},
"retention_days": 90,
"received_at": time_within(ts, precision="s"),
},
]

expected_outcomes = [
{
"category": DataCategory.SPAN.value,
"key_id": 123,
"org_id": 1,
"outcome": 0,
"project_id": 42,
"quantity": 1,
}
]

if not sampled:
expected_outcomes.append(
{
"category": DataCategory.SPAN_INDEXED.value,
"key_id": 123,
"org_id": 1,
"outcome": 1,
"project_id": 42,
"quantity": 1,
"reason": "Sampled:0",
}
)

assert outcomes_consumer.get_aggregated_outcomes() == expected_outcomes


def _if_dict(cond, then):
return then if cond else {}
Loading