diff --git a/CHANGELOG.md b/CHANGELOG.md index 13485621ee..9c35ee18b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ **Features**: - Add inbound filters option to filter legacy Edge browsers (i.e. versions 12-18 ) ([#2650](https://github.com/getsentry/relay/pull/2650)) +- Group resource spans by scrubbed domain and filename. ([#2654](https://github.com/getsentry/relay/pull/2654)) **Internal**: diff --git a/relay-event-normalization/src/normalize/span/description/mod.rs b/relay-event-normalization/src/normalize/span/description/mod.rs index 3be9408058..96f6554bd3 100644 --- a/relay-event-normalization/src/normalize/span/description/mod.rs +++ b/relay-event-normalization/src/normalize/span/description/mod.rs @@ -228,14 +228,24 @@ fn scrub_resource(string: &str) -> Option { let path = scrub_resource_path(url.path()); format!("chrome-extension://*{path}") } + "moz-extension" => { + let path = scrub_resource_path(url.path()); + format!("moz-extension://*{path}") + } scheme => { - let path = url.path(); - let path = scrub_resource_path(path); + let segments = url.path_segments(); + let segment_count = segments.map(|s| s.count()).unwrap_or_default(); let domain = url .domain() .and_then(|d| normalize_domain(d, url.port())) .unwrap_or("".into()); - format!("{scheme}://{domain}{path}") + let last_segment = url + .path_segments() + .and_then(|s| s.last()) + .unwrap_or_default(); + let sep = if segment_count > 1 { "*/" } else { "" }; + let last_segment = scrub_resource_path(last_segment); + format!("{scheme}://{domain}/{sep}{last_segment}") } }; @@ -465,70 +475,70 @@ mod tests { resource_script, "https://example.com/static/chunks/vendors-node_modules_somemodule_v1.2.3_mini-dist_index_js-client_dist-6c733292-f3cd-11ed-a05b-0242ac120003-0dc369dcf3d311eda05b0242ac120003.[hash].abcd1234.chunk.js-0242ac120003.map", "resource.script", - "https://example.com/static/chunks/*.map" + "https://example.com/*/*.map" ); span_description_test!( resource_script_numeric_filename, "https://example.com/static/chunks/09876543211234567890", "resource.script", - "https://example.com/static/chunks/*" + "https://example.com/*/*" ); span_description_test!( resource_css, "https://example.com/assets/dark_high_contrast-764fa7c8-f3cd-11ed-a05b-0242ac120003.css", "resource.css", - "https://example.com/assets/dark_high_contrast-*.css" + "https://example.com/*/dark_high_contrast-*.css" ); span_description_test!( integer_in_resource, "https://example.com/assets/this_is-a_good_resource-123-scrub_me.js", "resource.css", - "https://example.com/assets/*.js" + "https://example.com/*/*.js" ); span_description_test!( resource_query_params, "/organization-avatar/123/?s=120", "resource.img", - "/organization-avatar/*/" + "/*/" ); span_description_test!( resource_query_params2, "https://data.domain.com/data/guide123.gif?jzb=3f535634H467g5-2f256f&ct=1234567890&v=1.203.0_prod", "resource.img", - "https://*.domain.com/data/guide*.gif" + "https://*.domain.com/*/guide*.gif" ); span_description_test!( resource_no_ids, "https://data.domain.com/data/guide.gif", "resource.img", - "https://*.domain.com/data/guide.gif" + "https://*.domain.com/*/guide.gif" ); span_description_test!( resource_webpack, "https://domain.com/path/to/app-1f90d5.f012d11690e188c96fe6.js", "resource.js", - "https://domain.com/path/to/app-*.*.js" + "https://domain.com/*/app-*.*.js" ); span_description_test!( resource_vite, "webroot/assets/Profile-73f6525d.js", "resource.js", - "webroot/assets/Profile-*.js" + "*/Profile-*.js" ); span_description_test!( resource_vite_css, "webroot/assets/Shop-1aff80f7.css", "resource.css", - "webroot/assets/Shop-*.css" + "*/Shop-*.css" ); span_description_test!( @@ -542,7 +552,7 @@ mod tests { urlencoded_path_segments, "https://some.domain.com/embed/%2Fembed%2Fdashboards%2F20%3FSlug%3Dsomeone%*hide_title%3Dtrue", "resource.iframe", - "https://*.domain.com/embed/*" + "https://*.domain.com/*/*" ); span_description_test!( @@ -556,7 +566,7 @@ mod tests { random_string2, "http://domain.com/fy2XSqBMqkEm_qZZH3RrzvBTKg4/qltdXIJWTF_cuwt3uKmcwWBc1DM/z1a--BVsUI_oyUjJR12pDBcOIn5.dom.jsonp", "resource.script", - "http://domain.com/*/*/*.jsonp" + "http://domain.com/*/*.jsonp" ); span_description_test!( @@ -598,7 +608,7 @@ mod tests { resource_url_with_fragment, "https://data.domain.com/data/guide123.gif#url=someotherurl", "resource.img", - "https://*.domain.com/data/guide*.gif" + "https://*.domain.com/*/guide*.gif" ); span_description_test!( @@ -642,28 +652,28 @@ mod tests { resource_img_semi_colon, "http://www.foo.com/path/to/resource;param1=test;param2=ing", "resource.img", - "http://*.foo.com/path/to/*" + "http://*.foo.com/*/*" ); span_description_test!( resource_img_comma_with_extension, "https://example.org/p/fit=cover,width=150,height=150,format=auto,quality=90/media/photosV2/weird-stuff-123-234-456.jpg", "resource.img", - "https://example.org/p/*/media/photos*/weird-stuff-*-*-*.jpg" + "https://example.org/*/weird-stuff-*-*-*.jpg" ); span_description_test!( resource_img_path_with_comma, "/help/purchase-details/1,*,0&fmt=webp&qlt=*,1&fit=constrain,0&op_sharpen=0&resMode=sharp2&iccEmbed=0&printRes=*", "resource.img", - "/help/purchase-details/*" + "/*/*" ); span_description_test!( resource_script_random_path_only, "/ERs-sUsu3/wd4/LyMTWg/Ot1Om4m8cu3p7a/QkJWAQ/FSYL/GBlxb3kB", "resource.script", - "/*/*/*/*/*/*/*" + "/*/*" ); span_description_test!( @@ -677,21 +687,21 @@ mod tests { resource_script_extension_in_segment, "https://domain.com/foo.bar/resource.js", "resource.script", - "https://domain.com/foo.bar/resource.js" + "https://domain.com/*/resource.js" ); span_description_test!( resource_script_missing_scheme, "domain.com/foo.bar/resource.js", "resource.script", - "domain.com/foo.bar/resource.js" + "*/resource.js" ); span_description_test!( resource_script_missing_scheme_integer_id, "domain.com/zero-length-00", "resource.script", - "domain.com/zero-length-*" + "*/zero-length-*" ); #[test] diff --git a/relay-server/src/metrics_extraction/event.rs b/relay-server/src/metrics_extraction/event.rs index 0436442bcf..aef4566d19 100644 --- a/relay-server/src/metrics_extraction/event.rs +++ b/relay-server/src/metrics_extraction/event.rs @@ -441,7 +441,7 @@ mod tests { "start_timestamp": 1694732407.8367, "exclusive_time": 477.800131, "description": "https://cdn.domain.com/path/to/file-hk2YHeW7Eo2XLCiE38F1Fz22KuljsgCAD6hyWCyOYZM.css", - "op": "resource.link", + "op": "resource.css", "span_id": "97c0ef9770a02f9d", "parent_span_id": "9756d8d7b2b364ff", "trace_id": "77aeb1c16bb544a4a39b8d42944947a3", @@ -459,7 +459,7 @@ mod tests { "span_id": "97c0ef9770a02f9d", "parent_span_id": "9756d8d7b2b364ff", "trace_id": "77aeb1c16bb544a4a39b8d42944947a3", - "op": "resource.link", + "op": "resource.script", "description": "domain.com/zero-length-00", "data": { "http.decoded_response_content_length": 0, @@ -980,7 +980,7 @@ mod tests { "start_timestamp": 1694732407.8367, "exclusive_time": 477.800131, "description": "https://cdn.domain.com/path/to/file-hk2YHeW7Eo2XLCiE38F1Fz22KuljsgCAD6hyWCyOYZM.css", - "op": "resource.link", + "op": "resource.css", "span_id": "97c0ef9770a02f9d", "parent_span_id": "9756d8d7b2b364ff", "trace_id": "77aeb1c16bb544a4a39b8d42944947a3", diff --git a/relay-server/src/metrics_extraction/snapshots/relay_server__metrics_extraction__event__tests__extract_span_metrics_all_modules.snap b/relay-server/src/metrics_extraction/snapshots/relay_server__metrics_extraction__event__tests__extract_span_metrics_all_modules.snap index 4010031e8c..afcb8d9529 100644 --- a/relay-server/src/metrics_extraction/snapshots/relay_server__metrics_extraction__event__tests__extract_span_metrics_all_modules.snap +++ b/relay-server/src/metrics_extraction/snapshots/relay_server__metrics_extraction__event__tests__extract_span_metrics_all_modules.snap @@ -1169,9 +1169,9 @@ expression: metrics "environment": "fake_environment", "http.status_code": "500", "span.category": "resource", - "span.description": "http://domain/static/myscript-*.js", + "span.description": "http://domain/*/myscript-*.js", "span.domain": "domain", - "span.group": "022f81fdf31228bf", + "span.group": "ea1af0b8d5f734c5", "span.op": "resource.script", "span.status": "ok", "transaction": "gEt /api/:version/users/", @@ -1192,9 +1192,9 @@ expression: metrics "environment": "fake_environment", "http.status_code": "500", "span.category": "resource", - "span.description": "http://domain/static/myscript-*.js", + "span.description": "http://domain/*/myscript-*.js", "span.domain": "domain", - "span.group": "022f81fdf31228bf", + "span.group": "ea1af0b8d5f734c5", "span.op": "resource.script", "span.status": "ok", "transaction.method": "POST", @@ -1215,10 +1215,10 @@ expression: metrics "http.status_code": "500", "resource.render_blocking_status": "blocking", "span.category": "resource", - "span.description": "https://*.domain.com/path/to/*.css", + "span.description": "https://*.domain.com/*/*.css", "span.domain": "*.domain.com", - "span.group": "52c9cf14584b4101", - "span.op": "resource.link", + "span.group": "d744fa0716ef1142", + "span.op": "resource.css", "transaction": "gEt /api/:version/users/", "transaction.method": "POST", "transaction.op": "myop", @@ -1238,14 +1238,71 @@ expression: metrics "http.status_code": "500", "resource.render_blocking_status": "blocking", "span.category": "resource", - "span.description": "https://*.domain.com/path/to/*.css", + "span.description": "https://*.domain.com/*/*.css", "span.domain": "*.domain.com", - "span.group": "52c9cf14584b4101", - "span.op": "resource.link", + "span.group": "d744fa0716ef1142", + "span.op": "resource.css", "transaction.method": "POST", "transaction.op": "myop", }, }, + Bucket { + timestamp: UnixTimestamp(1694732408), + width: 0, + name: "d:spans/http.response_content_length@byte", + value: Distribution( + [ + 36170.0, + ], + ), + tags: { + "environment": "fake_environment", + "resource.render_blocking_status": "blocking", + "span.description": "https://*.domain.com/*/*.css", + "span.domain": "*.domain.com", + "span.group": "d744fa0716ef1142", + "span.op": "resource.css", + "transaction": "gEt /api/:version/users/", + }, + }, + Bucket { + timestamp: UnixTimestamp(1694732408), + width: 0, + name: "d:spans/http.decoded_response_content_length@byte", + value: Distribution( + [ + 128950.0, + ], + ), + tags: { + "environment": "fake_environment", + "resource.render_blocking_status": "blocking", + "span.description": "https://*.domain.com/*/*.css", + "span.domain": "*.domain.com", + "span.group": "d744fa0716ef1142", + "span.op": "resource.css", + "transaction": "gEt /api/:version/users/", + }, + }, + Bucket { + timestamp: UnixTimestamp(1694732408), + width: 0, + name: "d:spans/http.response_transfer_size@byte", + value: Distribution( + [ + 36470.0, + ], + ), + tags: { + "environment": "fake_environment", + "resource.render_blocking_status": "blocking", + "span.description": "https://*.domain.com/*/*.css", + "span.domain": "*.domain.com", + "span.group": "d744fa0716ef1142", + "span.op": "resource.css", + "transaction": "gEt /api/:version/users/", + }, + }, Bucket { timestamp: UnixTimestamp(1694732408), width: 0, @@ -1259,9 +1316,9 @@ expression: metrics "environment": "fake_environment", "http.status_code": "500", "span.category": "resource", - "span.description": "domain.com/zero-length-*", - "span.group": "c30e0c2b28682cb7", - "span.op": "resource.link", + "span.description": "*/zero-length-*", + "span.group": "c7d3c9d83f92123a", + "span.op": "resource.script", "transaction": "gEt /api/:version/users/", "transaction.method": "POST", "transaction.op": "myop", @@ -1280,9 +1337,9 @@ expression: metrics "environment": "fake_environment", "http.status_code": "500", "span.category": "resource", - "span.description": "domain.com/zero-length-*", - "span.group": "c30e0c2b28682cb7", - "span.op": "resource.link", + "span.description": "*/zero-length-*", + "span.group": "c7d3c9d83f92123a", + "span.op": "resource.script", "transaction.method": "POST", "transaction.op": "myop", },