diff --git a/.size-limit.js b/.size-limit.js index 012fea839bda..10efb849a582 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -52,7 +52,7 @@ module.exports = [ path: 'packages/browser/build/npm/esm/index.js', import: createImport('init', 'browserTracingIntegration', 'replayIntegration'), gzip: true, - limit: '71 KB', + limit: '70.1 KB', modifyWebpackConfig: function (config) { const webpack = require('webpack'); @@ -206,7 +206,7 @@ module.exports = [ import: createImport('init'), ignore: ['next/router', 'next/constants'], gzip: true, - limit: '42.5 KB', + limit: '42 KB', }, // SvelteKit SDK (ESM) { diff --git a/packages/browser-utils/src/metrics/browserMetrics.ts b/packages/browser-utils/src/metrics/browserMetrics.ts index 646d73ef29c3..71470a0d8706 100644 --- a/packages/browser-utils/src/metrics/browserMetrics.ts +++ b/packages/browser-utils/src/metrics/browserMetrics.ts @@ -1,11 +1,10 @@ /* eslint-disable max-lines */ -import type { Measurements, Span, SpanAttributes, SpanAttributeValue, StartSpanOptions } from '@sentry/core'; +import type { Measurements, Span, SpanAttributes, StartSpanOptions } from '@sentry/core'; import { browserPerformanceTimeOrigin, getActiveSpan, getComponentName, htmlTreeAsString, - isPrimitive, parseUrl, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, setMeasurement, @@ -340,7 +339,7 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries case 'mark': case 'paint': case 'measure': { - _addMeasureSpans(span, entry as PerformanceMeasure, startTime, duration, timeOrigin); + _addMeasureSpans(span, entry, startTime, duration, timeOrigin); // capture web vitals const firstHidden = getVisibilityWatcher(); @@ -422,7 +421,7 @@ export function addPerformanceEntries(span: Span, options: AddPerformanceEntries */ export function _addMeasureSpans( span: Span, - entry: PerformanceMeasure, + entry: PerformanceEntry, startTime: number, duration: number, timeOrigin: number, @@ -451,34 +450,6 @@ export function _addMeasureSpans( attributes['sentry.browser.measure_start_time'] = measureStartTimestamp; } - // https://developer.mozilla.org/en-US/docs/Web/API/Performance/measure#detail - if (entry.detail) { - // Handle detail as an object - if (typeof entry.detail === 'object') { - for (const [key, value] of Object.entries(entry.detail)) { - if (value && isPrimitive(value)) { - attributes[`sentry.browser.measure.detail.${key}`] = value as SpanAttributeValue; - } else { - try { - // This is user defined so we can't guarantee it's serializable - attributes[`sentry.browser.measure.detail.${key}`] = JSON.stringify(value); - } catch { - // skip - } - } - } - } else if (isPrimitive(entry.detail)) { - attributes['sentry.browser.measure.detail'] = entry.detail as SpanAttributeValue; - } else { - // This is user defined so we can't guarantee it's serializable - try { - attributes['sentry.browser.measure.detail'] = JSON.stringify(entry.detail); - } catch { - // skip - } - } - } - // Measurements from third parties can be off, which would create invalid spans, dropping transactions in the process. if (measureStartTimestamp <= measureEndTimestamp) { startAndEndSpan(span, measureStartTimestamp, measureEndTimestamp, { diff --git a/packages/browser-utils/test/browser/browserMetrics.test.ts b/packages/browser-utils/test/browser/browserMetrics.test.ts index a6004b73622a..99cf451f824e 100644 --- a/packages/browser-utils/test/browser/browserMetrics.test.ts +++ b/packages/browser-utils/test/browser/browserMetrics.test.ts @@ -70,8 +70,7 @@ describe('_addMeasureSpans', () => { name: 'measure-1', duration: 10, startTime: 12, - detail: null, - } as PerformanceMeasure; + } as PerformanceEntry; const timeOrigin = 100; const startTime = 23; @@ -107,8 +106,7 @@ describe('_addMeasureSpans', () => { name: 'measure-1', duration: 10, startTime: 12, - detail: null, - } as PerformanceMeasure; + } as PerformanceEntry; const timeOrigin = 100; const startTime = 23; @@ -118,165 +116,6 @@ describe('_addMeasureSpans', () => { expect(spans).toHaveLength(0); }); - - it('adds measure spans with primitive detail', () => { - const spans: Span[] = []; - - getClient()?.on('spanEnd', span => { - spans.push(span); - }); - - const entry = { - entryType: 'measure', - name: 'measure-1', - duration: 10, - startTime: 12, - detail: 'test-detail', - } as PerformanceMeasure; - - const timeOrigin = 100; - const startTime = 23; - const duration = 356; - - _addMeasureSpans(span, entry, startTime, duration, timeOrigin); - - expect(spans).toHaveLength(1); - expect(spanToJSON(spans[0]!)).toEqual( - expect.objectContaining({ - description: 'measure-1', - start_timestamp: timeOrigin + startTime, - timestamp: timeOrigin + startTime + duration, - op: 'measure', - origin: 'auto.resource.browser.metrics', - data: { - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'measure', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics', - 'sentry.browser.measure.detail': 'test-detail', - }, - }), - ); - }); - - it('adds measure spans with object detail', () => { - const spans: Span[] = []; - - getClient()?.on('spanEnd', span => { - spans.push(span); - }); - - const detail = { - component: 'Button', - action: 'click', - metadata: { id: 123 }, - }; - - const entry = { - entryType: 'measure', - name: 'measure-1', - duration: 10, - startTime: 12, - detail, - } as PerformanceMeasure; - - const timeOrigin = 100; - const startTime = 23; - const duration = 356; - - _addMeasureSpans(span, entry, startTime, duration, timeOrigin); - - expect(spans).toHaveLength(1); - expect(spanToJSON(spans[0]!)).toEqual( - expect.objectContaining({ - description: 'measure-1', - start_timestamp: timeOrigin + startTime, - timestamp: timeOrigin + startTime + duration, - op: 'measure', - origin: 'auto.resource.browser.metrics', - data: { - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'measure', - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.resource.browser.metrics', - 'sentry.browser.measure.detail.component': 'Button', - 'sentry.browser.measure.detail.action': 'click', - 'sentry.browser.measure.detail.metadata': JSON.stringify({ id: 123 }), - }, - }), - ); - }); - - it('handles non-primitive detail values by stringifying them', () => { - const spans: Span[] = []; - - getClient()?.on('spanEnd', span => { - spans.push(span); - }); - - const detail = { - component: 'Button', - action: 'click', - metadata: { id: 123 }, - callback: () => {}, - }; - - const entry = { - entryType: 'measure', - name: 'measure-1', - duration: 10, - startTime: 12, - detail, - } as PerformanceMeasure; - - const timeOrigin = 100; - const startTime = 23; - const duration = 356; - - _addMeasureSpans(span, entry, startTime, duration, timeOrigin); - - expect(spans).toHaveLength(1); - const spanData = spanToJSON(spans[0]!).data; - expect(spanData['sentry.browser.measure.detail.component']).toBe('Button'); - expect(spanData['sentry.browser.measure.detail.action']).toBe('click'); - expect(spanData['sentry.browser.measure.detail.metadata']).toBe(JSON.stringify({ id: 123 })); - expect(spanData['sentry.browser.measure.detail.callback']).toBe(JSON.stringify(detail.callback)); - }); - - it('handles errors in object detail value stringification', () => { - const spans: Span[] = []; - - getClient()?.on('spanEnd', span => { - spans.push(span); - }); - - const circular: any = {}; - circular.self = circular; - - const detail = { - component: 'Button', - action: 'click', - circular, - }; - - const entry = { - entryType: 'measure', - name: 'measure-1', - duration: 10, - startTime: 12, - detail, - } as PerformanceMeasure; - - const timeOrigin = 100; - const startTime = 23; - const duration = 356; - - // Should not throw - _addMeasureSpans(span, entry, startTime, duration, timeOrigin); - - expect(spans).toHaveLength(1); - const spanData = spanToJSON(spans[0]!).data; - expect(spanData['sentry.browser.measure.detail.component']).toBe('Button'); - expect(spanData['sentry.browser.measure.detail.action']).toBe('click'); - // The circular reference should be skipped - expect(spanData['sentry.browser.measure.detail.circular']).toBeUndefined(); - }); }); describe('_addResourceSpans', () => { @@ -625,6 +464,7 @@ describe('_addNavigationSpans', () => { transferSize: 14726, encodedBodySize: 14426, decodedBodySize: 67232, + responseStatus: 200, serverTiming: [], unloadEventStart: 0, unloadEventEnd: 0,