diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 25797f31a008..d65491640642 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -568,6 +568,7 @@ jobs: - bundle_min - bundle_replay - bundle_tracing + - bundle_tracing_logs_metrics - bundle_tracing_replay - bundle_tracing_replay_feedback - bundle_tracing_replay_feedback_min diff --git a/.size-limit.js b/.size-limit.js index 65496e02a8ae..a43d4d61e527 100644 --- a/.size-limit.js +++ b/.size-limit.js @@ -186,6 +186,12 @@ module.exports = [ gzip: true, limit: '43 KB', }, + { + name: 'CDN Bundle (incl. Tracing, Logs, Metrics)', + path: createCDNPath('bundle.tracing.logs.metrics.min.js'), + gzip: true, + limit: '44 KB', + }, { name: 'CDN Bundle (incl. Tracing, Replay)', path: createCDNPath('bundle.tracing.replay.min.js'), @@ -213,6 +219,13 @@ module.exports = [ brotli: false, limit: '127 KB', }, + { + name: 'CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed', + path: createCDNPath('bundle.tracing.logs.metrics.min.js'), + gzip: false, + brotli: false, + limit: '130 KB', + }, { name: 'CDN Bundle (incl. Tracing, Replay) - uncompressed', path: createCDNPath('bundle.tracing.replay.min.js'), diff --git a/dev-packages/browser-integration-tests/README.md b/dev-packages/browser-integration-tests/README.md index 6d1f69cde973..c5fa72bf6747 100644 --- a/dev-packages/browser-integration-tests/README.md +++ b/dev-packages/browser-integration-tests/README.md @@ -74,8 +74,9 @@ To filter tests by their title: You can refer to [Playwright documentation](https://playwright.dev/docs/test-cli) for other CLI options. -You can set env variable `PW_BUNDLE` to set specific build or bundle to test against. Available options: `esm`, `cjs`, -`bundle`, `bundle_min` +You can set env variable `PW_BUNDLE` to set specific build or bundle to test against. Available options include: `esm`, `cjs`, +`bundle`, `bundle_min`, `bundle_tracing`, `bundle_tracing_logs_metrics`, `bundle_replay`, `bundle_tracing_replay_feedback`, and more. +See `package.json` scripts for the full list of `test:bundle:*` commands. ### Troubleshooting diff --git a/dev-packages/browser-integration-tests/package.json b/dev-packages/browser-integration-tests/package.json index 9e178c0d6a91..dab25fa1e7f1 100644 --- a/dev-packages/browser-integration-tests/package.json +++ b/dev-packages/browser-integration-tests/package.json @@ -23,6 +23,9 @@ "test:bundle:replay:min": "PW_BUNDLE=bundle_replay_min yarn test", "test:bundle:tracing": "PW_BUNDLE=bundle_tracing yarn test", "test:bundle:tracing:min": "PW_BUNDLE=bundle_tracing_min yarn test", + "test:bundle:tracing_logs_metrics": "PW_BUNDLE=bundle_tracing_logs_metrics yarn test", + "test:bundle:tracing_logs_metrics:min": "PW_BUNDLE=bundle_tracing_logs_metrics_min yarn test", + "test:bundle:tracing_logs_metrics:debug_min": "PW_BUNDLE=bundle_tracing_logs_metrics_debug_min yarn test", "test:bundle:full": "PW_BUNDLE=bundle_tracing_replay_feedback yarn test", "test:bundle:full:min": "PW_BUNDLE=bundle_tracing_replay_feedback_min yarn test", "test:cjs": "PW_BUNDLE=cjs yarn test", diff --git a/dev-packages/browser-integration-tests/suites/public-api/logger/integration/test.ts b/dev-packages/browser-integration-tests/suites/public-api/logger/integration/test.ts index 29d1eabab1b3..40c2d18d29bd 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/logger/integration/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/logger/integration/test.ts @@ -4,12 +4,12 @@ import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, properFullEnvelopeRequestParser, - testingCdnBundle, + shouldSkipLogsTest, } from '../../../../utils/helpers'; sentryTest('should capture console object calls', async ({ getLocalTestUrl, page }) => { - // Only run this for npm package exports - sentryTest.skip(testingCdnBundle()); + // Only run this for npm package exports and CDN bundles with logs + sentryTest.skip(shouldSkipLogsTest()); const url = await getLocalTestUrl({ testDir: __dirname }); diff --git a/dev-packages/browser-integration-tests/suites/public-api/logger/scopeAttributes/test.ts b/dev-packages/browser-integration-tests/suites/public-api/logger/scopeAttributes/test.ts index 5f0f49bf21a9..c02a110046dd 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/logger/scopeAttributes/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/logger/scopeAttributes/test.ts @@ -4,11 +4,11 @@ import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, properFullEnvelopeRequestParser, - testingCdnBundle, + shouldSkipLogsTest, } from '../../../../utils/helpers'; sentryTest('captures logs with scope attributes', async ({ getLocalTestUrl, page }) => { - sentryTest.skip(testingCdnBundle()); + sentryTest.skip(shouldSkipLogsTest()); const url = await getLocalTestUrl({ testDir: __dirname }); diff --git a/dev-packages/browser-integration-tests/suites/public-api/logger/simple/test.ts b/dev-packages/browser-integration-tests/suites/public-api/logger/simple/test.ts index 8477ca6b52c8..aa2159d13bc1 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/logger/simple/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/logger/simple/test.ts @@ -4,12 +4,12 @@ import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, properFullEnvelopeRequestParser, - testingCdnBundle, + shouldSkipLogsTest, } from '../../../../utils/helpers'; sentryTest('should capture all logging methods', async ({ getLocalTestUrl, page }) => { - // Only run this for npm package exports - sentryTest.skip(testingCdnBundle()); + // Only run this for npm package exports and CDN bundles with logs + sentryTest.skip(shouldSkipLogsTest()); const url = await getLocalTestUrl({ testDir: __dirname }); diff --git a/dev-packages/browser-integration-tests/suites/public-api/metrics/afterCaptureMetric/test.ts b/dev-packages/browser-integration-tests/suites/public-api/metrics/afterCaptureMetric/test.ts index a89bdea81902..3361bbc50ab7 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/metrics/afterCaptureMetric/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/metrics/afterCaptureMetric/test.ts @@ -1,11 +1,12 @@ import { expect } from '@playwright/test'; import { sentryTest } from '../../../../utils/fixtures'; +import { shouldSkipMetricsTest } from '../../../../utils/helpers'; sentryTest( 'should emit afterCaptureMetric event with processed metric from beforeSendMetric', async ({ getLocalTestUrl, page }) => { - const bundle = process.env.PW_BUNDLE || ''; - if (bundle.startsWith('bundle') || bundle.startsWith('loader')) { + // Only run this for npm package exports and CDN bundles with metrics + if (shouldSkipMetricsTest()) { sentryTest.skip(); } diff --git a/dev-packages/browser-integration-tests/suites/public-api/metrics/simple/test.ts b/dev-packages/browser-integration-tests/suites/public-api/metrics/simple/test.ts index 655458c008a1..a983d9fbe728 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/metrics/simple/test.ts +++ b/dev-packages/browser-integration-tests/suites/public-api/metrics/simple/test.ts @@ -1,11 +1,15 @@ import { expect } from '@playwright/test'; import type { MetricEnvelope } from '@sentry/core'; import { sentryTest } from '../../../../utils/fixtures'; -import { getFirstSentryEnvelopeRequest, properFullEnvelopeRequestParser } from '../../../../utils/helpers'; +import { + getFirstSentryEnvelopeRequest, + properFullEnvelopeRequestParser, + shouldSkipMetricsTest, +} from '../../../../utils/helpers'; sentryTest('should capture all metric types', async ({ getLocalTestUrl, page }) => { - const bundle = process.env.PW_BUNDLE || ''; - if (bundle.startsWith('bundle') || bundle.startsWith('loader')) { + // Only run this for npm package exports and CDN bundles with metrics + if (shouldSkipMetricsTest()) { sentryTest.skip(); } diff --git a/dev-packages/browser-integration-tests/utils/generatePlugin.ts b/dev-packages/browser-integration-tests/utils/generatePlugin.ts index b1b1df410ca3..64a82f5f0e62 100644 --- a/dev-packages/browser-integration-tests/utils/generatePlugin.ts +++ b/dev-packages/browser-integration-tests/utils/generatePlugin.ts @@ -56,6 +56,9 @@ const BUNDLE_PATHS: Record> = { bundle_replay_min: 'build/bundles/bundle.replay.min.js', bundle_tracing: 'build/bundles/bundle.tracing.js', bundle_tracing_min: 'build/bundles/bundle.tracing.min.js', + bundle_tracing_logs_metrics: 'build/bundles/bundle.tracing.logs.metrics.js', + bundle_tracing_logs_metrics_min: 'build/bundles/bundle.tracing.logs.metrics.min.js', + bundle_tracing_logs_metrics_debug_min: 'build/bundles/bundle.tracing.logs.metrics.debug.min.js', bundle_tracing_replay: 'build/bundles/bundle.tracing.replay.js', bundle_tracing_replay_min: 'build/bundles/bundle.tracing.replay.min.js', bundle_tracing_replay_feedback: 'build/bundles/bundle.tracing.replay.feedback.js', @@ -245,7 +248,9 @@ class SentryScenarioGenerationPlugin { .replace('loader_', 'bundle_') .replace('_replay', '') .replace('_tracing', '') - .replace('_feedback', ''); + .replace('_feedback', '') + .replace('_logs', '') + .replace('_metrics', ''); // For feedback bundle, make sure to add modal & screenshot integrations if (bundleKey.includes('_feedback')) { diff --git a/dev-packages/browser-integration-tests/utils/helpers.ts b/dev-packages/browser-integration-tests/utils/helpers.ts index 0888b3e286b0..6cc5188d3c29 100644 --- a/dev-packages/browser-integration-tests/utils/helpers.ts +++ b/dev-packages/browser-integration-tests/utils/helpers.ts @@ -314,6 +314,30 @@ export function shouldSkipTracingTest(): boolean { return bundle != null && !bundle.includes('tracing') && !bundle.includes('esm') && !bundle.includes('cjs'); } +/** + * We can only test metrics tests in certain bundles/packages: + * - NPM (ESM, CJS) + * - CDN bundles that contain metrics + * + * @returns `true` if we should skip the metrics test + */ +export function shouldSkipMetricsTest(): boolean { + const bundle = process.env.PW_BUNDLE; + return bundle != null && !bundle.includes('metrics') && !bundle.includes('esm') && !bundle.includes('cjs'); +} + +/** + * We can only test logs tests in certain bundles/packages: + * - NPM (ESM, CJS) + * - CDN bundles that contain logs + * + * @returns `true` if we should skip the logs test + */ +export function shouldSkipLogsTest(): boolean { + const bundle = process.env.PW_BUNDLE; + return bundle != null && !bundle.includes('logs') && !bundle.includes('esm') && !bundle.includes('cjs'); +} + /** * @returns `true` if we are testing a CDN bundle */ diff --git a/packages/browser/rollup.bundle.config.mjs b/packages/browser/rollup.bundle.config.mjs index 57f1bd80b748..684db929b111 100644 --- a/packages/browser/rollup.bundle.config.mjs +++ b/packages/browser/rollup.bundle.config.mjs @@ -104,6 +104,13 @@ const tracingReplayFeedbackBaseBundleConfig = makeBaseBundleConfig({ outputFileBase: () => 'bundles/bundle.tracing.replay.feedback', }); +const tracingLogsMetricsBaseBundleConfig = makeBaseBundleConfig({ + bundleType: 'standalone', + entrypoints: ['src/index.bundle.tracing.logs.metrics.ts'], + licenseTitle: '@sentry/browser (Performance Monitoring, Logs, and Metrics)', + outputFileBase: () => 'bundles/bundle.tracing.logs.metrics', +}); + builds.push( ...makeBundleConfigVariants(baseBundleConfig), ...makeBundleConfigVariants(tracingBaseBundleConfig), @@ -112,6 +119,7 @@ builds.push( ...makeBundleConfigVariants(tracingReplayBaseBundleConfig), ...makeBundleConfigVariants(replayFeedbackBaseBundleConfig), ...makeBundleConfigVariants(tracingReplayFeedbackBaseBundleConfig), + ...makeBundleConfigVariants(tracingLogsMetricsBaseBundleConfig), ); export default builds; diff --git a/packages/browser/src/index.bundle.tracing.logs.metrics.ts b/packages/browser/src/index.bundle.tracing.logs.metrics.ts new file mode 100644 index 000000000000..ce6a65061385 --- /dev/null +++ b/packages/browser/src/index.bundle.tracing.logs.metrics.ts @@ -0,0 +1,35 @@ +import { registerSpanErrorInstrumentation } from '@sentry/core'; +import { feedbackIntegrationShim, replayIntegrationShim } from '@sentry-internal/integration-shims'; + +registerSpanErrorInstrumentation(); + +export * from './index.bundle.base'; + +// TODO(v11): Export metrics here once we remove it from the base bundle. +export { logger, consoleLoggingIntegration } from '@sentry/core'; + +export { + getActiveSpan, + getRootSpan, + getSpanDescendants, + setMeasurement, + startInactiveSpan, + startNewTrace, + startSpan, + startSpanManual, + withActiveSpan, +} from '@sentry/core'; + +export { + browserTracingIntegration, + startBrowserTracingNavigationSpan, + startBrowserTracingPageLoadSpan, +} from './tracing/browserTracingIntegration'; +export { reportPageLoaded } from './tracing/reportPageLoaded'; +export { setActiveSpanInBrowser } from './tracing/setActiveSpan'; + +export { + feedbackIntegrationShim as feedbackAsyncIntegration, + feedbackIntegrationShim as feedbackIntegration, + replayIntegrationShim as replayIntegration, +}; diff --git a/packages/browser/test/index.bundle.tracing.logs.metrics.test.ts b/packages/browser/test/index.bundle.tracing.logs.metrics.test.ts new file mode 100644 index 000000000000..19b3701ebf77 --- /dev/null +++ b/packages/browser/test/index.bundle.tracing.logs.metrics.test.ts @@ -0,0 +1,17 @@ +import { logger as coreLogger, metrics as coreMetrics } from '@sentry/core'; +import { feedbackIntegrationShim, replayIntegrationShim } from '@sentry-internal/integration-shims'; +import { describe, expect, it } from 'vitest'; +import { browserTracingIntegration } from '../src'; +import * as TracingLogsMetricsBundle from '../src/index.bundle.tracing.logs.metrics'; + +describe('index.bundle.tracing.logs.metrics', () => { + it('has correct exports', () => { + expect(TracingLogsMetricsBundle.browserTracingIntegration).toBe(browserTracingIntegration); + expect(TracingLogsMetricsBundle.feedbackAsyncIntegration).toBe(feedbackIntegrationShim); + expect(TracingLogsMetricsBundle.feedbackIntegration).toBe(feedbackIntegrationShim); + expect(TracingLogsMetricsBundle.replayIntegration).toBe(replayIntegrationShim); + + expect(TracingLogsMetricsBundle.logger).toBe(coreLogger); + expect(TracingLogsMetricsBundle.metrics).toBe(coreMetrics); + }); +});