Skip to content

Commit b8410a0

Browse files
authored
feat(browser): Add url.full attribute to resource spans (#21846)
This attribute is needed for resource span description inference in Relay (span streaming) closes #21749
1 parent 45f2219 commit b8410a0

3 files changed

Lines changed: 57 additions & 0 deletions

File tree

dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-resource-spans/test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,12 @@ sentryTest('adds resource spans to pageload transaction', async ({ getLocalTestU
6565
expect(scriptSpans?.map(({ description }) => description).sort()).toEqual(expectedScripts);
6666
expect(scriptSpans?.map(({ parent_span_id }) => parent_span_id)).toEqual(expectedScripts.map(() => spanId));
6767

68+
// The init bundle script is served from the test origin: its description is origin-relative,
69+
// but `url.full` retains the full absolute URL (needed for span description inference).
70+
const sameOriginScriptSpan = scriptSpans?.find(({ description }) => description === '/init.bundle.js');
71+
expect(sameOriginScriptSpan?.data?.['url.same_origin']).toBe(true);
72+
expect(sameOriginScriptSpan?.data?.['url.full']).toMatch(/^https?:\/\/.+\/init\.bundle\.js$/);
73+
6874
const customScriptSpan = scriptSpans?.find(
6975
({ description }) => description === 'https://sentry-test-site.example/path/to/script.js',
7076
);
@@ -94,6 +100,7 @@ sentryTest('adds resource spans to pageload transaction', async ({ getLocalTestU
94100
'server.address': 'sentry-test-site.example',
95101
'url.same_origin': false,
96102
'url.scheme': 'https',
103+
'url.full': 'https://sentry-test-site.example/path/to/image.svg',
97104
...(!isWebkitRun && {
98105
'http.response.status_code': expect.any(Number),
99106
'resource.render_blocking_status': 'non-blocking',
@@ -141,6 +148,7 @@ sentryTest('adds resource spans to pageload transaction', async ({ getLocalTestU
141148
'server.address': 'sentry-test-site.example',
142149
'url.same_origin': false,
143150
'url.scheme': 'https',
151+
'url.full': 'https://sentry-test-site.example/path/to/style.css',
144152
...(!isWebkitRun && {
145153
'http.response.status_code': expect.any(Number),
146154
'resource.render_blocking_status': 'non-blocking',
@@ -182,6 +190,7 @@ sentryTest('adds resource spans to pageload transaction', async ({ getLocalTestU
182190
'server.address': 'sentry-test-site.example',
183191
'url.same_origin': false,
184192
'url.scheme': 'https',
193+
'url.full': 'https://sentry-test-site.example/path/to/script.js',
185194
...(!isWebkitRun && {
186195
'http.response.status_code': expect.any(Number),
187196
'resource.render_blocking_status': 'non-blocking',

packages/browser-utils/src/metrics/browserMetrics.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
isPrimitive,
99
parseUrl,
1010
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
11+
SEMANTIC_ATTRIBUTE_URL_FULL,
1112
setMeasurement,
1213
spanToJSON,
1314
stringMatchesSomePattern,
@@ -774,6 +775,8 @@ export function _addResourceSpans(
774775

775776
attributes['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);
776777

778+
attributes[SEMANTIC_ATTRIBUTE_URL_FULL] = resourceUrl;
779+
777780
_setResourceRequestAttributes(entry, attributes, [
778781
// https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/responseStatus
779782
['responseStatus', 'http.response.status_code'],

packages/browser-utils/test/browser/browserMetrics.test.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,7 @@ describe('_addResourceSpans', () => {
471471
['url.scheme']: 'https',
472472
['server.address']: 'example.com',
473473
['url.same_origin']: true,
474+
['url.full']: resourceEntryName,
474475
['network.protocol.name']: 'http',
475476
['network.protocol.version']: '1.1',
476477
'http.request.connect_start': expect.any(Number),
@@ -491,6 +492,47 @@ describe('_addResourceSpans', () => {
491492
);
492493
});
493494

495+
it('sets url.full to the absolute resource URL with query and fragment while keeping the description origin-relative', () => {
496+
const spans: Span[] = [];
497+
498+
getClient()?.on('spanEnd', span => {
499+
spans.push(span);
500+
});
501+
502+
const entry = mockPerformanceResourceTiming({
503+
initiatorType: 'script',
504+
nextHopProtocol: 'http/1.1',
505+
});
506+
507+
_addResourceSpans(span, entry, 'https://example.com/assets/app.js?v=42#main', 100, 23, 345);
508+
509+
expect(spans).toHaveLength(1);
510+
const json = spanToJSON(spans[0]!);
511+
expect(json.description).toBe('/assets/app.js?v=42#main');
512+
expect(json.data['url.full']).toBe('https://example.com/assets/app.js?v=42#main');
513+
});
514+
515+
it('sets url.full to the full cross-origin URL', () => {
516+
const spans: Span[] = [];
517+
518+
getClient()?.on('spanEnd', span => {
519+
spans.push(span);
520+
});
521+
522+
const entry = mockPerformanceResourceTiming({
523+
initiatorType: 'img',
524+
nextHopProtocol: 'http/1.1',
525+
});
526+
527+
_addResourceSpans(span, entry, 'https://cdn.example.org/static/logo.png', 100, 23, 345);
528+
529+
expect(spans).toHaveLength(1);
530+
const json = spanToJSON(spans[0]!);
531+
expect(json.description).toBe('https://cdn.example.org/static/logo.png');
532+
expect(json.data['url.full']).toBe('https://cdn.example.org/static/logo.png');
533+
expect(json.data['url.same_origin']).toBe(false);
534+
});
535+
494536
it('creates a variety of resource spans', () => {
495537
const spans: Span[] = [];
496538

@@ -611,6 +653,7 @@ describe('_addResourceSpans', () => {
611653
['url.scheme']: 'https',
612654
['server.address']: 'example.com',
613655
['url.same_origin']: true,
656+
['url.full']: resourceEntryName,
614657
['network.protocol.name']: 'http',
615658
['network.protocol.version']: '2',
616659
}),
@@ -644,6 +687,7 @@ describe('_addResourceSpans', () => {
644687
'server.address': 'example.com',
645688
'url.same_origin': true,
646689
'url.scheme': 'https',
690+
'url.full': resourceEntryName,
647691
['network.protocol.name']: 'http',
648692
['network.protocol.version']: '3',
649693
}),
@@ -696,6 +740,7 @@ describe('_addResourceSpans', () => {
696740
'server.address': 'example.com',
697741
'url.same_origin': true,
698742
'url.scheme': 'https',
743+
'url.full': resourceEntryName,
699744
['network.protocol.name']: 'http',
700745
['network.protocol.version']: '3',
701746
'http.request.connect_start': expect.any(Number),

0 commit comments

Comments
 (0)