diff --git a/.size-limit.js b/.size-limit.js index c4b37635ecda..f1dd4dc668c1 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -221,7 +221,7 @@ module.exports = [ name: 'CDN Bundle (incl. Tracing, Replay, Logs, Metrics)', path: createCDNPath('bundle.tracing.replay.logs.metrics.min.js'), gzip: true, - limit: '83 KB', + limit: '83.5 KB', }, { name: 'CDN Bundle (incl. Tracing, Replay, Feedback)', @@ -283,7 +283,7 @@ module.exports = [ path: createCDNPath('bundle.tracing.replay.logs.metrics.min.js'), gzip: false, brotli: false, - limit: '255 KB', + limit: '255.5 KB', }, { name: 'CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed', @@ -297,7 +297,7 @@ module.exports = [ path: createCDNPath('bundle.tracing.replay.feedback.logs.metrics.min.js'), gzip: false, brotli: false, - limit: '268 KB', + limit: '268.5 KB', }, // Next.js SDK (ESM) { diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts b/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts index 9ea2197fff85..bd9e8438ad24 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/streamed/test.ts @@ -56,6 +56,8 @@ sentryTest( [ { content_type: 'application/vnd.sentry.items.span.v2+json', item_count: 4, type: 'span' }, { + version: 2, + ingest_settings: { infer_ip: 'never', infer_useragent: 'never' }, items: expect.any(Array), }, ], diff --git a/packages/core/src/tracing/spans/envelope.ts b/packages/core/src/tracing/spans/envelope.ts index 8429b22d7e1c..33f985fe198c 100644 --- a/packages/core/src/tracing/spans/envelope.ts +++ b/packages/core/src/tracing/spans/envelope.ts @@ -3,6 +3,7 @@ import type { DynamicSamplingContext, SpanContainerItem, StreamedSpanEnvelope } import type { SerializedStreamedSpan } from '../../types-hoist/span'; import { dsnToString } from '../../utils/dsn'; import { createEnvelope, getSdkMetadataForEnvelopeHeader } from '../../utils/envelope'; +import { isBrowser } from '../../utils/isBrowser'; /** * Creates a span v2 span streaming envelope @@ -12,9 +13,10 @@ export function createStreamedSpanEnvelope( dsc: Partial, client: Client, ): StreamedSpanEnvelope { + const options = client.getOptions(); const dsn = client.getDsn(); - const tunnel = client.getOptions().tunnel; - const sdk = getSdkMetadataForEnvelopeHeader(client.getOptions()._metadata); + const tunnel = options.tunnel; + const sdk = getSdkMetadataForEnvelopeHeader(options._metadata); const headers: StreamedSpanEnvelope[0] = { sent_at: new Date().toISOString(), @@ -23,9 +25,17 @@ export function createStreamedSpanEnvelope( ...(!!tunnel && dsn && { dsn: dsnToString(dsn) }), }; + const inferSetting = options.sendDefaultPii ? 'auto' : 'never'; + const spanContainer: SpanContainerItem = [ { type: 'span', item_count: serializedSpans.length, content_type: 'application/vnd.sentry.items.span.v2+json' }, - { items: serializedSpans }, + { + version: 2, + ...(isBrowser() && { + ingest_settings: { infer_ip: inferSetting, infer_useragent: inferSetting }, + }), + items: serializedSpans, + }, ]; return createEnvelope(headers, [spanContainer]); diff --git a/packages/core/src/types-hoist/span.ts b/packages/core/src/types-hoist/span.ts index a918cc57859c..7b0e59243cc4 100644 --- a/packages/core/src/types-hoist/span.ts +++ b/packages/core/src/types-hoist/span.ts @@ -69,6 +69,11 @@ export type SerializedStreamedSpan = Omit; }; diff --git a/packages/core/test/lib/tracing/spans/envelope.test.ts b/packages/core/test/lib/tracing/spans/envelope.test.ts index 197b7ed40365..04d443239e1e 100644 --- a/packages/core/test/lib/tracing/spans/envelope.test.ts +++ b/packages/core/test/lib/tracing/spans/envelope.test.ts @@ -1,9 +1,18 @@ -import { describe, expect, it } from 'vitest'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import { createStreamedSpanEnvelope } from '../../../../src/tracing/spans/envelope'; import type { DynamicSamplingContext } from '../../../../src/types-hoist/envelope'; import type { SerializedStreamedSpan } from '../../../../src/types-hoist/span'; +import { isBrowser } from '../../../../src/utils/isBrowser'; import { getDefaultTestClientOptions, TestClient } from '../../../mocks/client'; +vi.mock('../../../../src/utils/isBrowser', () => ({ + isBrowser: vi.fn(() => false), +})); + +afterEach(() => { + vi.mocked(isBrowser).mockReturnValue(false); +}); + function createMockSerializedSpan(overrides: Partial = {}): SerializedStreamedSpan { return { trace_id: 'abc123', @@ -181,6 +190,7 @@ describe('createStreamedSpanEnvelope', () => { type: 'span', }, { + version: 2, items: [mockSpan], }, ], @@ -199,7 +209,7 @@ describe('createStreamedSpanEnvelope', () => { expect(envelopeItems).toEqual([ [ { type: 'span', item_count: 3, content_type: 'application/vnd.sentry.items.span.v2+json' }, - { items: [mockSpan1, mockSpan2, mockSpan3] }, + { version: 2, items: [mockSpan1, mockSpan2, mockSpan3] }, ], ]); }); @@ -222,11 +232,72 @@ describe('createStreamedSpanEnvelope', () => { type: 'span', }, { + version: 2, items: [], }, ], ], ]); }); + + it("includes ingest_settings with 'auto' values when in browser and sendDefaultPii is true", () => { + vi.mocked(isBrowser).mockReturnValue(true); + + const mockSpan = createMockSerializedSpan(); + const mockClient = new TestClient(getDefaultTestClientOptions({ sendDefaultPii: true })); + const dsc: Partial = {}; + + const envelopeItems = createStreamedSpanEnvelope([mockSpan], dsc, mockClient)[1]; + + expect(envelopeItems).toEqual([ + [ + { type: 'span', item_count: 1, content_type: 'application/vnd.sentry.items.span.v2+json' }, + { + version: 2, + ingest_settings: { infer_ip: 'auto', infer_useragent: 'auto' }, + items: [mockSpan], + }, + ], + ]); + }); + + it("includes ingest_settings with 'never' values when in browser and sendDefaultPii is false", () => { + vi.mocked(isBrowser).mockReturnValue(true); + + const mockSpan = createMockSerializedSpan(); + const mockClient = new TestClient(getDefaultTestClientOptions({ sendDefaultPii: false })); + const dsc: Partial = {}; + + const envelopeItems = createStreamedSpanEnvelope([mockSpan], dsc, mockClient)[1]; + + expect(envelopeItems).toEqual([ + [ + { type: 'span', item_count: 1, content_type: 'application/vnd.sentry.items.span.v2+json' }, + { + version: 2, + ingest_settings: { infer_ip: 'never', infer_useragent: 'never' }, + items: [mockSpan], + }, + ], + ]); + }); + + it('omits ingest_settings when not in browser', () => { + const mockSpan = createMockSerializedSpan(); + const mockClient = new TestClient(getDefaultTestClientOptions({ sendDefaultPii: true })); + const dsc: Partial = {}; + + const envelopeItems = createStreamedSpanEnvelope([mockSpan], dsc, mockClient)[1]; + + expect(envelopeItems).toEqual([ + [ + { type: 'span', item_count: 1, content_type: 'application/vnd.sentry.items.span.v2+json' }, + { + version: 2, + items: [mockSpan], + }, + ], + ]); + }); }); });