diff --git a/CHANGELOG.md b/CHANGELOG.md index ee3d24217c..89662f0245 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ **Features**: - Only apply non-destructive PII rules to log bodies by default. ([#5272](https://github.com/getsentry/relay/pull/5272)) +- Add `sentry.origin` attribute to OTLP spans. ([#5294](https://github.com/getsentry/relay/pull/5294)) **Breaking Changes**: diff --git a/relay-server/src/services/processor/span.rs b/relay-server/src/services/processor/span.rs index a50dd5f3a8..c9532fe8cc 100644 --- a/relay-server/src/services/processor/span.rs +++ b/relay-server/src/services/processor/span.rs @@ -246,6 +246,7 @@ mod tests { "instrumentation.scope_key": "scope_value", "instrumentation.version": "0.0.1", "resource.resource_key": "resource_value", + "sentry.origin": "auto.otlp.spans", "span_key": "span_value" }, "exclusive_time": 0.0, diff --git a/relay-spans/src/otel_to_sentry.rs b/relay-spans/src/otel_to_sentry.rs index b3ecf582c8..4fb6e5f19a 100644 --- a/relay-spans/src/otel_to_sentry.rs +++ b/relay-spans/src/otel_to_sentry.rs @@ -154,6 +154,7 @@ mod tests { "instrumentation.version": "123.42", "plugin.name": "fastify -> @fastify/multipart", "resource.service.name": 42, + "sentry.origin": "auto.otlp.spans", "sentry.parentSampled": true, "sentry.sample_rate": 1, "sentry.status.message": "test" @@ -199,7 +200,8 @@ mod tests { "status": "ok", "description": "middleware - fastify -> @fastify/multipart", "data": { - "sentry.name": "middleware - fastify -> @fastify/multipart" + "sentry.name": "middleware - fastify -> @fastify/multipart", + "sentry.origin": "auto.otlp.spans" }, "links": [], "kind": "internal" @@ -234,7 +236,8 @@ mod tests { "status": "ok", "description": "middleware - fastify -> @fastify/multipart", "data": { - "sentry.name": "middleware - fastify -> @fastify/multipart" + "sentry.name": "middleware - fastify -> @fastify/multipart", + "sentry.origin": "auto.otlp.spans" }, "links": [], "kind": "internal" @@ -299,7 +302,8 @@ mod tests { "sentry.name": "database query", "db.name": "database", "db.statement": "SELECT \"table\".\"col\" FROM \"table\" WHERE \"table\".\"col\" = %s", - "db.type": "sql" + "db.type": "sql", + "sentry.origin": "auto.otlp.spans" }, "links": [], "kind": "client" @@ -363,7 +367,8 @@ mod tests { "sentry.name": "database query", "db.name": "database", "db.statement": "SELECT \"table\".\"col\" FROM \"table\" WHERE \"table\".\"col\" = %s", - "db.type": "sql" + "db.type": "sql", + "sentry.origin": "auto.otlp.spans" }, "links": [], "kind": "client" @@ -414,6 +419,7 @@ mod tests { "data": { "sentry.name": "http client request", "http.request.method": "GET", + "sentry.origin": "auto.otlp.spans", "url.path": "/api/search?q=foobar" }, "links": [], @@ -483,7 +489,8 @@ mod tests { "data": { "sentry.name": "cmd.run", "process.args": "[\"node\",\"--require\",\"preflight.cjs\"]", - "process.info": "[41]" + "process.info": "[41]", + "sentry.origin": "auto.otlp.spans" }, "links": [] } @@ -645,6 +652,7 @@ mod tests { "sentry.sdk.name": "sentry.php", "sentry.name": "myname", "sentry.metrics_summary.some_metric": "[]", + "sentry.origin": "auto.otlp.spans", "sentry.status.message": "foo" }, "links": [], @@ -677,7 +685,9 @@ mod tests { "trace_id": "89143b0763095bd9c9955e8175d1fb23", "is_remote": true, "status": "ok", - "data": {}, + "data": { + "sentry.origin": "auto.otlp.spans" + }, "links": [] } "#); @@ -707,7 +717,9 @@ mod tests { "trace_id": "89143b0763095bd9c9955e8175d1fb23", "is_remote": false, "status": "ok", - "data": {}, + "data": { + "sentry.origin": "auto.otlp.spans" + }, "links": [] } "#); @@ -737,7 +749,9 @@ mod tests { "trace_id": "89143b0763095bd9c9955e8175d1fb23", "is_remote": false, "status": "ok", - "data": {}, + "data": { + "sentry.origin": "auto.otlp.spans" + }, "links": [], "kind": "client" } @@ -797,7 +811,9 @@ mod tests { "trace_id": "3c79f60c11214eb38604f4ae0781bfb2", "is_remote": false, "status": "ok", - "data": {}, + "data": { + "sentry.origin": "auto.otlp.spans" + }, "links": [ { "trace_id": "4c79f60c11214eb38604f4ae0781bfb2", @@ -839,6 +855,7 @@ mod tests { "is_remote": false, "status": "internal_error", "data": { + "sentry.origin": "auto.otlp.spans", "sentry.status.message": "2 is the error status code" }, "links": [] diff --git a/relay-spans/src/otel_to_sentry_v2.rs b/relay-spans/src/otel_to_sentry_v2.rs index 8574e13e77..2a8046dd29 100644 --- a/relay-spans/src/otel_to_sentry_v2.rs +++ b/relay-spans/src/otel_to_sentry_v2.rs @@ -3,6 +3,7 @@ use opentelemetry_proto::tonic::common::v1::InstrumentationScope; use opentelemetry_proto::tonic::resource::v1::Resource; use opentelemetry_proto::tonic::trace::v1::span::Link as OtelLink; use opentelemetry_proto::tonic::trace::v1::span::SpanKind as OtelSpanKind; +use relay_conventions::ORIGIN; use relay_conventions::STATUS_MESSAGE; use relay_event_schema::protocol::{Attributes, SpanKind}; use relay_otel::otel_value_to_attribute; @@ -64,6 +65,8 @@ pub fn otel_to_sentry_span( relay_otel::otel_scope_into_attributes(&mut sentry_attributes, resource, scope); + sentry_attributes.insert(ORIGIN, "auto.otlp.spans".to_owned()); + let mut name = if name.is_empty() { None } else { Some(name) }; for (key, value) in attributes.into_iter().flat_map(|attribute| { let value = attribute.value?.value?; @@ -302,6 +305,10 @@ mod tests { "type": "double", "value": 1000.0 }, + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" + }, "sentry.parentSampled": { "type": "boolean", "value": true @@ -357,6 +364,10 @@ mod tests { "sentry.exclusive_time": { "type": "double", "value": 3200.0 + }, + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" } } } @@ -421,6 +432,10 @@ mod tests { "db.type": { "type": "string", "value": "sql" + }, + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" } } } @@ -495,6 +510,10 @@ mod tests { "sentry.description": { "type": "string", "value": "index view query" + }, + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" } } } @@ -546,6 +565,10 @@ mod tests { "type": "string", "value": "GET" }, + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" + }, "url.path": { "type": "string", "value": "/api/search?q=foobar" @@ -723,6 +746,10 @@ mod tests { "type": "string", "value": "myop" }, + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" + }, "sentry.platform": { "type": "string", "value": "php" @@ -779,7 +806,12 @@ mod tests { "start_timestamp": 123.0, "end_timestamp": 123.5, "links": [], - "attributes": {} + "attributes": { + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" + } + } } "#); } @@ -807,7 +839,12 @@ mod tests { "start_timestamp": 123.0, "end_timestamp": 123.5, "links": [], - "attributes": {} + "attributes": { + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" + } + } } "#); } @@ -836,7 +873,12 @@ mod tests { "start_timestamp": 123.0, "end_timestamp": 123.5, "links": [], - "attributes": {} + "attributes": { + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" + } + } } "#); } @@ -917,7 +959,12 @@ mod tests { } } ], - "attributes": {} + "attributes": { + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" + } + } } "#); } @@ -945,6 +992,10 @@ mod tests { "end_timestamp": 0.0, "links": [], "attributes": { + "sentry.origin": { + "type": "string", + "value": "auto.otlp.spans" + }, "sentry.status.message": { "type": "string", "value": "2 is the error status code" diff --git a/tests/integration/test_spans.py b/tests/integration/test_spans.py index 4f7d63d90e..5663596cb5 100644 --- a/tests/integration/test_spans.py +++ b/tests/integration/test_spans.py @@ -758,6 +758,7 @@ def test_span_ingestion( "sentry.exclusive_time": {"type": "double", "value": 500.0}, "sentry.is_segment": {"type": "boolean", "value": True}, "sentry.op": {"type": "string", "value": "default"}, + "sentry.origin": {"type": "string", "value": "auto.otlp.spans"}, "sentry.segment.id": {"type": "string", "value": "d342abb1214ca182"}, "sentry.status": {"type": "string", "value": "ok"}, "user_agent.original": { @@ -826,6 +827,7 @@ def test_span_ingestion( }, "sentry.exclusive_time": {"type": "double", "value": 500.0}, "sentry.op": {"type": "string", "value": "default"}, + "sentry.origin": {"type": "string", "value": "auto.otlp.spans"}, "sentry.status": {"type": "string", "value": "ok"}, "ui.component_name": {"type": "string", "value": "MyComponent"}, "user_agent.original": { diff --git a/tests/integration/test_spansv2_otel.py b/tests/integration/test_spansv2_otel.py index 54d6c330e3..e61ef3c060 100644 --- a/tests/integration/test_spansv2_otel.py +++ b/tests/integration/test_spansv2_otel.py @@ -97,6 +97,7 @@ def test_span_ingestion( "type": "string", "value": time_within(ts, expect_resolution="ns"), }, + "sentry.origin": {"type": "string", "value": "auto.otlp.spans"}, "ui.component_name": {"type": "string", "value": "MyComponent"}, }, "downsampled_retention_days": 90,