Skip to content

Commit caad0bc

Browse files
authored
Merge pull request #10205 from getsentry/DominikB2014/add-span-domain-to-span-data
feat(core): Add domain information to resource span data
2 parents acf58d3 + da68244 commit caad0bc

File tree

2 files changed

+81
-14
lines changed

2 files changed

+81
-14
lines changed

packages/tracing-internal/src/browser/metrics/index.ts

+16-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import type { IdleTransaction, Transaction } from '@sentry/core';
33
import { getActiveTransaction, setMeasurement } from '@sentry/core';
44
import type { Measurements, SpanContext } from '@sentry/types';
5-
import { browserPerformanceTimeOrigin, getComponentName, htmlTreeAsString, logger } from '@sentry/utils';
5+
import { browserPerformanceTimeOrigin, getComponentName, htmlTreeAsString, logger, parseUrl } from '@sentry/utils';
66

77
import { spanToJSON } from '@sentry/core';
88
import { DEBUG_BUILD } from '../../common/debug-build';
@@ -226,8 +226,7 @@ export function addPerformanceEntries(transaction: Transaction): void {
226226
break;
227227
}
228228
case 'resource': {
229-
const resourceName = (entry.name as string).replace(WINDOW.location.origin, '');
230-
_addResourceSpans(transaction, entry, resourceName, startTime, duration, timeOrigin);
229+
_addResourceSpans(transaction, entry, entry.name as string, startTime, duration, timeOrigin);
231230
break;
232231
}
233232
default:
@@ -408,7 +407,7 @@ export interface ResourceEntry extends Record<string, unknown> {
408407
export function _addResourceSpans(
409408
transaction: Transaction,
410409
entry: ResourceEntry,
411-
resourceName: string,
410+
resourceUrl: string,
412411
startTime: number,
413412
duration: number,
414413
timeOrigin: number,
@@ -419,20 +418,32 @@ export function _addResourceSpans(
419418
return;
420419
}
421420

421+
const parsedUrl = parseUrl(resourceUrl);
422+
422423
// eslint-disable-next-line @typescript-eslint/no-explicit-any
423424
const data: Record<string, any> = {};
424425
setResourceEntrySizeData(data, entry, 'transferSize', 'http.response_transfer_size');
425426
setResourceEntrySizeData(data, entry, 'encodedBodySize', 'http.response_content_length');
426427
setResourceEntrySizeData(data, entry, 'decodedBodySize', 'http.decoded_response_content_length');
428+
427429
if ('renderBlockingStatus' in entry) {
428430
data['resource.render_blocking_status'] = entry.renderBlockingStatus;
429431
}
432+
if (parsedUrl.protocol) {
433+
data['url.scheme'] = parsedUrl.protocol.split(':').pop(); // the protocol returned by parseUrl includes a :, but OTEL spec does not, so we remove it.
434+
}
435+
436+
if (parsedUrl.host) {
437+
data['server.address'] = parsedUrl.host;
438+
}
439+
440+
data['url.same_origin'] = resourceUrl.includes(WINDOW.location.origin);
430441

431442
const startTimestamp = timeOrigin + startTime;
432443
const endTimestamp = startTimestamp + duration;
433444

434445
_startChild(transaction, {
435-
description: resourceName,
446+
description: resourceUrl.replace(WINDOW.location.origin, ''),
436447
endTimestamp,
437448
op: entry.initiatorType ? `resource.${entry.initiatorType}` : 'resource.other',
438449
origin: 'auto.resource.browser.metrics',

packages/tracing-internal/test/browser/metrics/index.test.ts

+65-9
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,29 @@
11
import { Transaction } from '../../../src';
22
import type { ResourceEntry } from '../../../src/browser/metrics';
33
import { _addMeasureSpans, _addResourceSpans } from '../../../src/browser/metrics';
4+
import { WINDOW } from '../../../src/browser/types';
5+
6+
const mockWindowLocation = {
7+
ancestorOrigins: {},
8+
href: 'https://example.com/path/to/something',
9+
origin: 'https://example.com',
10+
protocol: 'https',
11+
host: 'example.com',
12+
hostname: 'example.com',
13+
port: '',
14+
pathname: '/path/to/something',
15+
search: '',
16+
hash: '',
17+
} as Window['location'];
18+
19+
const originalLocation = WINDOW.location;
20+
21+
const resourceEntryName = 'https://example.com/assets/to/css';
422

523
describe('_addMeasureSpans', () => {
624
// eslint-disable-next-line deprecation/deprecation
725
const transaction = new Transaction({ op: 'pageload', name: '/' });
26+
827
beforeEach(() => {
928
// eslint-disable-next-line deprecation/deprecation
1029
transaction.startChild = jest.fn();
@@ -42,6 +61,15 @@ describe('_addMeasureSpans', () => {
4261
describe('_addResourceSpans', () => {
4362
// eslint-disable-next-line deprecation/deprecation
4463
const transaction = new Transaction({ op: 'pageload', name: '/' });
64+
65+
beforeAll(() => {
66+
setGlobalLocation(mockWindowLocation);
67+
});
68+
69+
afterAll(() => {
70+
resetGlobalLocation();
71+
});
72+
4573
beforeEach(() => {
4674
// eslint-disable-next-line deprecation/deprecation
4775
transaction.startChild = jest.fn();
@@ -56,7 +84,7 @@ describe('_addResourceSpans', () => {
5684
decodedBodySize: 256,
5785
renderBlockingStatus: 'non-blocking',
5886
};
59-
_addResourceSpans(transaction, entry, '/assets/to/me', 123, 456, 100);
87+
_addResourceSpans(transaction, entry, resourceEntryName, 123, 456, 100);
6088

6189
// eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
6290
expect(transaction.startChild).toHaveBeenCalledTimes(0);
@@ -70,7 +98,7 @@ describe('_addResourceSpans', () => {
7098
decodedBodySize: 256,
7199
renderBlockingStatus: 'non-blocking',
72100
};
73-
_addResourceSpans(transaction, entry, '/assets/to/me', 123, 456, 100);
101+
_addResourceSpans(transaction, entry, 'https://example.com/assets/to/me', 123, 456, 100);
74102

75103
// eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
76104
expect(transaction.startChild).toHaveBeenCalledTimes(0);
@@ -89,7 +117,7 @@ describe('_addResourceSpans', () => {
89117
const startTime = 23;
90118
const duration = 356;
91119

92-
_addResourceSpans(transaction, entry, '/assets/to/css', startTime, duration, timeOrigin);
120+
_addResourceSpans(transaction, entry, resourceEntryName, startTime, duration, timeOrigin);
93121

94122
// eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
95123
expect(transaction.startChild).toHaveBeenCalledTimes(1);
@@ -100,6 +128,9 @@ describe('_addResourceSpans', () => {
100128
['http.response_content_length']: entry.encodedBodySize,
101129
['http.response_transfer_size']: entry.transferSize,
102130
['resource.render_blocking_status']: entry.renderBlockingStatus,
131+
['url.scheme']: 'https',
132+
['server.address']: 'example.com',
133+
['url.same_origin']: true,
103134
},
104135
description: '/assets/to/css',
105136
endTimestamp: timeOrigin + startTime + duration,
@@ -137,7 +168,7 @@ describe('_addResourceSpans', () => {
137168
const entry: ResourceEntry = {
138169
initiatorType,
139170
};
140-
_addResourceSpans(transaction, entry, '/assets/to/me', 123, 234, 465);
171+
_addResourceSpans(transaction, entry, 'https://example.com/assets/to/me', 123, 234, 465);
141172

142173
// eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
143174
expect(transaction.startChild).toHaveBeenLastCalledWith(
@@ -157,7 +188,7 @@ describe('_addResourceSpans', () => {
157188
renderBlockingStatus: 'non-blocking',
158189
};
159190

160-
_addResourceSpans(transaction, entry, '/assets/to/css', 100, 23, 345);
191+
_addResourceSpans(transaction, entry, resourceEntryName, 100, 23, 345);
161192

162193
// eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
163194
expect(transaction.startChild).toHaveBeenCalledTimes(1);
@@ -169,6 +200,9 @@ describe('_addResourceSpans', () => {
169200
['http.response_content_length']: entry.encodedBodySize,
170201
['http.response_transfer_size']: entry.transferSize,
171202
['resource.render_blocking_status']: entry.renderBlockingStatus,
203+
['url.scheme']: 'https',
204+
['server.address']: 'example.com',
205+
['url.same_origin']: true,
172206
},
173207
}),
174208
);
@@ -182,14 +216,19 @@ describe('_addResourceSpans', () => {
182216
decodedBodySize: 2147483647,
183217
};
184218

185-
_addResourceSpans(transaction, entry, '/assets/to/css', 100, 23, 345);
219+
_addResourceSpans(transaction, entry, resourceEntryName, 100, 23, 345);
186220

187221
// eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
188222
expect(transaction.startChild).toHaveBeenCalledTimes(1);
189223
// eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
190224
expect(transaction.startChild).toHaveBeenLastCalledWith(
191225
expect.objectContaining({
192-
data: {},
226+
data: { 'server.address': 'example.com', 'url.same_origin': true, 'url.scheme': 'https' },
227+
description: '/assets/to/css',
228+
endTimestamp: 468,
229+
op: 'resource.css',
230+
origin: 'auto.resource.browser.metrics',
231+
startTimestamp: 445,
193232
}),
194233
);
195234
});
@@ -204,15 +243,32 @@ describe('_addResourceSpans', () => {
204243
decodedBodySize: null,
205244
} as unknown as ResourceEntry;
206245

207-
_addResourceSpans(transaction, entry, '/assets/to/css', 100, 23, 345);
246+
_addResourceSpans(transaction, entry, resourceEntryName, 100, 23, 345);
208247

209248
// eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
210249
expect(transaction.startChild).toHaveBeenCalledTimes(1);
211250
// eslint-disable-next-line @typescript-eslint/unbound-method, deprecation/deprecation
212251
expect(transaction.startChild).toHaveBeenLastCalledWith(
213252
expect.objectContaining({
214-
data: {},
253+
data: { 'server.address': 'example.com', 'url.same_origin': true, 'url.scheme': 'https' },
254+
description: '/assets/to/css',
255+
endTimestamp: 468,
256+
op: 'resource.css',
257+
origin: 'auto.resource.browser.metrics',
258+
startTimestamp: 445,
215259
}),
216260
);
217261
});
218262
});
263+
264+
const setGlobalLocation = (location: Location) => {
265+
// @ts-expect-error need to delete this in order to set to new value
266+
delete WINDOW.location;
267+
WINDOW.location = location;
268+
};
269+
270+
const resetGlobalLocation = () => {
271+
// @ts-expect-error need to delete this in order to set to new value
272+
delete WINDOW.location;
273+
WINDOW.location = originalLocation;
274+
};

0 commit comments

Comments
 (0)