diff --git a/relay-dynamic-config/src/defaults.rs b/relay-dynamic-config/src/defaults.rs index 9642b6cabc8..003d8f07098 100644 --- a/relay-dynamic-config/src/defaults.rs +++ b/relay-dynamic-config/src/defaults.rs @@ -1074,6 +1074,84 @@ pub fn hardcoded_span_metrics() -> Vec<(GroupKey, Vec, Vec::from_json(json).unwrap().0.unwrap(); + + let performance_score: PerformanceScoreConfig = serde_json::from_value(json!({ + "profiles": [ + { + "name": "Default", + "scoreComponents": [ + { + "measurement": "fcp", + "weight": 0.15, + "p10": 900.0, + "p50": 1600.0, + "optional": true, + }, + { + "measurement": "lcp", + "weight": 0.30, + "p10": 1200.0, + "p50": 2400.0, + "optional": true, + }, + { + "measurement": "cls", + "weight": 0.15, + "p10": 0.1, + "p50": 0.25, + "optional": true, + }, + { + "measurement": "ttfb", + "weight": 0.10, + "p10": 200.0, + "p50": 400.0, + "optional": true, + }, + ], + "condition": { + "op": "and", + "inner": [], + }, + } + ] + })) + .unwrap(); + + normalize( + &mut event, + &mut Meta::default(), + &NormalizationConfig { + performance_score: Some(&performance_score), + ..Default::default() + }, + ); + + insta::assert_ron_snapshot!(SerializableAnnotated(&event.measurements), {}, @r###" + { + "lcp": { + "value": 1200.0, + "unit": "millisecond", + }, + "score.lcp": { + "value": 0.8999999314038525, + "unit": "ratio", + }, + "score.total": { + "value": 0.8999999314038525, + "unit": "ratio", + }, + "score.weight.cls": { + "value": 0.0, + "unit": "ratio", + }, + "score.weight.fcp": { + "value": 0.0, + "unit": "ratio", + }, + "score.weight.lcp": { + "value": 1.0, + "unit": "ratio", + }, + "score.weight.ttfb": { + "value": 0.0, + "unit": "ratio", + }, + } + "###); + } + #[test] fn test_computed_performance_score_uses_first_matching_profile() { let json = r#" diff --git a/relay-server/src/metrics_extraction/event.rs b/relay-server/src/metrics_extraction/event.rs index c99bd07be56..785a2881bce 100644 --- a/relay-server/src/metrics_extraction/event.rs +++ b/relay-server/src/metrics_extraction/event.rs @@ -1823,6 +1823,46 @@ mod tests { } } + #[test] + fn test_extract_span_metrics_lcp_performance_score() { + let json = r#" + { + "op": "ui.webvital.lcp", + "span_id": "bd429c44b67a3eb4", + "start_timestamp": 1597976302.0000000, + "timestamp": 1597976302.0000000, + "exclusive_time": 0, + "trace_id": "ff62a8b040f340bda5d830223def1d81", + "sentry_tags": { + "browser.name": "Chrome", + "op": "ui.webvital.lcp" + }, + "measurements": { + "score.total": {"value": 1.0}, + "score.lcp": {"value": 1.0}, + "score.weight.lcp": {"value": 1.0}, + "lcp": {"value": 1200.0} + } + } + "#; + let span = Annotated::::from_json(json).unwrap(); + let metrics = generic::extract_metrics( + span.value().unwrap(), + combined_config([Feature::ExtractCommonSpanMetricsFromEvent], None).combined(), + ); + + for mri in [ + "d:transactions/measurements.lcp@ratio", + "d:transactions/measurements.score.lcp@ratio", + "d:transactions/measurements.score.total@ratio", + "d:transactions/measurements.score.weight.lcp@ratio", + ] { + assert!(metrics.iter().any(|b| &*b.name == mri)); + assert!(metrics.iter().any(|b| b.tags.contains_key("browser.name"))); + assert!(metrics.iter().any(|b| b.tags.contains_key("span.op"))); + } + } + #[test] fn extracts_span_metrics_from_transaction() { let event = r#"