Skip to content

Commit 58f9eb5

Browse files
mjqloewenheim
andauthored
feat(otlp): Populate sentry.platform during ingestion (#5411)
Co-authored-by: Sebastian Zivota <loewenheim@users.noreply.github.com>
1 parent 3eb6e36 commit 58f9eb5

File tree

7 files changed

+104
-2
lines changed

7 files changed

+104
-2
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- Remove feature flag for Vercel Log Drain endpoint. ([#5406](https://github.com/getsentry/relay/pull/5406))
1616
- Add `http.request.header.cookie` to fields scrubbed by cookie rules. ([#5408](https://github.com/getsentry/relay/pull/5408))
1717
- Map `request_id` to `trace_id` in vercel log drain transform. ([#5333](https://github.com/getsentry/relay/pull/5333))
18+
- Populate `sentry.platform` during OTLP ingestion. ([#5411](https://github.com/getsentry/relay/pull/5411))
1819

1920
**Internal**:
2021

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ multer = "3.1.0"
143143
num-traits = "0.2.19"
144144
num_cpus = "1.17.0"
145145
objectstore-client = "0.0.11"
146+
opentelemetry-semantic-conventions = { version = "0.31.0" }
146147
opentelemetry-proto = { version = "0.30.0", default-features = false }
147148
papaya = "0.2.3"
148149
parking_lot = "0.12.5"

relay-otel/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ opentelemetry-proto = { workspace = true, features = [
1919
"trace",
2020
"logs",
2121
] }
22+
opentelemetry-semantic-conventions = { workspace = true }
2223
relay-event-schema = { workspace = true }
2324
relay-protocol = { workspace = true }
2425
serde_json = { workspace = true }

relay-otel/src/lib.rs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99
html_favicon_url = "https://raw.githubusercontent.com/getsentry/relay/master/artwork/relay-icon.png"
1010
)]
1111

12+
use opentelemetry_proto::tonic::common::v1::any_value;
1213
use opentelemetry_proto::tonic::{
1314
common::v1::{InstrumentationScope, any_value::Value as OtelValue},
1415
resource::v1::Resource,
1516
};
17+
use opentelemetry_semantic_conventions::attribute as otel_semconv;
1618
use relay_event_schema::protocol::{Attribute, AttributeType, Attributes};
1719
use relay_protocol::{Annotated, Value};
1820

@@ -129,6 +131,32 @@ pub fn otel_scope_into_attributes(
129131
}
130132
}
131133

134+
/// Returns the telemetry language SDK from the resource, mapped into a `sentry.platform` value.
135+
pub fn otel_resource_to_platform(resource: &Resource) -> Option<&str> {
136+
let any_value::Value::StringValue(language) = resource
137+
.attributes
138+
.iter()
139+
.find(|attr| attr.key == otel_semconv::TELEMETRY_SDK_LANGUAGE)?
140+
.value
141+
.as_ref()?
142+
.value
143+
.as_ref()?
144+
else {
145+
return None;
146+
};
147+
148+
// Smooth out some naming differences between OTel
149+
// (https://opentelemetry.io/docs/specs/semconv/resource/#telemetry-sdk)
150+
// and Sentry
151+
// (https://github.com/getsentry/relay/blob/8e6c963cdd79dc9ba2bebc21518a3553f70feeb3/relay-event-schema/src/protocol/event.rs#L251-L253).
152+
Some(match language.as_str() {
153+
"dotnet" => "csharp",
154+
"nodejs" => "node",
155+
"webjs" => "javascript",
156+
_ => language,
157+
})
158+
}
159+
132160
#[cfg(test)]
133161
mod tests {
134162
use super::*;
@@ -288,4 +316,34 @@ mod tests {
288316
}
289317
"#);
290318
}
319+
320+
#[test]
321+
fn test_otel_resource_to_attribute_without_language() {
322+
let resource = serde_json::from_value(serde_json::json!({"attributes": []})).unwrap();
323+
assert_eq!(otel_resource_to_platform(&resource), None);
324+
}
325+
326+
#[test]
327+
fn test_otel_resource_to_attribute_with_unmapped_language() {
328+
let resource = serde_json::from_value(serde_json::json!({
329+
"attributes": [{
330+
"key": "telemetry.sdk.language",
331+
"value": {"stringValue": "foo"},
332+
},
333+
]}))
334+
.unwrap();
335+
assert_eq!(otel_resource_to_platform(&resource), Some("foo"));
336+
}
337+
338+
#[test]
339+
fn test_otel_resource_to_attribute_with_mapped_language() {
340+
let resource = serde_json::from_value(serde_json::json!({
341+
"attributes": [{
342+
"key": "telemetry.sdk.language",
343+
"value": {"stringValue": "nodejs"},
344+
},
345+
]}))
346+
.unwrap();
347+
assert_eq!(otel_resource_to_platform(&resource), Some("node"));
348+
}
291349
}

relay-ourlogs/src/otel_to_sentry.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ use chrono::{TimeZone, Utc};
77
use opentelemetry_proto::tonic::common::v1::InstrumentationScope;
88
use opentelemetry_proto::tonic::common::v1::any_value::Value as OtelValue;
99
use opentelemetry_proto::tonic::logs::v1::LogRecord as OtelLogRecord;
10-
use relay_conventions::{EVENT_NAME, ORIGIN};
10+
use relay_conventions::{EVENT_NAME, ORIGIN, PLATFORM};
1111

1212
use opentelemetry_proto::tonic::resource::v1::Resource;
1313
use relay_event_schema::protocol::{Attributes, OurLog, OurLogLevel, SpanId, Timestamp, TraceId};
14-
use relay_otel::otel_value_to_attribute;
14+
use relay_otel::{otel_resource_to_platform, otel_value_to_attribute};
1515
use relay_protocol::{Annotated, Object};
1616

1717
/// Maps OpenTelemetry severity number to Sentry log level.
@@ -82,6 +82,11 @@ pub fn otel_to_sentry_log(
8282
if !event_name.is_empty() {
8383
attribute_data.insert(EVENT_NAME, event_name.to_owned());
8484
}
85+
if let Some(resource) = resource
86+
&& let Some(platform) = otel_resource_to_platform(resource)
87+
{
88+
attribute_data.insert(PLATFORM, platform.to_owned());
89+
}
8590

8691
relay_otel::otel_scope_into_attributes(&mut attribute_data, resource, scope);
8792

@@ -186,6 +191,9 @@ mod tests {
186191
"attributes": [{
187192
"key": "service.name",
188193
"value": {"stringValue": "test-service"},
194+
}, {
195+
"key": "telemetry.sdk.language",
196+
"value": {"stringValue": "nodejs"},
189197
}]
190198
}))
191199
.unwrap();
@@ -247,10 +255,18 @@ mod tests {
247255
"type": "string",
248256
"value": "test-service"
249257
},
258+
"resource.telemetry.sdk.language": {
259+
"type": "string",
260+
"value": "nodejs"
261+
},
250262
"sentry.origin": {
251263
"type": "string",
252264
"value": "auto.otlp.logs"
253265
},
266+
"sentry.platform": {
267+
"type": "string",
268+
"value": "node"
269+
},
254270
"string.attribute": {
255271
"type": "string",
256272
"value": "some string"

relay-spans/src/otel_to_sentry_v2.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ use opentelemetry_proto::tonic::trace::v1::span::Link as OtelLink;
55
use opentelemetry_proto::tonic::trace::v1::span::SpanKind as OtelSpanKind;
66
use relay_conventions::IS_REMOTE;
77
use relay_conventions::ORIGIN;
8+
use relay_conventions::PLATFORM;
89
use relay_conventions::SPAN_KIND;
910
use relay_conventions::STATUS_MESSAGE;
1011
use relay_event_schema::protocol::{Attributes, SpanKind};
12+
use relay_otel::otel_resource_to_platform;
1113
use relay_otel::otel_value_to_attribute;
1214
use relay_protocol::ErrorKind;
1315

@@ -68,6 +70,11 @@ pub fn otel_to_sentry_span(
6870
relay_otel::otel_scope_into_attributes(&mut sentry_attributes, resource, scope);
6971

7072
sentry_attributes.insert(ORIGIN, "auto.otlp.spans".to_owned());
73+
if let Some(resource) = resource
74+
&& let Some(platform) = otel_resource_to_platform(resource)
75+
{
76+
sentry_attributes.insert(PLATFORM, platform.to_owned());
77+
}
7178

7279
let mut name = if name.is_empty() { None } else { Some(name) };
7380
for (key, value) in attributes.into_iter().flat_map(|attribute| {
@@ -264,6 +271,9 @@ mod tests {
264271
"attributes": [{
265272
"key": "service.name",
266273
"value": {"stringValue": "test-service"},
274+
}, {
275+
"key": "telemetry.sdk.language",
276+
"value": {"stringValue": "nodejs"},
267277
}]
268278
}))
269279
.unwrap();
@@ -313,6 +323,10 @@ mod tests {
313323
"type": "string",
314324
"value": "test-service"
315325
},
326+
"resource.telemetry.sdk.language": {
327+
"type": "string",
328+
"value": "nodejs"
329+
},
316330
"sentry.environment": {
317331
"type": "string",
318332
"value": "test"
@@ -333,6 +347,10 @@ mod tests {
333347
"type": "boolean",
334348
"value": true
335349
},
350+
"sentry.platform": {
351+
"type": "string",
352+
"value": "node"
353+
},
336354
"sentry.sample_rate": {
337355
"type": "integer",
338356
"value": 1

0 commit comments

Comments
 (0)