Skip to content
Open
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 @@ -11,6 +11,7 @@

- Correctly handle minidump objecstore upload failures. ([#6033](https://github.com/getsentry/relay/pull/6033))
- Add `client.address` attribute to known IP fields. ([#6058](https://github.com/getsentry/relay/pull/6058))
- Fix a bug in mobile attribute normalization. ([#6065](https://github.com/getsentry/relay/pull/6065))

**Internal**:

Expand Down
36 changes: 20 additions & 16 deletions relay-event-normalization/src/eap/mobile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,19 @@ pub fn normalize_mobile_attributes(attributes: &mut Annotated<Attributes>) {

// Normalize app start measurements into unified attributes.
// V1 spans have measurements `app_start_cold`/`app_start_warm` which become
// attributes with those names after v1→v2 conversion.
// V2 spans will at some point send `app.vitals.start.value` + `app.vitals.start.type` directly.
// attributes `app.vitals.start.cold.value` and `app.vitals.start.warm.value`, respectively,
// after v1→v2 conversion. V2 spans will at some point send `app.vitals.start.value` + `app.vitals.start.type` directly.
if !attrs.contains_key(APP__VITALS__START__VALUE) {
if let Some(value) = attrs.get_value("app_start_cold").and_then(|v| v.as_f64())
if let Some(value) = attrs
.get_value(APP__VITALS__START__COLD__VALUE)
.and_then(|v| v.as_f64())
&& value <= MAX_DURATION_MOBILE_MS
{
attrs.insert(APP__VITALS__START__VALUE, value);
attrs.insert_if_missing(APP__VITALS__START__TYPE, || "cold".to_owned());
} else if let Some(value) = attrs.get_value("app_start_warm").and_then(|v| v.as_f64())
} else if let Some(value) = attrs
.get_value(APP__VITALS__START__WARM__VALUE)
.and_then(|v| v.as_f64())
Comment on lines -54 to +63

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the functional change in this PR.

&& value <= MAX_DURATION_MOBILE_MS
{
attrs.insert(APP__VITALS__START__VALUE, value);
Expand Down Expand Up @@ -315,24 +319,24 @@ mod tests {
#[test]
fn test_app_start_cold_normalized() {
let mut attributes = Annotated::new(attributes! {
"app_start_cold" => 1234.0,
"app.vitals.start.cold.value" => 1234.0,
});

normalize_mobile_attributes(&mut attributes);

assert_annotated_snapshot!(attributes, @r#"
{
"app.vitals.start.cold.value": {
"type": "double",
"value": 1234.0
},
"app.vitals.start.type": {
"type": "string",
"value": "cold"
},
"app.vitals.start.value": {
"type": "double",
"value": 1234.0
},
"app_start_cold": {
"type": "double",
"value": 1234.0
}
}
"#);
Expand All @@ -341,7 +345,7 @@ mod tests {
#[test]
fn test_app_start_warm_normalized() {
let mut attributes = Annotated::new(attributes! {
"app_start_warm" => 567.0,
"app.vitals.start.warm.value" => 567.0,
});

normalize_mobile_attributes(&mut attributes);
Expand All @@ -356,7 +360,7 @@ mod tests {
"type": "double",
"value": 567.0
},
"app_start_warm": {
"app.vitals.start.warm.value": {
"type": "double",
"value": 567.0
}
Expand All @@ -369,24 +373,24 @@ mod tests {
let mut attributes = Annotated::new(attributes! {
APP__VITALS__START__VALUE => 999.0,
APP__VITALS__START__TYPE => "warm",
"app_start_cold" => 1234.0,
"app.vitals.start.cold.value" => 1234.0,
});

normalize_mobile_attributes(&mut attributes);

assert_annotated_snapshot!(attributes, @r#"
{
"app.vitals.start.cold.value": {
"type": "double",
"value": 1234.0
},
"app.vitals.start.type": {
"type": "string",
"value": "warm"
},
"app.vitals.start.value": {
"type": "double",
"value": 999.0
},
"app_start_cold": {
"type": "double",
"value": 1234.0
}
}
"#);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,13 @@ expression: attributes
"app.vitals.start.cold.value": {
"type": "double",
"value": 5000.0
},
"app.vitals.start.type": {
"type": "string",
"value": "cold"
},
"app.vitals.start.value": {
"type": "double",
"value": 5000.0
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ source: relay-event-normalization/src/eap/mobile.rs
expression: attributes
---
{
"app.vitals.start.type": {
"type": "string",
"value": "warm"
},
"app.vitals.start.value": {
"type": "double",
"value": 5000.0
},
"app.vitals.start.warm.value": {
"type": "double",
"value": 5000.0
Expand Down
4 changes: 2 additions & 2 deletions relay-event-normalization/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1423,8 +1423,8 @@ fn normalize_mobile_measurements(measurements: &mut Measurements) {
}

const APP_START_SOURCES: [(&str, Option<&str>); 5] = [
("app_start_cold", Some("cold")),
("app_start_warm", Some("warm")),
(APP_START_COLD, Some("cold")),
(APP_START_WARM, Some("warm")),
Comment on lines -1426 to +1427

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by change.

(APP__VITALS__START__VALUE, None),
(APP__VITALS__START__COLD__VALUE, None),
(APP__VITALS__START__WARM__VALUE, None),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use std::sync::LazyLock;

use regex::Regex;
use relay_base_schema::metrics::{DurationUnit, InformationUnit, MetricUnit};
use relay_conventions::measurements::{APP_START_COLD, APP_START_WARM};
use relay_event_schema::protocol::{
AppContext, BrowserContext, DeviceContext, Event, GpuContext, Measurement, MonitorContext,
OsContext, ProfileContext, ReplayContext, RuntimeContext, SentryTags, Span, Timestamp,
Expand Down Expand Up @@ -1546,9 +1547,9 @@ pub fn span_op_to_category(op: &str) -> Option<&str> {
/// Reads the event measurements to determine the start type of the event.
fn get_event_start_type(event: &Event) -> Option<&'static str> {
// Check the measurements on the event to determine what kind of start type the event is.
if event.measurement("app_start_cold").is_some() {
if event.measurement(APP_START_COLD).is_some() {
Some("cold")
} else if event.measurement("app_start_warm").is_some() {
} else if event.measurement(APP_START_WARM).is_some() {
Some("warm")
Comment on lines -1549 to 1552

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Drive-by change.

} else {
None
Expand Down
2 changes: 1 addition & 1 deletion relay-server/src/processing/spans/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ mod tests {
(DEVICE__MODEL, "iPhone17,5"),
],
&[
("app_start_cold", 1234.0),
(APP__VITALS__START__COLD__VALUE, 1234.0),
(APP__VITALS__TTFD__VALUE, 200_000.0),
],
);
Expand Down
11 changes: 11 additions & 0 deletions tests/integration/test_spans_standalone.py

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change I'm making in this file would've caught the bug.

Original file line number Diff line number Diff line change
Expand Up @@ -836,6 +836,7 @@ def test_mobile_measurements(
"origin": "mobile",
"exclusive_time": 104,
"measurements": {
"app_start_cold": {"value": 0.123, "unit": "millisecond"},
"frames_slow": {"value": 1},
"frames_frozen": {"value": 2},
"frames_total": {"value": 4},
Expand Down Expand Up @@ -894,6 +895,16 @@ def test_mobile_measurements(
"app.vitals.frames.total.count": {"value": 4.0, "type": "double"},
"frames_frozen_rate": {"value": 0.5, "type": "double"},
"frames_slow_rate": {"value": 0.25, "type": "double"},
"app.vitals.start.cold.value": {"value": 0.123, "type": "double"},
# These attributes are backfilled only in the V2 pipeline. In the legacy
# pipeline this logic doesn't exist.
**_if_dict(
mode == "v2",
{
"app.vitals.start.value": {"value": 0.123, "type": "double"},
"app.vitals.start.type": {"value": "cold", "type": "string"},
},
),
**attributes,
},
"downsampled_retention_days": 90,
Expand Down
Loading