From 9a60e597b0992e4faf59c56ad5b2f0f85723d49e Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 12 Feb 2024 13:14:41 -0500 Subject: [PATCH 01/14] feat(v8): Remove @sentry/tracing --- .craft.yml | 7 +- MIGRATION.md | 8 +- README.md | 2 - .../browser-integration-tests/package.json | 1 - .../suites/public-api/startSpan/init.js | 5 +- .../public-api/startTransaction/init.js | 5 +- .../browserTracingIntegrationShim/init.js | 2 +- .../backgroundtab-custom/init.js | 3 +- .../browsertracing/http-timings/init.js | 3 +- .../suites/tracing/browsertracing/init.js | 3 +- .../browsertracing/interactions/init.js | 3 +- .../long-tasks-disabled/init.js | 3 +- .../browsertracing/long-tasks-enabled/init.js | 3 +- .../tracing/browsertracing/meta/init.js | 3 +- .../tracing/browsertracing/pageload/init.js | 3 +- .../browsertracing/pageloadDelayed/init.js | 3 +- .../pageloadWithHeartbeatTimeout/init.js | 3 +- .../customTargetsAndOrigins/init.js | 9 + .../customTracingOrigins/init.js | 9 + .../defaultTargetsNoMatch/init.js | 3 +- .../envelope-header-transaction-name/init.js | 3 +- .../suites/tracing/metrics/init.js | 3 +- .../utils/generatePlugin.ts | 3 +- .../create-react-app/package.json | 1 - .../create-react-app/src/index.tsx | 3 +- .../test-applications/generic-ts3.8/index.ts | 2 - .../generic-ts3.8/package.json | 1 - .../node-express-app/package.json | 1 - .../node-express-app/src/app.ts | 1 - .../node-hapi-app/package.json | 1 - .../package.json | 1 - .../sveltekit-2/package.json | 3 +- .../test-applications/sveltekit/package.json | 3 +- .../e2e-tests/verdaccio-config/config.yaml | 6 - .../node-integration-tests/package.json | 1 - .../common-infix-parameterized/server.ts | 3 +- .../multiple-routers/common-infix/server.ts | 3 +- .../server.ts | 3 +- .../common-prefix-parameterized/server.ts | 3 +- .../server.ts | 3 +- .../server.ts | 3 +- .../multiple-routers/common-prefix/server.ts | 3 +- .../multiple-routers/complex-router/server.ts | 3 +- .../middle-layer-parameterized/server.ts | 3 +- .../sentry-trace/baggage-header-out/server.ts | 4 +- .../server.ts | 4 +- .../baggage-other-vendors/server.ts | 4 +- .../baggage-transaction-name/server.ts | 4 +- .../suites/express/sentry-trace/server.ts | 4 +- .../startTransaction/basic-usage/scenario.ts | 3 - .../startTransaction/basic-usage/test.ts | 2 +- .../with-nested-spans/scenario.ts | 2 - .../httpIntegration/spans/scenario.ts | 2 - .../httpIntegration/spansDisabled/scenario.ts | 2 - .../tracePropagationTargets/scenario.ts | 2 - .../scenario.ts | 2 - .../suites/tracing/apollo-graphql/scenario.ts | 4 +- .../auto-instrument/mongodb/scenario.ts | 2 - .../tracing/auto-instrument/mysql/scenario.ts | 2 - .../tracing/auto-instrument/pg/scenario.ts | 2 - .../suites/tracing/prisma-orm/scenario.ts | 4 +- .../tracePropagationTargets/scenario.ts | 2 - dev-packages/rollup-utils/bundleHelpers.mjs | 2 +- package.json | 1 - packages/browser/rollup.bundle.config.mjs | 6 +- packages/core/test/lib/tracing/errors.test.ts | 7 +- .../test/lib/tracing}/idletransaction.test.ts | 13 +- packages/core/test/lib/tracing/span.test.ts | 312 +++++++- packages/nextjs/test/integration/package.json | 1 - packages/remix/test/integration/package.json | 1 - .../test/browser/backgroundtab.test.ts | 12 +- .../test/browser/browsertracing.test.ts | 14 +- .../test/browser/router.test.ts | 2 +- packages/tracing/.eslintrc.js | 11 - packages/tracing/LICENSE | 14 - packages/tracing/README.md | 163 ----- packages/tracing/jest.config.js | 1 - packages/tracing/package.json | 73 -- packages/tracing/rollup.npm.config.mjs | 8 - packages/tracing/src/index.ts | 255 ------- packages/tracing/test/hub.test.ts | 637 ---------------- packages/tracing/test/index.test.ts | 33 - .../test/integrations/apollo-nestjs.test.ts | 126 ---- .../tracing/test/integrations/apollo.test.ts | 126 ---- .../tracing/test/integrations/graphql.test.ts | 78 -- .../test/integrations/node/mongo.test.ts | 160 ---- .../test/integrations/node/postgres.test.ts | 153 ---- .../test/integrations/node/prisma.test.ts | 85 --- packages/tracing/test/span.test.ts | 691 ------------------ packages/tracing/test/testutils.ts | 100 --- packages/tracing/test/transaction.test.ts | 214 ------ packages/tracing/test/utils.test.ts | 35 - packages/tracing/tsconfig.json | 9 - packages/tracing/tsconfig.test.json | 12 - packages/tracing/tsconfig.types.json | 10 - packages/types/src/span.ts | 6 +- yarn.lock | 36 + 97 files changed, 439 insertions(+), 3160 deletions(-) create mode 100644 dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/customTargetsAndOrigins/init.js create mode 100644 dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/customTracingOrigins/init.js rename packages/{tracing/test => core/test/lib/tracing}/idletransaction.test.ts (98%) delete mode 100644 packages/tracing/.eslintrc.js delete mode 100644 packages/tracing/LICENSE delete mode 100644 packages/tracing/README.md delete mode 100644 packages/tracing/jest.config.js delete mode 100644 packages/tracing/package.json delete mode 100644 packages/tracing/rollup.npm.config.mjs delete mode 100644 packages/tracing/src/index.ts delete mode 100644 packages/tracing/test/hub.test.ts delete mode 100644 packages/tracing/test/index.test.ts delete mode 100644 packages/tracing/test/integrations/apollo-nestjs.test.ts delete mode 100644 packages/tracing/test/integrations/apollo.test.ts delete mode 100644 packages/tracing/test/integrations/graphql.test.ts delete mode 100644 packages/tracing/test/integrations/node/mongo.test.ts delete mode 100644 packages/tracing/test/integrations/node/postgres.test.ts delete mode 100644 packages/tracing/test/integrations/node/prisma.test.ts delete mode 100644 packages/tracing/test/span.test.ts delete mode 100644 packages/tracing/test/testutils.ts delete mode 100644 packages/tracing/test/transaction.test.ts delete mode 100644 packages/tracing/test/utils.test.ts delete mode 100644 packages/tracing/tsconfig.json delete mode 100644 packages/tracing/tsconfig.test.json delete mode 100644 packages/tracing/tsconfig.types.json diff --git a/.craft.yml b/.craft.yml index f795d317b05e..5ffdda2338ae 100644 --- a/.craft.yml +++ b/.craft.yml @@ -131,12 +131,7 @@ targets: id: '@sentry-internal/eslint-config-sdk' includeNames: /^sentry-internal-eslint-config-sdk-\d.*\.tgz$/ - ## 8. Deprecated packages we still release (but no packages depend on them anymore) - - name: npm - id: '@sentry/tracing' - includeNames: /^sentry-tracing-\d.*\.tgz$/ - - ## 9. Experimental packages + ## 8. Experimental packages - name: npm id: '@sentry/node-experimental' includeNames: /^sentry-node-experimental-\d.*\.tgz$/ diff --git a/MIGRATION.md b/MIGRATION.md index c38572523fab..2a9a62d1d1c4 100644 --- a/MIGRATION.md +++ b/MIGRATION.md @@ -51,7 +51,13 @@ to access and mutate the current scope. ## Deletion of `@sentry/hub` package (#10530) -`@sentry/hub` has been removed. All exports from `@sentry.hub` should be available in `@sentry/core`. +`@sentry/hub` has been removed. All exports from `@sentry/tracing` should be available in `@sentry/core` or in +`@sentry/browser` and `@sentry/node`. + +## Deletion of `@sentry/tracing` package + +`@sentry/tracing` has been removed. All exports from `@sentry/tracing` should be available in `@sentry/core` or in +`@sentry/browser` and `@sentry/node`. ## General API Changes diff --git a/README.md b/README.md index 97ec4dadb89a..80790d36c4a2 100644 --- a/README.md +++ b/README.md @@ -95,8 +95,6 @@ Besides the high-level SDKs, this repository contains shared packages, helpers a development. If you're thinking about contributing to or creating a JavaScript-based SDK, have a look at the resources below: -- [`@sentry/tracing`](https://github.com/getsentry/sentry-javascript/tree/master/packages/tracing): Provides - integrations and extensions for Performance Monitoring / Tracing. - [`@sentry/replay`](https://github.com/getsentry/sentry-javascript/tree/master/packages/replay): Provides the integration for Session Replay. - [`@sentry/core`](https://github.com/getsentry/sentry-javascript/tree/master/packages/core): The base for all diff --git a/dev-packages/browser-integration-tests/package.json b/dev-packages/browser-integration-tests/package.json index 7f12a2c7d954..e9a009e5acec 100644 --- a/dev-packages/browser-integration-tests/package.json +++ b/dev-packages/browser-integration-tests/package.json @@ -48,7 +48,6 @@ "@playwright/test": "^1.40.1", "@sentry-internal/rrweb": "2.11.0", "@sentry/browser": "7.100.0", - "@sentry/tracing": "7.100.0", "axios": "1.6.0", "babel-loader": "^8.2.2", "html-webpack-plugin": "^5.5.0", diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js b/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js index b0bf1e869254..d6e849bc7cae 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js @@ -1,7 +1,6 @@ -/* eslint-disable no-unused-vars */ import * as Sentry from '@sentry/browser'; -// biome-ignore lint/nursery/noUnusedImports: Need to import tracing for side effect -import * as _ from '@sentry/tracing'; + +Sentry.addTracingExtensions(); window.Sentry = Sentry; diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js b/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js index e1903e2cc268..1c155f323586 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js +++ b/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js @@ -1,7 +1,6 @@ -/* eslint-disable no-unused-vars */ import * as Sentry from '@sentry/browser'; -// biome-ignore lint/nursery/noUnusedImports: Need to import tracing for side effect -import * as _ from '@sentry/tracing'; + +Sentry.addTracingExtensions(); window.Sentry = Sentry; diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegrationShim/init.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegrationShim/init.js index e8ba5702cff8..d7cfd52aedcc 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegrationShim/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegrationShim/init.js @@ -5,7 +5,7 @@ window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', sampleRate: 1, - integrations: [new Sentry.browserTracingIntegration()], + integrations: [Sentry.browserTracingIntegration()], }); // This should not fail diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/backgroundtab-custom/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/backgroundtab-custom/init.js index a4bddcff1b21..3f5bf2b3765e 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/backgroundtab-custom/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/backgroundtab-custom/init.js @@ -1,10 +1,9 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new Integrations.BrowserTracing({ idleTimeout: 9000 })], + integrations: [new Sentry.BrowserTracing({ idleTimeout: 9000 })], tracesSampleRate: 1, }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/http-timings/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/http-timings/init.js index efe1e2ef9778..ec8b0cb08034 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/http-timings/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/http-timings/init.js @@ -1,12 +1,11 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', integrations: [ - new Integrations.BrowserTracing({ + new Sentry.BrowserTracing({ idleTimeout: 1000, _experiments: { enableHTTPTimings: true, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/init.js index ce4e0c4ad7f7..14e743361fd7 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/init.js @@ -1,10 +1,9 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new Integrations.BrowserTracing()], + integrations: [new Sentry.BrowserTracing()], tracesSampleRate: 1, }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/interactions/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/interactions/init.js index d30222b7f47e..f8f8cf526a6b 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/interactions/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/interactions/init.js @@ -1,12 +1,11 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', integrations: [ - new Integrations.BrowserTracing({ + new Sentry.BrowserTracing({ idleTimeout: 1000, _experiments: { enableInteractions: true, diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-disabled/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-disabled/init.js index c1d5e8a8a7ae..8dba00211a01 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-disabled/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-disabled/init.js @@ -1,10 +1,9 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new Integrations.BrowserTracing({ enableLongTask: false, idleTimeout: 9000 })], + integrations: [new Sentry.BrowserTracing({ enableLongTask: false, idleTimeout: 9000 })], tracesSampleRate: 1, }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-enabled/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-enabled/init.js index 037e2dc88517..155966847b1c 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-enabled/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-enabled/init.js @@ -1,12 +1,11 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', integrations: [ - new Integrations.BrowserTracing({ + new Sentry.BrowserTracing({ idleTimeout: 9000, }), ], diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/meta/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/meta/init.js index 50f4a898e251..e6f49fa89562 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/meta/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/meta/init.js @@ -1,11 +1,10 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new Integrations.BrowserTracing()], + integrations: [new Sentry.BrowserTracing()], tracesSampleRate: 1, environment: 'staging', }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageload/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageload/init.js index 2340df528aa7..a1e77dae58c2 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageload/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageload/init.js @@ -1,11 +1,10 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; window._testBaseTimestamp = performance.timeOrigin / 1000; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new Integrations.BrowserTracing()], + integrations: [new Sentry.BrowserTracing()], tracesSampleRate: 1, }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageloadDelayed/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageloadDelayed/init.js index ff6345dec8f2..6e4774650261 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageloadDelayed/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageloadDelayed/init.js @@ -1,5 +1,4 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; window._testBaseTimestamp = performance.timeOrigin / 1000; @@ -8,7 +7,7 @@ setTimeout(() => { window._testTimeoutTimestamp = (performance.timeOrigin + performance.now()) / 1000; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new Integrations.BrowserTracing()], + integrations: [new Sentry.BrowserTracing()], tracesSampleRate: 1, }); }, 250); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageloadWithHeartbeatTimeout/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageloadWithHeartbeatTimeout/init.js index ce0d16f0f0db..2a4797a74a15 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageloadWithHeartbeatTimeout/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/pageloadWithHeartbeatTimeout/init.js @@ -1,12 +1,11 @@ import * as Sentry from '@sentry/browser'; import { startSpanManual } from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new Integrations.BrowserTracing()], + integrations: [new Sentry.BrowserTracing()], tracesSampleRate: 1, }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/customTargetsAndOrigins/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/customTargetsAndOrigins/init.js new file mode 100644 index 000000000000..d4fd36f8302c --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/customTargetsAndOrigins/init.js @@ -0,0 +1,9 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: [new Sentry.BrowserTracing({ tracePropagationTargets: [], tracingOrigins: ['http://example.com'] })], + tracesSampleRate: 1, +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/customTracingOrigins/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/customTracingOrigins/init.js new file mode 100644 index 000000000000..c43686bbc598 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/customTracingOrigins/init.js @@ -0,0 +1,9 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: [new Sentry.BrowserTracing({ tracingOrigins: ['http://example.com'] })], + tracesSampleRate: 1, +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/defaultTargetsNoMatch/init.js b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/defaultTargetsNoMatch/init.js index ce4e0c4ad7f7..14e743361fd7 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/defaultTargetsNoMatch/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/tracePropagationTargets/defaultTargetsNoMatch/init.js @@ -1,10 +1,9 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new Integrations.BrowserTracing()], + integrations: [new Sentry.BrowserTracing()], tracesSampleRate: 1, }); diff --git a/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/init.js b/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/init.js index e28325fcf78e..4c4220d905a2 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/envelope-header-transaction-name/init.js @@ -1,11 +1,10 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new Integrations.BrowserTracing({ tracingOrigins: [/.*/] })], + integrations: [new Sentry.BrowserTracing({ tracingOrigins: [/.*/] })], environment: 'production', tracesSampleRate: 1, debug: true, diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/init.js b/dev-packages/browser-integration-tests/suites/tracing/metrics/init.js index 037e2dc88517..155966847b1c 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/init.js +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/init.js @@ -1,12 +1,11 @@ import * as Sentry from '@sentry/browser'; -import { Integrations } from '@sentry/tracing'; window.Sentry = Sentry; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', integrations: [ - new Integrations.BrowserTracing({ + new Sentry.BrowserTracing({ idleTimeout: 9000, }), ], diff --git a/dev-packages/browser-integration-tests/utils/generatePlugin.ts b/dev-packages/browser-integration-tests/utils/generatePlugin.ts index fe583e271ca3..0ef9a73a91d2 100644 --- a/dev-packages/browser-integration-tests/utils/generatePlugin.ts +++ b/dev-packages/browser-integration-tests/utils/generatePlugin.ts @@ -168,14 +168,13 @@ class SentryScenarioGenerationPlugin { ? { // To help Webpack resolve Sentry modules in `import` statements in cases where they're provided in bundles rather than in `node_modules` '@sentry/browser': 'Sentry', - '@sentry/tracing': 'Sentry', '@sentry/replay': 'Sentry', '@sentry/integrations': 'Sentry', '@sentry/wasm': 'Sentry', } : {}; - // Checking if the current scenario has imported `@sentry/tracing` or `@sentry/integrations`. + // Checking if the current scenario has imported `@sentry/integrations`. compiler.hooks.normalModuleFactory.tap(this._name, factory => { factory.hooks.parser.for('javascript/auto').tap(this._name, parser => { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access diff --git a/dev-packages/e2e-tests/test-applications/create-react-app/package.json b/dev-packages/e2e-tests/test-applications/create-react-app/package.json index 07c4210736a8..a6f33f5372f4 100644 --- a/dev-packages/e2e-tests/test-applications/create-react-app/package.json +++ b/dev-packages/e2e-tests/test-applications/create-react-app/package.json @@ -4,7 +4,6 @@ "private": true, "dependencies": { "@sentry/react": "latest || *", - "@sentry/tracing": "latest || *", "@testing-library/jest-dom": "5.14.1", "@testing-library/react": "13.0.0", "@testing-library/user-event": "13.2.1", diff --git a/dev-packages/e2e-tests/test-applications/create-react-app/src/index.tsx b/dev-packages/e2e-tests/test-applications/create-react-app/src/index.tsx index f4f58b689b9e..1c10b3e92da6 100644 --- a/dev-packages/e2e-tests/test-applications/create-react-app/src/index.tsx +++ b/dev-packages/e2e-tests/test-applications/create-react-app/src/index.tsx @@ -1,5 +1,4 @@ import * as Sentry from '@sentry/react'; -import { BrowserTracing } from '@sentry/tracing'; import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; @@ -9,7 +8,7 @@ import reportWebVitals from './reportWebVitals'; Sentry.init({ environment: 'qa', // dynamic sampling bias to keep transactions dsn: 'https://public@dsn.ingest.sentry.io/1337', - integrations: [new BrowserTracing()], + integrations: [Sentry.browserTracingIntegration()], // We recommend adjusting this value in production, or using tracesSampler // for finer control diff --git a/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts b/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts index 3ec4677b17bc..34a7ba15fe24 100644 --- a/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts +++ b/dev-packages/e2e-tests/test-applications/generic-ts3.8/index.ts @@ -11,8 +11,6 @@ import * as _SentryOpentelemetry from '@sentry/opentelemetry-node'; // biome-ignore lint/nursery/noUnusedImports: import * as _SentryReplay from '@sentry/replay'; // biome-ignore lint/nursery/noUnusedImports: -import * as _SentryTracing from '@sentry/tracing'; -// biome-ignore lint/nursery/noUnusedImports: import * as _SentryTypes from '@sentry/types'; // biome-ignore lint/nursery/noUnusedImports: import * as _SentryUtils from '@sentry/utils'; diff --git a/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json b/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json index 919d2fb99e84..82be8f36bd5f 100644 --- a/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json +++ b/dev-packages/e2e-tests/test-applications/generic-ts3.8/package.json @@ -19,7 +19,6 @@ "@sentry/node": "latest || *", "@sentry/opentelemetry-node": "latest || *", "@sentry/replay": "latest || *", - "@sentry/tracing": "latest || *", "@sentry/types": "latest || *", "@sentry/utils": "latest || *", "@sentry/wasm": "latest || *" diff --git a/dev-packages/e2e-tests/test-applications/node-express-app/package.json b/dev-packages/e2e-tests/test-applications/node-express-app/package.json index 2d44043b94e7..2c721361b212 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-app/package.json +++ b/dev-packages/e2e-tests/test-applications/node-express-app/package.json @@ -13,7 +13,6 @@ "dependencies": { "@sentry/integrations": "latest || *", "@sentry/node": "latest || *", - "@sentry/tracing": "latest || *", "@sentry/types": "latest || *", "express": "4.18.2", "@types/express": "4.17.17", diff --git a/dev-packages/e2e-tests/test-applications/node-express-app/src/app.ts b/dev-packages/e2e-tests/test-applications/node-express-app/src/app.ts index 9006936c4e60..452f29caeaf5 100644 --- a/dev-packages/e2e-tests/test-applications/node-express-app/src/app.ts +++ b/dev-packages/e2e-tests/test-applications/node-express-app/src/app.ts @@ -1,6 +1,5 @@ import { httpClientIntegration } from '@sentry/integrations'; import * as Sentry from '@sentry/node'; -import '@sentry/tracing'; import express from 'express'; declare global { diff --git a/dev-packages/e2e-tests/test-applications/node-hapi-app/package.json b/dev-packages/e2e-tests/test-applications/node-hapi-app/package.json index 1f667abc8987..1aba49ac4d3e 100644 --- a/dev-packages/e2e-tests/test-applications/node-hapi-app/package.json +++ b/dev-packages/e2e-tests/test-applications/node-hapi-app/package.json @@ -14,7 +14,6 @@ "@hapi/hapi": "21.3.2", "@sentry/integrations": "latest || *", "@sentry/node": "latest || *", - "@sentry/tracing": "latest || *", "@sentry/types": "latest || *", "@types/node": "18.15.1", "typescript": "4.9.5" diff --git a/dev-packages/e2e-tests/test-applications/standard-frontend-react-tracing-import/package.json b/dev-packages/e2e-tests/test-applications/standard-frontend-react-tracing-import/package.json index be15956c2ca6..cde5ad8225ee 100644 --- a/dev-packages/e2e-tests/test-applications/standard-frontend-react-tracing-import/package.json +++ b/dev-packages/e2e-tests/test-applications/standard-frontend-react-tracing-import/package.json @@ -4,7 +4,6 @@ "private": true, "dependencies": { "@sentry/react": "latest || *", - "@sentry/tracing": "latest || *", "@testing-library/jest-dom": "5.14.1", "@testing-library/react": "13.0.0", "@testing-library/user-event": "13.2.1", diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json b/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json index a323c3c415be..62d195ae98c7 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json @@ -33,8 +33,7 @@ }, "pnpm": { "overrides": { - "@sentry/node": "latest || *", - "@sentry/tracing": "latest || *" + "@sentry/node": "latest || *" } }, "type": "module" diff --git a/dev-packages/e2e-tests/test-applications/sveltekit/package.json b/dev-packages/e2e-tests/test-applications/sveltekit/package.json index ea21787939c3..a449961b97ea 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit/package.json +++ b/dev-packages/e2e-tests/test-applications/sveltekit/package.json @@ -32,8 +32,7 @@ }, "pnpm": { "overrides": { - "@sentry/node": "latest || *", - "@sentry/tracing": "latest || *" + "@sentry/node": "latest || *" } }, "type": "module" diff --git a/dev-packages/e2e-tests/verdaccio-config/config.yaml b/dev-packages/e2e-tests/verdaccio-config/config.yaml index 143596b74849..2ff38d3f63d1 100644 --- a/dev-packages/e2e-tests/verdaccio-config/config.yaml +++ b/dev-packages/e2e-tests/verdaccio-config/config.yaml @@ -164,12 +164,6 @@ packages: unpublish: $all # proxy: npmjs # Don't proxy for E2E tests! - '@sentry/tracing': - access: $all - publish: $all - unpublish: $all - # proxy: npmjs # Don't proxy for E2E tests! - '@sentry/types': access: $all publish: $all diff --git a/dev-packages/node-integration-tests/package.json b/dev-packages/node-integration-tests/package.json index d9679c29dc27..d8e3fd59e66b 100644 --- a/dev-packages/node-integration-tests/package.json +++ b/dev-packages/node-integration-tests/package.json @@ -30,7 +30,6 @@ "@hapi/hapi": "^20.3.0", "@prisma/client": "3.15.2", "@sentry/node": "7.100.0", - "@sentry/tracing": "7.100.0", "@sentry/types": "7.100.0", "@types/mongodb": "^3.6.20", "@types/mysql": "^2.15.21", diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-infix-parameterized/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-infix-parameterized/server.ts index fe2d32009ded..ecccf1e3ecb2 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-infix-parameterized/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-infix-parameterized/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -10,7 +9,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-infix/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-infix/server.ts index afc5aeb4b66e..00d690adf28e 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-infix/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-infix/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -10,7 +9,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-parameterized-reverse/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-parameterized-reverse/server.ts index 38400a6455e2..cc6cfb49e5f5 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-parameterized-reverse/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-parameterized-reverse/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -10,7 +9,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-parameterized/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-parameterized/server.ts index a787aa288fcb..f2ac93ac4a1f 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-parameterized/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-parameterized/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -10,7 +9,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-same-length-parameterized copy/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-same-length-parameterized copy/server.ts index 0b51b70f80f7..7deb794935e2 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-same-length-parameterized copy/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-same-length-parameterized copy/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -10,7 +9,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-same-length-parameterized/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-same-length-parameterized/server.ts index d32c6dadfe1f..aa5200791802 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-same-length-parameterized/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix-same-length-parameterized/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -10,7 +9,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix/server.ts index 270c2fec5e49..ae91e7743ede 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/common-prefix/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -10,7 +9,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/complex-router/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/complex-router/server.ts index 8df1b9c3d988..08b3a8f024cc 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/complex-router/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/complex-router/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import express from 'express'; const app = express(); @@ -9,7 +8,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/multiple-routers/middle-layer-parameterized/server.ts b/dev-packages/node-integration-tests/suites/express/multiple-routers/middle-layer-parameterized/server.ts index 7b92c2b6508d..4f1dd24cdcea 100644 --- a/dev-packages/node-integration-tests/suites/express/multiple-routers/middle-layer-parameterized/server.ts +++ b/dev-packages/node-integration-tests/suites/express/multiple-routers/middle-layer-parameterized/server.ts @@ -1,6 +1,5 @@ import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import express from 'express'; const app = express(); @@ -9,7 +8,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/server.ts b/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/server.ts index 8669c5bb21b8..bd4753646767 100644 --- a/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/server.ts +++ b/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-header-out/server.ts @@ -1,7 +1,6 @@ import http from 'http'; import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -14,8 +13,7 @@ Sentry.init({ release: '1.0', environment: 'prod', tracePropagationTargets: [/^(?!.*express).*$/], - // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/server.ts b/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/server.ts index 2c226da111a1..e14566556177 100644 --- a/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/server.ts +++ b/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors-with-sentry-entries/server.ts @@ -1,7 +1,6 @@ import * as http from 'http'; import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -15,8 +14,7 @@ Sentry.init({ environment: 'prod', // disable requests to /express tracePropagationTargets: [/^(?!.*express).*$/], - // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors/server.ts b/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors/server.ts index 5858f452c71d..e368afda7300 100644 --- a/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors/server.ts +++ b/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-other-vendors/server.ts @@ -1,7 +1,6 @@ import http from 'http'; import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -15,8 +14,7 @@ Sentry.init({ environment: 'prod', // disable requests to /express tracePropagationTargets: [/^(?!.*express).*$/], - // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/server.ts b/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/server.ts index 92d2f8a0195a..8b05749f40e2 100644 --- a/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/server.ts +++ b/dev-packages/node-integration-tests/suites/express/sentry-trace/baggage-transaction-name/server.ts @@ -2,7 +2,6 @@ import http from 'http'; import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -16,8 +15,7 @@ Sentry.init({ environment: 'prod', // disable requests to /express tracePropagationTargets: [/^(?!.*express).*$/], - // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, // TODO: We're rethinking the mechanism for including Pii data in DSC, hence commenting out sendDefaultPii for now // sendDefaultPii: true, diff --git a/dev-packages/node-integration-tests/suites/express/sentry-trace/server.ts b/dev-packages/node-integration-tests/suites/express/sentry-trace/server.ts index 77de1a188afa..206bfda82f9c 100644 --- a/dev-packages/node-integration-tests/suites/express/sentry-trace/server.ts +++ b/dev-packages/node-integration-tests/suites/express/sentry-trace/server.ts @@ -1,7 +1,6 @@ import http from 'http'; import { loggingTransport, startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import cors from 'cors'; import express from 'express'; @@ -14,8 +13,7 @@ Sentry.init({ release: '1.0', environment: 'prod', tracePropagationTargets: [/^(?!.*express).*$/], - // eslint-disable-next-line deprecation/deprecation - integrations: [new Sentry.Integrations.Http({ tracing: true }), new Tracing.Integrations.Express({ app })], + integrations: [new Sentry.Integrations.Http({ tracing: true }), new Sentry.Integrations.Express({ app })], tracesSampleRate: 1.0, transport: loggingTransport, }); diff --git a/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts index 70596da19716..436bbfc9ba37 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts @@ -1,6 +1,3 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import '@sentry/tracing'; - import * as Sentry from '@sentry/node'; Sentry.init({ diff --git a/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/test.ts b/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/test.ts index 4628782f025c..f732ee29062d 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/test.ts @@ -1,6 +1,6 @@ import { TestEnv, assertSentryTransaction } from '../../../../utils'; -test('should send a manually started transaction when @sentry/tracing is imported using unnamed import.', async () => { +test('should send a manually started transaction.', async () => { const env = await TestEnv.init(__dirname); const envelope = await env.getEnvelopeRequest({ envelopeType: 'transaction' }); diff --git a/dev-packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts index f82fe81d969a..6e508de02fb4 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts @@ -1,5 +1,3 @@ -import '@sentry/tracing'; - import * as Sentry from '@sentry/node'; Sentry.init({ diff --git a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spans/scenario.ts b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spans/scenario.ts index 9b1abf466db1..7b1dddab2f68 100644 --- a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spans/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spans/scenario.ts @@ -1,5 +1,3 @@ -import '@sentry/tracing'; - import * as http from 'http'; import * as Sentry from '@sentry/node'; diff --git a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spansDisabled/scenario.ts b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spansDisabled/scenario.ts index 61711e974f7d..29e6bfdbc5a3 100644 --- a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spansDisabled/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spansDisabled/scenario.ts @@ -1,5 +1,3 @@ -import '@sentry/tracing'; - import * as http from 'http'; import * as Sentry from '@sentry/node'; diff --git a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargets/scenario.ts b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargets/scenario.ts index 7794b20911f9..fc2de664cbf3 100644 --- a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargets/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargets/scenario.ts @@ -1,6 +1,4 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars -import '@sentry/tracing'; - import * as http from 'http'; import * as Sentry from '@sentry/node'; diff --git a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargetsDisabled/scenario.ts b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargetsDisabled/scenario.ts index c04616f7db89..eade81b4febc 100644 --- a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargetsDisabled/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargetsDisabled/scenario.ts @@ -1,6 +1,4 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars -import '@sentry/tracing'; - import * as http from 'http'; import * as Sentry from '@sentry/node'; diff --git a/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts index 6a699fa07af7..1584274bce7d 100644 --- a/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts @@ -1,13 +1,11 @@ import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; import { ApolloServer, gql } from 'apollo-server'; Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', tracesSampleRate: 1.0, - // eslint-disable-next-line deprecation/deprecation - integrations: [new Tracing.Integrations.GraphQL(), new Tracing.Integrations.Apollo()], + integrations: [new Sentry.Integrations.GraphQL(), new Sentry.Integrations.Apollo()], }); const typeDefs = gql` diff --git a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts index 51359ac726da..549f36504761 100644 --- a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts @@ -1,5 +1,3 @@ -import '@sentry/tracing'; - import * as Sentry from '@sentry/node'; import { MongoClient } from 'mongodb'; diff --git a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts index ce53d776fe54..ae69aad2f2c0 100644 --- a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts @@ -1,5 +1,3 @@ -import '@sentry/tracing'; - import * as Sentry from '@sentry/node'; import mysql from 'mysql'; diff --git a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts index f9bfa0de0294..948564a952d0 100644 --- a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts @@ -1,5 +1,3 @@ -import '@sentry/tracing'; - import * as Sentry from '@sentry/node'; import pg from 'pg'; diff --git a/dev-packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts index b5003141caec..6191dbf31d75 100644 --- a/dev-packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts @@ -2,7 +2,6 @@ import { randomBytes } from 'crypto'; /* eslint-disable @typescript-eslint/no-unsafe-member-access */ import { PrismaClient } from '@prisma/client'; import * as Sentry from '@sentry/node'; -import * as Tracing from '@sentry/tracing'; const client = new PrismaClient(); @@ -10,8 +9,7 @@ Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', release: '1.0', tracesSampleRate: 1.0, - // eslint-disable-next-line deprecation/deprecation - integrations: [new Tracing.Integrations.Prisma({ client })], + integrations: [new Sentry.Integrations.Prisma({ client })], }); async function run(): Promise { diff --git a/dev-packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts index 8ecb7ed3cc61..afa891bb8701 100644 --- a/dev-packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts +++ b/dev-packages/node-integration-tests/suites/tracing/tracePropagationTargets/scenario.ts @@ -1,6 +1,4 @@ // eslint-disable-next-line @typescript-eslint/no-unused-vars -import '@sentry/tracing'; - import * as http from 'http'; import * as Sentry from '@sentry/node'; diff --git a/dev-packages/rollup-utils/bundleHelpers.mjs b/dev-packages/rollup-utils/bundleHelpers.mjs index 66bded3b62de..2b77db6c7a9e 100644 --- a/dev-packages/rollup-utils/bundleHelpers.mjs +++ b/dev-packages/rollup-utils/bundleHelpers.mjs @@ -45,7 +45,7 @@ export function makeBaseBundleConfig(options) { // at all, and without `transformMixedEsModules`, they're only included if they're imported, not if they're required.) const commonJSPlugin = makeCommonJSPlugin({ transformMixedEsModules: true }); - // used by `@sentry/browser`, `@sentry/tracing`, and `@sentry/vue` (bundles which are a full SDK in and of themselves) + // used by `@sentry/browser` const standAloneBundleConfig = { output: { format: 'iife', diff --git a/package.json b/package.json index 74fbfe2a650f..f1cbdfd8c726 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,6 @@ "packages/serverless", "packages/svelte", "packages/sveltekit", - "packages/tracing", "packages/tracing-internal", "packages/types", "packages/typescript", diff --git a/packages/browser/rollup.bundle.config.mjs b/packages/browser/rollup.bundle.config.mjs index c64a88931a33..66b1c5bb5992 100644 --- a/packages/browser/rollup.bundle.config.mjs +++ b/packages/browser/rollup.bundle.config.mjs @@ -21,7 +21,7 @@ targets.forEach(jsVersion => { bundleType: 'standalone', entrypoints: ['src/index.bundle.tracing.ts'], jsVersion, - licenseTitle: '@sentry/browser & @sentry/tracing', + licenseTitle: '@sentry/browser (Performance Monitoring)', outputFileBase: () => `bundles/bundle.tracing${jsVersion === 'es5' ? '.es5' : ''}`, }); @@ -50,7 +50,7 @@ if (targets.includes('es6')) { bundleType: 'standalone', entrypoints: ['src/index.bundle.tracing.replay.ts'], jsVersion: 'es6', - licenseTitle: '@sentry/browser & @sentry/tracing & @sentry/replay', + licenseTitle: '@sentry/browser (Performance Monitoring and Replay)', outputFileBase: () => 'bundles/bundle.tracing.replay', }); @@ -58,7 +58,7 @@ if (targets.includes('es6')) { bundleType: 'standalone', entrypoints: ['src/index.bundle.tracing.replay.feedback.ts'], jsVersion: 'es6', - licenseTitle: '@sentry/browser & @sentry/tracing & @sentry/replay & @sentry/feedback', + licenseTitle: '@sentry/browser (Performance Monitoring, Replay, and Feedback)', outputFileBase: () => 'bundles/bundle.tracing.replay.feedback', }); diff --git a/packages/core/test/lib/tracing/errors.test.ts b/packages/core/test/lib/tracing/errors.test.ts index 35a80f60265a..3e27fa03daaf 100644 --- a/packages/core/test/lib/tracing/errors.test.ts +++ b/packages/core/test/lib/tracing/errors.test.ts @@ -1,9 +1,8 @@ -import { BrowserClient } from '@sentry/browser'; import { Hub, addTracingExtensions, makeMain, spanToJSON, startInactiveSpan, startSpan } from '@sentry/core'; import type { HandlerDataError, HandlerDataUnhandledRejection } from '@sentry/types'; -import { getDefaultBrowserClientOptions } from '../../../../tracing/test/testutils'; import { registerErrorInstrumentation } from '../../../src/tracing/errors'; +import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; const mockAddGlobalErrorInstrumentationHandler = jest.fn(); const mockAddGlobalUnhandledRejectionInstrumentationHandler = jest.fn(); @@ -33,9 +32,9 @@ describe('registerErrorHandlers()', () => { beforeEach(() => { mockAddGlobalErrorInstrumentationHandler.mockClear(); mockAddGlobalUnhandledRejectionInstrumentationHandler.mockClear(); - const options = getDefaultBrowserClientOptions({ enableTracing: true }); + const options = getDefaultTestClientOptions({ enableTracing: true }); // eslint-disable-next-line deprecation/deprecation - const hub = new Hub(new BrowserClient(options)); + const hub = new Hub(new TestClient(options)); // eslint-disable-next-line deprecation/deprecation makeMain(hub); }); diff --git a/packages/tracing/test/idletransaction.test.ts b/packages/core/test/lib/tracing/idletransaction.test.ts similarity index 98% rename from packages/tracing/test/idletransaction.test.ts rename to packages/core/test/lib/tracing/idletransaction.test.ts index bc0f7efac86a..b12cb650929b 100644 --- a/packages/tracing/test/idletransaction.test.ts +++ b/packages/core/test/lib/tracing/idletransaction.test.ts @@ -1,5 +1,3 @@ -/* eslint-disable deprecation/deprecation */ -import { BrowserClient } from '@sentry/browser'; import { TRACING_DEFAULTS, Transaction, @@ -9,16 +7,17 @@ import { startSpan, startSpanManual, } from '@sentry/core'; +/* eslint-disable deprecation/deprecation */ +import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; -import { Hub, IdleTransaction, Span, getClient, makeMain } from '../../core/src'; -import { IdleTransactionSpanRecorder } from '../../core/src/tracing/idletransaction'; -import { getDefaultBrowserClientOptions } from './testutils'; +import { Hub, IdleTransaction, Span, getClient, makeMain } from '../../../src'; +import { IdleTransactionSpanRecorder } from '../../../src/tracing/idletransaction'; const dsn = 'https://123@sentry.io/42'; let hub: Hub; beforeEach(() => { - const options = getDefaultBrowserClientOptions({ dsn, tracesSampleRate: 1 }); - hub = new Hub(new BrowserClient(options)); + const options = getDefaultTestClientOptions({ dsn, tracesSampleRate: 1 }); + hub = new Hub(new TestClient(options)); makeMain(hub); }); diff --git a/packages/core/test/lib/tracing/span.test.ts b/packages/core/test/lib/tracing/span.test.ts index b3c08987d4b2..688331561237 100644 --- a/packages/core/test/lib/tracing/span.test.ts +++ b/packages/core/test/lib/tracing/span.test.ts @@ -1,4 +1,4 @@ -import { timestampInSeconds } from '@sentry/utils'; +import { TRACEPARENT_REGEXP, timestampInSeconds } from '@sentry/utils'; import { Span } from '../../../src'; import { TRACE_FLAG_NONE, TRACE_FLAG_SAMPLED, spanToJSON } from '../../../src/utils/spanUtils'; @@ -57,6 +57,316 @@ describe('span', () => { expect(span.description).toEqual('new name'); }); }); + + describe('new Span', () => { + test('simple', () => { + const span = new Span({ sampled: true }); + const span2 = span.startChild(); + expect((span2 as any).parentSpanId).toBe((span as any).spanId); + expect((span2 as any).traceId).toBe((span as any).traceId); + expect((span2 as any).sampled).toBe((span as any).sampled); + }); + + test('sets instrumenter to `sentry` if not specified in constructor', () => { + const span = new Span({}); + + expect(span.instrumenter).toBe('sentry'); + }); + + test('allows to set instrumenter in constructor', () => { + const span = new Span({ instrumenter: 'otel' }); + + expect(span.instrumenter).toBe('otel'); + }); + }); + + describe('setters', () => { + test('setTag', () => { + const span = new Span({}); + expect(span.tags.foo).toBeUndefined(); + span.setTag('foo', 'bar'); + expect(span.tags.foo).toBe('bar'); + span.setTag('foo', 'baz'); + expect(span.tags.foo).toBe('baz'); + }); + + test('setData', () => { + const span = new Span({}); + expect(span.data.foo).toBeUndefined(); + span.setData('foo', null); + expect(span.data.foo).toBe(null); + span.setData('foo', 2); + expect(span.data.foo).toBe(2); + span.setData('foo', true); + expect(span.data.foo).toBe(true); + }); + + test('setName', () => { + const span = new Span({}); + expect(span.description).toBeUndefined(); + span.updateName('foo'); + expect(span.description).toBe('foo'); + }); + }); + + describe('status', () => { + test('setStatus', () => { + const span = new Span({}); + span.setStatus('permission_denied'); + expect((span.getTraceContext() as any).status).toBe('permission_denied'); + }); + + // TODO (v8): Remove + test('setHttpStatus', () => { + const span = new Span({}); + span.setHttpStatus(404); + expect((span.getTraceContext() as any).status).toBe('not_found'); + expect(span.tags['http.status_code']).toBe('404'); + expect(span.data['http.response.status_code']).toBe(404); + }); + + // TODO (v8): Remove + test('isSuccess', () => { + const span = new Span({}); + expect(span.isSuccess()).toBe(false); + expect(spanToJSON(span).status).not.toBe('ok'); + span.setHttpStatus(200); + expect(span.isSuccess()).toBe(true); + expect(spanToJSON(span).status).toBe('ok'); + span.setStatus('permission_denied'); + expect(span.isSuccess()).toBe(false); + expect(spanToJSON(span).status).not.toBe('ok'); + span.setHttpStatus(0); + expect(span.isSuccess()).toBe(false); + expect(spanToJSON(span).status).not.toBe('ok'); + span.setHttpStatus(-1); + expect(span.isSuccess()).toBe(false); + expect(spanToJSON(span).status).not.toBe('ok'); + span.setHttpStatus(99); + expect(span.isSuccess()).toBe(false); + expect(spanToJSON(span).status).not.toBe('ok'); + span.setHttpStatus(100); + expect(span.isSuccess()).toBe(true); + expect(spanToJSON(span).status).toBe('ok'); + }); + }); + + describe('toTraceparent', () => { + test('simple', () => { + expect(new Span().toTraceparent()).toMatch(TRACEPARENT_REGEXP); + }); + test('with sample', () => { + expect(new Span({ sampled: true }).toTraceparent()).toMatch(TRACEPARENT_REGEXP); + }); + }); + + describe('toJSON', () => { + test('simple', () => { + const span = JSON.parse( + JSON.stringify(new Span({ traceId: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', spanId: 'bbbbbbbbbbbbbbbb' })), + ); + expect(span).toHaveProperty('span_id', 'bbbbbbbbbbbbbbbb'); + expect(span).toHaveProperty('trace_id', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); + }); + + test('with parent', () => { + const spanA = new Span({ traceId: 'a', spanId: 'b' }) as any; + const spanB = new Span({ traceId: 'c', spanId: 'd', sampled: false, parentSpanId: spanA.spanId }); + const serialized = JSON.parse(JSON.stringify(spanB)); + expect(serialized).toHaveProperty('parent_span_id', 'b'); + expect(serialized).toHaveProperty('span_id', 'd'); + expect(serialized).toHaveProperty('trace_id', 'c'); + }); + + test('should drop all `undefined` values', () => { + const spanA = new Span({ traceId: 'a', spanId: 'b' }) as any; + const spanB = new Span({ + parentSpanId: spanA.spanId, + spanId: 'd', + traceId: 'c', + }); + const serialized = spanB.toJSON(); + expect(serialized).toStrictEqual({ + start_timestamp: expect.any(Number), + parent_span_id: 'b', + span_id: 'd', + trace_id: 'c', + origin: 'manual', + data: { + 'sentry.origin': 'manual', + }, + }); + }); + }); + + describe('finish', () => { + test('simple', () => { + const span = new Span({}); + expect(spanToJSON(span).timestamp).toBeUndefined(); + span.end(); + expect(spanToJSON(span).timestamp).toBeGreaterThan(1); + }); + }); + + describe('end', () => { + test('simple', () => { + const span = new Span({}); + expect(spanToJSON(span).timestamp).toBeUndefined(); + span.end(); + expect(spanToJSON(span).timestamp).toBeGreaterThan(1); + }); + + test('with endTime in seconds', () => { + const span = new Span({}); + expect(spanToJSON(span).timestamp).toBeUndefined(); + const endTime = Date.now() / 1000; + span.end(endTime); + expect(spanToJSON(span).timestamp).toBe(endTime); + }); + + test('with endTime in milliseconds', () => { + const span = new Span({}); + expect(spanToJSON(span).timestamp).toBeUndefined(); + const endTime = Date.now(); + span.end(endTime); + expect(spanToJSON(span).timestamp).toBe(endTime / 1000); + }); + }); + + describe('getTraceContext', () => { + test('should have status attribute undefined if no status tag is available', () => { + const span = new Span({}); + const context = span.getTraceContext(); + expect((context as any).status).toBeUndefined(); + }); + + test('should have success status extracted from tags', () => { + const span = new Span({}); + span.setStatus('ok'); + const context = span.getTraceContext(); + expect((context as any).status).toBe('ok'); + }); + + test('should have failure status extracted from tags', () => { + const span = new Span({}); + span.setStatus('resource_exhausted'); + const context = span.getTraceContext(); + expect((context as any).status).toBe('resource_exhausted'); + }); + + test('should drop all `undefined` values', () => { + const spanB = new Span({ spanId: 'd', traceId: 'c' }); + const context = spanB.getTraceContext(); + expect(context).toStrictEqual({ + span_id: 'd', + trace_id: 'c', + data: { + 'sentry.origin': 'manual', + }, + origin: 'manual', + }); + }); + }); + + describe('toContext and updateWithContext', () => { + test('toContext should return correct context', () => { + const originalContext = { + traceId: 'a', + spanId: 'b', + sampled: false, + description: 'test', + op: 'op', + }; + const span = new Span(originalContext); + + const newContext = span.toContext(); + + expect(newContext).toStrictEqual({ + ...originalContext, + spanId: expect.any(String), + startTimestamp: expect.any(Number), + tags: {}, + traceId: expect.any(String), + data: { + 'sentry.op': 'op', + 'sentry.origin': 'manual', + }, + }); + }); + + test('updateWithContext should completely change span properties', () => { + const originalContext = { + traceId: 'a', + spanId: 'b', + sampled: false, + description: 'test', + op: 'op', + tags: { + tag0: 'hello', + }, + }; + const span = new Span(originalContext); + + span.updateWithContext({ + traceId: 'c', + spanId: 'd', + sampled: true, + }); + + expect(span.spanContext().traceId).toBe('c'); + expect(span.spanContext().spanId).toBe('d'); + expect(span.sampled).toBe(true); + expect(span.description).toBe(undefined); + expect(span.op).toBe(undefined); + expect(span.tags).toStrictEqual({}); + }); + + test('using toContext and updateWithContext together should update only changed properties', () => { + const originalContext = { + traceId: 'a', + spanId: 'b', + sampled: false, + description: 'test', + op: 'op', + tags: { tag0: 'hello' }, + data: { data0: 'foo' }, + }; + const span = new Span(originalContext); + + const newContext = { + ...span.toContext(), + description: 'new', + endTimestamp: 1, + op: 'new-op', + sampled: true, + tags: { + tag1: 'bye', + }, + data: { + ...span.toContext().data, + }, + }; + + if (newContext.data) newContext.data.data1 = 'bar'; + + span.updateWithContext(newContext); + + expect(span.spanContext().traceId).toBe('a'); + expect(span.spanContext().spanId).toBe('b'); + expect(span.description).toBe('new'); + expect(spanToJSON(span).timestamp).toBe(1); + expect(span.op).toBe('new-op'); + expect(span.sampled).toBe(true); + expect(span.tags).toStrictEqual({ tag1: 'bye' }); + expect(span.data).toStrictEqual({ + data0: 'foo', + data1: 'bar', + 'sentry.op': 'op', + 'sentry.origin': 'manual', + }); + }); + }); + /* eslint-enable deprecation/deprecation */ describe('setAttribute', () => { diff --git a/packages/nextjs/test/integration/package.json b/packages/nextjs/test/integration/package.json index 14ac5a38aa6b..48713ac0408b 100644 --- a/packages/nextjs/test/integration/package.json +++ b/packages/nextjs/test/integration/package.json @@ -32,7 +32,6 @@ "@sentry/react": "file:../../../react", "@sentry/replay": "file:../../../replay", "@sentry-internal/replay-canvas": "file:../../../replay-canvas", - "@sentry/tracing": "file:../../../tracing", "@sentry-internal/tracing": "file:../../../tracing-internal", "@sentry-internal/feedback": "file:../../../feedback", "@sentry/types": "file:../../../types", diff --git a/packages/remix/test/integration/package.json b/packages/remix/test/integration/package.json index 03068150e6f8..302c5f079d91 100644 --- a/packages/remix/test/integration/package.json +++ b/packages/remix/test/integration/package.json @@ -30,7 +30,6 @@ "@sentry/react": "file:../../../react", "@sentry/replay": "file:../../../replay", "@sentry-internal/replay-canvas": "file:../../../replay-canvas", - "@sentry/tracing": "file:../../../tracing", "@sentry-internal/tracing": "file:../../../tracing-internal", "@sentry-internal/feedback": "file:../../../feedback", "@sentry/types": "file:../../../types", diff --git a/packages/tracing-internal/test/browser/backgroundtab.test.ts b/packages/tracing-internal/test/browser/backgroundtab.test.ts index aa5889c89958..f5c14b7f40e1 100644 --- a/packages/tracing-internal/test/browser/backgroundtab.test.ts +++ b/packages/tracing-internal/test/browser/backgroundtab.test.ts @@ -1,10 +1,8 @@ -import { Hub, makeMain, spanToJSON, startSpan } from '@sentry/core'; +import { Hub, addTracingExtensions, makeMain, spanToJSON, startSpan } from '@sentry/core'; import { JSDOM } from 'jsdom'; -import { addExtensionMethods } from '../../../tracing/src'; -import { getDefaultBrowserClientOptions } from '../../../tracing/test/testutils'; import { registerBackgroundTabDetection } from '../../src/browser/backgroundtab'; -import { TestClient } from '../utils/TestClient'; +import { TestClient, getDefaultClientOptions } from '../utils/TestClient'; describe('registerBackgroundTabDetection', () => { let events: Record = {}; @@ -14,15 +12,13 @@ describe('registerBackgroundTabDetection', () => { // @ts-expect-error need to override global document global.document = dom.window.document; - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); + const options = getDefaultClientOptions({ tracesSampleRate: 1 }); // eslint-disable-next-line deprecation/deprecation hub = new Hub(new TestClient(options)); // eslint-disable-next-line deprecation/deprecation makeMain(hub); - // If we do not add extension methods, invoking hub.startTransaction returns undefined - // eslint-disable-next-line deprecation/deprecation - addExtensionMethods(); + addTracingExtensions(); // @ts-expect-error need to override global document global.document.addEventListener = jest.fn((event, callback) => { diff --git a/packages/tracing-internal/test/browser/browsertracing.test.ts b/packages/tracing-internal/test/browser/browsertracing.test.ts index 9d4105dc415d..18bb70baf64d 100644 --- a/packages/tracing-internal/test/browser/browsertracing.test.ts +++ b/packages/tracing-internal/test/browser/browsertracing.test.ts @@ -1,19 +1,17 @@ /* eslint-disable deprecation/deprecation */ -import { Hub, TRACING_DEFAULTS, makeMain, setCurrentClient, spanToJSON } from '@sentry/core'; +import type { IdleTransaction } from '@sentry/core'; +import { Hub, TRACING_DEFAULTS, getActiveTransaction, makeMain, setCurrentClient, spanToJSON } from '@sentry/core'; import * as hubExtensions from '@sentry/core'; import type { BaseTransportOptions, ClientOptions, DsnComponents, HandlerDataHistory } from '@sentry/types'; import { JSDOM } from 'jsdom'; import { timestampInSeconds } from '@sentry/utils'; -import type { IdleTransaction } from '../../../tracing/src'; -import { getActiveTransaction } from '../../../tracing/src'; -import { getDefaultBrowserClientOptions } from '../../../tracing/test/testutils'; import type { BrowserTracingOptions } from '../../src/browser/browsertracing'; import { BrowserTracing, getMetaContent } from '../../src/browser/browsertracing'; import { defaultRequestInstrumentationOptions } from '../../src/browser/request'; import { instrumentRoutingWithDefaults } from '../../src/browser/router'; import { WINDOW } from '../../src/browser/types'; -import { TestClient } from '../utils/TestClient'; +import { TestClient, getDefaultClientOptions } from '../utils/TestClient'; let mockChangeHistory: (data: HandlerDataHistory) => void = () => {}; @@ -59,7 +57,7 @@ describe('BrowserTracing', () => { let hub: Hub; beforeEach(() => { jest.useFakeTimers(); - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); + const options = getDefaultClientOptions({ tracesSampleRate: 1 }); hub = new Hub(new TestClient(options)); makeMain(hub); document.head.innerHTML = ''; @@ -540,7 +538,7 @@ describe('BrowserTracing', () => { WINDOW.location = dogParkLocation as any; const tracesSampler = jest.fn(); - const options = getDefaultBrowserClientOptions({ tracesSampler }); + const options = getDefaultClientOptions({ tracesSampler }); const client = new TestClient(options); setCurrentClient(client); client.init(); @@ -559,7 +557,7 @@ describe('BrowserTracing', () => { WINDOW.location = dogParkLocation as any; const tracesSampler = jest.fn(); - const options = getDefaultBrowserClientOptions({ tracesSampler }); + const options = getDefaultClientOptions({ tracesSampler }); const client = new TestClient(options); setCurrentClient(client); client.init(); diff --git a/packages/tracing-internal/test/browser/router.test.ts b/packages/tracing-internal/test/browser/router.test.ts index a27926ad9803..948885ddc0ab 100644 --- a/packages/tracing-internal/test/browser/router.test.ts +++ b/packages/tracing-internal/test/browser/router.test.ts @@ -1,7 +1,7 @@ import type { HandlerDataHistory } from '@sentry/types'; import { JSDOM } from 'jsdom'; +import { conditionalTest } from '../../../node/test/utils'; -import { conditionalTest } from '../../../tracing/test/testutils'; import { instrumentRoutingWithDefaults } from '../../src/browser/router'; let mockChangeHistory: undefined | ((data: HandlerDataHistory) => void); diff --git a/packages/tracing/.eslintrc.js b/packages/tracing/.eslintrc.js deleted file mode 100644 index 7a937173064e..000000000000 --- a/packages/tracing/.eslintrc.js +++ /dev/null @@ -1,11 +0,0 @@ -module.exports = { - extends: ['../../.eslintrc.js'], - overrides: [ - { - files: ['src/node/**'], - rules: { - '@sentry-internal/sdk/no-optional-chaining': 'off', - }, - }, - ], -}; diff --git a/packages/tracing/LICENSE b/packages/tracing/LICENSE deleted file mode 100644 index 5113ccb2ac3d..000000000000 --- a/packages/tracing/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ -Copyright (c) 2020 Sentry (https://sentry.io) and individual contributors. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit -persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR -COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/tracing/README.md b/packages/tracing/README.md deleted file mode 100644 index 09bf79eb2e89..000000000000 --- a/packages/tracing/README.md +++ /dev/null @@ -1,163 +0,0 @@ -

- - Sentry - -

- -> ⚠️ **Deprecation Notice:** From SDK versions >= `7.47.0` onwards, the `@sentry/tracing` package is officially deprecated. This package will be removed in a future major release. More details can be found in the [migration docs](https://github.com/getsentry/sentry-javascript/blob/7.47.0/MIGRATION.md/#remove-requirement-for-sentrytracing-package-since-7460). - -# Sentry Tracing Extensions - -[![npm version](https://img.shields.io/npm/v/@sentry/tracing.svg)](https://www.npmjs.com/package/@sentry/tracing) -[![npm dm](https://img.shields.io/npm/dm/@sentry/tracing.svg)](https://www.npmjs.com/package/@sentry/tracing) -[![npm dt](https://img.shields.io/npm/dt/@sentry/tracing.svg)](https://www.npmjs.com/package/@sentry/tracing) - -## Links - -- [Official SDK Docs](https://docs.sentry.io/quickstart/) -- [TypeDoc](http://getsentry.github.io/sentry-javascript/) - -## General - -This package contains extensions to the Sentry SDKs to enable Sentry AM related functionality. It also provides integrations for Browser and Node that provide a good experience out of the box. - -## Migrating from @sentry/apm to @sentry/tracing - -The tracing integration for JavaScript SDKs has moved from -[`@sentry/apm`](https://www.npmjs.com/package/@sentry/apm) to -[`@sentry/tracing`](https://www.npmjs.com/package/@sentry/tracing). While the -two packages are similar, some imports and APIs have changed slightly. - -The old package `@sentry/apm` is deprecated in favor of `@sentry/tracing`. -Future support for `@sentry/apm` is limited to bug fixes only. - -## Migrating from @sentry/apm to @sentry/tracing - -### Browser (CDN bundle) - -If you were using the Browser CDN bundle, switch from the old -`bundle.apm.min.js` to the new tracing bundle: - -```html - -``` - -And then update `Sentry.init`: - -```diff - Sentry.init({ -- integrations: [new Sentry.Integrations.Tracing()] -+ integrations: [new Sentry.Integrations.BrowserTracing()] - }); -``` - -### Browser (npm package) - -If you were using automatic instrumentation, update the import statement and -update `Sentry.init` to use the new `BrowserTracing` integration: - -```diff - import * as Sentry from "@sentry/browser"; --import { Integrations } from "@sentry/apm"; -+import { Integrations } from "@sentry/tracing"; - - Sentry.init({ - integrations: [ -- new Integrations.Tracing(), -+ new Integrations.BrowserTracing(), - ] - }); -``` - -If you were using the `beforeNavigate` option from the `Tracing` integration, -the API in `BrowserTracing` has changed slightly. Instead of passing in a -location and returning a string representing transaction name, `beforeNavigate` -now accepts a transaction context and is expected to return a transaction -context. You can now add extra tags or change the `op` based on different -parameters. If you want to access the location like before, you can get it from -`window.location`. - -For example, if you had a function like so that computed a custom transaction -name: - -```javascript -import * as Sentry from "@sentry/browser"; -import { Integrations } from "@sentry/apm"; - -Sentry.init({ - integrations: [ - new Integrations.Tracing({ - beforeNavigate: location => { - return getTransactionName(location); - }, - }), - ], -}); -``` - -You would now leverage the context to do the same thing: - -```javascript -import * as Sentry from "@sentry/browser"; -import { Integrations } from "@sentry/tracing"; - -Sentry.init({ - integrations: [ - new Integrations.BrowserTracing({ - beforeNavigate: context => { - return { - ...context, - // Can even look at context tags or other data to adjust - // transaction name - name: getTransactionName(window.location), - }; - }, - }), - ], -}); -``` - -For the full diff: - -```diff - import * as Sentry from "@sentry/browser"; --import { Integrations } from "@sentry/apm"; -+import { Integrations } from "@sentry/tracing"; - - Sentry.init({ - integrations: [ -- new Integrations.Tracing({ -- beforeNavigate: (location) => { -- return getTransactionName(location) -+ new Integrations.BrowserTracing({ -+ beforeNavigate: (ctx) => { -+ return { -+ ...ctx, -+ name: getTransactionName(ctx.name, window.location) -+ } - } - }), - ] - }); -``` - -### Node - -If you were using the Express integration for automatic instrumentation, the -only necessary change is to update the import statement: - -```diff - import * as Sentry from "@sentry/node"; --import { Integrations } from "@sentry/apm"; -+import { Integrations } from "@sentry/tracing"; - - Sentry.init({ - integrations: [ - new Integrations.Express(), - ] - }); -``` diff --git a/packages/tracing/jest.config.js b/packages/tracing/jest.config.js deleted file mode 100644 index 24f49ab59a4c..000000000000 --- a/packages/tracing/jest.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = require('../../jest/jest.config.js'); diff --git a/packages/tracing/package.json b/packages/tracing/package.json deleted file mode 100644 index aa8b44ecdc5c..000000000000 --- a/packages/tracing/package.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "@sentry/tracing", - "version": "7.100.0", - "description": "Sentry Performance Monitoring Package", - "repository": "git://github.com/getsentry/sentry-javascript.git", - "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/tracing", - "author": "Sentry", - "license": "MIT", - "engines": { - "node": ">=14" - }, - "files": [ - "cjs", - "esm", - "types", - "types-ts3.8" - ], - "main": "build/npm/cjs/index.js", - "module": "build/npm/esm/index.js", - "types": "build/npm/types/index.d.ts", - "typesVersions": { - "<4.9": { - "build/npm/types/index.d.ts": [ - "build/npm/types-ts3.8/index.d.ts" - ] - } - }, - "publishConfig": { - "access": "public" - }, - "dependencies": { - "@sentry-internal/tracing": "7.100.0" - }, - "devDependencies": { - "@sentry-internal/integration-shims": "7.100.0", - "@sentry/browser": "7.100.0", - "@sentry/core": "7.100.0", - "@sentry/types": "7.100.0", - "@sentry/utils": "7.100.0", - "@types/express": "^4.17.14" - }, - "scripts": { - "build": "run-p build:transpile build:types", - "build:dev": "run-p build:transpile build:types", - "build:transpile": "rollup -c rollup.npm.config.mjs", - "build:types": "run-s build:types:core build:types:downlevel", - "build:types:core": "tsc -p tsconfig.types.json", - "build:types:downlevel": "yarn downlevel-dts build/npm/types build/npm/types-ts3.8 --to ts3.8", - "build:watch": "run-p build:transpile:watch build:types:watch", - "build:dev:watch": "run-p build:transpile:watch build:types:watch", - "build:transpile:watch": "rollup -c rollup.npm.config.mjs --watch", - "build:types:watch": "tsc -p tsconfig.types.json --watch", - "build:tarball": "ts-node ../../scripts/prepack.ts --bundles && npm pack ./build/npm", - "clean": "rimraf build coverage sentry-tracing-*.tgz", - "circularDepCheck": "madge --circular src/index.ts", - "fix": "eslint . --format stylish --fix", - "lint": "eslint . --format stylish", - "test:unit": "jest", - "test": "jest", - "test:watch": "jest --watch", - "yalc:publish": "ts-node ../../scripts/prepack.ts --bundles && yalc publish ./build/npm --push --sig" - }, - "volta": { - "extends": "../../package.json" - }, - "sideEffects": [ - "./cjs/index.js", - "./esm/index.js", - "./build/npm/cjs/index.js", - "./build/npm/esm/index.js", - "./src/index.ts" - ] -} diff --git a/packages/tracing/rollup.npm.config.mjs b/packages/tracing/rollup.npm.config.mjs deleted file mode 100644 index 6d09adefc859..000000000000 --- a/packages/tracing/rollup.npm.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { makeBaseNPMConfig, makeNPMConfigVariants } from '@sentry-internal/rollup-utils'; - -export default makeNPMConfigVariants( - makeBaseNPMConfig({ - // packages with bundles have a different build directory structure - hasBundles: true, - }), -); diff --git a/packages/tracing/src/index.ts b/packages/tracing/src/index.ts deleted file mode 100644 index 7192736b0f62..000000000000 --- a/packages/tracing/src/index.ts +++ /dev/null @@ -1,255 +0,0 @@ -import type { - RequestInstrumentationOptions as RequestInstrumentationOptionsT, - SpanStatusType as SpanStatusTypeT, -} from '@sentry-internal/tracing'; -import { - Apollo, - BROWSER_TRACING_INTEGRATION_ID as BROWSER_TRACING_INTEGRATION_ID_T, - BrowserTracing as BrowserTracingT, - Express, - GraphQL, - IdleTransaction as IdleTransactionT, - Mongo, - Mysql, - Postgres, - Prisma, - Span as SpanT, - SpanStatus as SpanStatusT, - TRACEPARENT_REGEXP as TRACEPARENT_REGEXP_T, - Transaction as TransactionT, - addExtensionMethods as addExtensionMethodsT, - defaultRequestInstrumentationOptions as defaultRequestInstrumentationOptionsT, - getActiveTransaction as getActiveTransactionT, - hasTracingEnabled as hasTracingEnabledT, - instrumentOutgoingRequests as instrumentOutgoingRequestsT, - startIdleTransaction as startIdleTransactionT, - stripUrlQueryAndFragment as stripUrlQueryAndFragmentT, -} from '@sentry-internal/tracing'; - -// BrowserTracing is already exported as part of `Integrations` below (and for the moment will remain so for -// backwards compatibility), but that interferes with treeshaking, so we also export it separately -// here. -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `BrowserTracing` can be imported from `@sentry/browser` or your framework SDK - * - * import { BrowserTracing } from '@sentry/browser'; - * new BrowserTracing() - */ -// eslint-disable-next-line deprecation/deprecation -export const BrowserTracing = BrowserTracingT; - -// BrowserTracing is already exported as part of `Integrations` below (and for the moment will remain so for -// backwards compatibility), but that interferes with treeshaking, so we also export it separately -// here. -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `BrowserTracing` can be imported from `@sentry/browser` or your framework SDK - * - * import { BrowserTracing } from '@sentry/browser'; - * new BrowserTracing() - */ -// eslint-disable-next-line deprecation/deprecation -export type BrowserTracing = BrowserTracingT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const addExtensionMethods = addExtensionMethodsT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `getActiveTransaction` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -// eslint-disable-next-line deprecation/deprecation -export const getActiveTransaction = getActiveTransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `SpanStatusType` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -export type SpanStatusType = SpanStatusTypeT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `Transaction` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -export const Transaction = TransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `Transaction` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -export type Transaction = TransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `Span` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -export const Span = SpanT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `Span` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -export type Span = SpanT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const BROWSER_TRACING_INTEGRATION_ID = BROWSER_TRACING_INTEGRATION_ID_T; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `defaultRequestInstrumentationOptions` can be imported from `@sentry/browser`, or your framework SDK - */ -export const defaultRequestInstrumentationOptions = defaultRequestInstrumentationOptionsT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `hasTracingEnabled` can be imported from `@sentry/utils` - */ -export const hasTracingEnabled = hasTracingEnabledT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `stripUrlQueryAndFragment` can be imported from `@sentry/utils` - */ -export const stripUrlQueryAndFragment = stripUrlQueryAndFragmentT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `TRACEPARENT_REGEXP` can be imported from `@sentry/utils` - */ -export const TRACEPARENT_REGEXP = TRACEPARENT_REGEXP_T; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const IdleTransaction = IdleTransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export type IdleTransaction = IdleTransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const instrumentOutgoingRequests = instrumentOutgoingRequestsT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const startIdleTransaction = startIdleTransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -// eslint-disable-next-line deprecation/deprecation -export const SpanStatus = SpanStatusT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -// eslint-disable-next-line deprecation/deprecation -export type SpanStatus = SpanStatusT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export type RequestInstrumentationOptions = RequestInstrumentationOptionsT; - -export const Integrations = { - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `BrowserTracing` can be imported from `@sentry/browser` or your framework SDK - * - * import { BrowserTracing } from '@sentry/browser'; - * new BrowserTracing() - */ - // eslint-disable-next-line deprecation/deprecation - BrowserTracing: BrowserTracing, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Apollo` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Apollo({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Apollo: Apollo, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Express` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Express({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Express: Express, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `GraphQL` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.GraphQL({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - GraphQL: GraphQL, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Mongo` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Mongo({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Mongo: Mongo, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Mysql` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Mysql({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Mysql: Mysql, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Postgres` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Postgres({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Postgres: Postgres, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Prisma` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Prisma({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Prisma: Prisma, -}; - -// Treeshakable guard to remove all code related to tracing -declare const __SENTRY_TRACING__: boolean; - -// Guard for tree -if (typeof __SENTRY_TRACING__ === 'undefined' || __SENTRY_TRACING__) { - // We are patching the global object with our hub extension methods - addExtensionMethodsT(); -} diff --git a/packages/tracing/test/hub.test.ts b/packages/tracing/test/hub.test.ts deleted file mode 100644 index b12966e6b3dc..000000000000 --- a/packages/tracing/test/hub.test.ts +++ /dev/null @@ -1,637 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { BrowserClient } from '@sentry/browser'; -import { Hub, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, makeMain } from '@sentry/core'; -import * as utilsModule from '@sentry/utils'; // for mocking -import { extractTraceparentData, logger } from '@sentry/utils'; - -import { BrowserTracing, TRACEPARENT_REGEXP, Transaction, addExtensionMethods } from '../src'; -import { - addDOMPropertiesToGlobal, - getDefaultBrowserClientOptions, - getSymbolObjectKeyByName, - testOnlyIfNodeVersionAtLeast, -} from './testutils'; - -addExtensionMethods(); - -const mathRandom = jest.spyOn(Math, 'random'); -jest.spyOn(Transaction.prototype, 'setAttribute'); -jest.spyOn(logger, 'warn'); -jest.spyOn(logger, 'log'); -jest.spyOn(logger, 'error'); -jest.spyOn(utilsModule, 'isNodeEnv'); - -addDOMPropertiesToGlobal(['XMLHttpRequest', 'Event', 'location', 'document']); - -describe('Hub', () => { - afterEach(() => { - jest.clearAllMocks(); - // Reset global carrier to the initial state - const hub = new Hub(); - makeMain(hub); - }); - - describe('getTransaction()', () => { - it('should find a transaction which has been set on the scope if sampled = true', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - transaction.sampled = true; - - hub.getScope().setSpan(transaction); - - expect(hub.getScope().getTransaction()).toBe(transaction); - }); - - it('should find a transaction which has been set on the scope if sampled = false', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); - - hub.getScope().setSpan(transaction); - - expect(hub.getScope().getTransaction()).toBe(transaction); - }); - - it("should not find an open transaction if it's not on the scope", () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(hub.getScope().getTransaction()).toBeUndefined(); - }); - }); - - describe('transaction sampling', () => { - describe('default sample context', () => { - it('should add transaction context data to default sample context', () => { - const tracesSampler = jest.fn(); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - - const transactionContext = { - name: 'dogpark', - parentSpanId: '12312012', - parentSampled: true, - }; - - hub.startTransaction(transactionContext); - - expect(tracesSampler).toHaveBeenLastCalledWith(expect.objectContaining({ transactionContext })); - }); - - it("should add parent's sampling decision to default sample context", () => { - const tracesSampler = jest.fn(); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const parentSamplingDecsion = false; - - hub.startTransaction({ - name: 'dogpark', - parentSpanId: '12312012', - parentSampled: parentSamplingDecsion, - }); - - expect(tracesSampler).toHaveBeenLastCalledWith( - expect.objectContaining({ parentSampled: parentSamplingDecsion }), - ); - }); - }); - - describe('sample()', () => { - it('should set sampled = false when tracing is disabled', () => { - const options = getDefaultBrowserClientOptions({}); - // neither tracesSampleRate nor tracesSampler is defined -> tracing disabled - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(transaction.sampled).toBe(false); - }); - - it('should set sampled = false if tracesSampleRate is 0', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(transaction.sampled).toBe(false); - }); - - it('should set sampled = true if tracesSampleRate is 1', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(transaction.sampled).toBe(true); - }); - - it('should set sampled = true if tracesSampleRate is 1 (without global hub)', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const hub = new Hub(new BrowserClient(options)); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(transaction.sampled).toBe(true); - }); - - it("should call tracesSampler if it's defined", () => { - const tracesSampler = jest.fn(); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(tracesSampler).toHaveBeenCalled(); - }); - - it('should set sampled = false if tracesSampler returns 0', () => { - const tracesSampler = jest.fn().mockReturnValue(0); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(tracesSampler).toHaveBeenCalled(); - expect(transaction.sampled).toBe(false); - }); - - it('should set sampled = true if tracesSampler returns 1', () => { - const tracesSampler = jest.fn().mockReturnValue(1); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(tracesSampler).toHaveBeenCalled(); - expect(transaction.sampled).toBe(true); - }); - - it('should set sampled = true if tracesSampler returns 1 (without global hub)', () => { - const tracesSampler = jest.fn().mockReturnValue(1); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(tracesSampler).toHaveBeenCalled(); - expect(transaction.sampled).toBe(true); - }); - - it('should set sampled = true if enableTracing is true', () => { - const options = getDefaultBrowserClientOptions({ enableTracing: true }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(transaction.sampled).toBe(true); - }); - - it('should set sampled = false if enableTracing is true & tracesSampleRate is 0', () => { - const options = getDefaultBrowserClientOptions({ enableTracing: true, tracesSampleRate: 0 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(transaction.sampled).toBe(false); - }); - - it('should set sampled = false if enableTracing is false & tracesSampleRate is 0', () => { - const options = getDefaultBrowserClientOptions({ enableTracing: false, tracesSampleRate: 0 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(transaction.sampled).toBe(false); - }); - - it('should prefer tracesSampler returning false to enableTracing', () => { - // make the two options do opposite things to prove precedence - const tracesSampler = jest.fn().mockReturnValue(false); - const options = getDefaultBrowserClientOptions({ enableTracing: true, tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(tracesSampler).toHaveBeenCalled(); - expect(transaction.sampled).toBe(false); - }); - - it('should prefer tracesSampler returning true to enableTracing', () => { - // make the two options do opposite things to prove precedence - const tracesSampler = jest.fn().mockReturnValue(true); - const options = getDefaultBrowserClientOptions({ enableTracing: false, tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(tracesSampler).toHaveBeenCalled(); - expect(transaction.sampled).toBe(true); - }); - - it('should not try to override explicitly set positive sampling decision', () => { - // so that the decision otherwise would be false - const tracesSampler = jest.fn().mockReturnValue(0); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark', sampled: true }); - - expect(transaction.sampled).toBe(true); - }); - - it('should not try to override explicitly set negative sampling decision', () => { - // so that the decision otherwise would be true - const tracesSampler = jest.fn().mockReturnValue(1); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); - - expect(transaction.sampled).toBe(false); - }); - - it('should prefer tracesSampler to tracesSampleRate', () => { - // make the two options do opposite things to prove precedence - const tracesSampler = jest.fn().mockReturnValue(true); - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0, tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(tracesSampler).toHaveBeenCalled(); - expect(transaction.sampled).toBe(true); - }); - - it('should tolerate tracesSampler returning a boolean', () => { - const tracesSampler = jest.fn().mockReturnValue(true); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - expect(tracesSampler).toHaveBeenCalled(); - expect(transaction.sampled).toBe(true); - }); - - it('should record sampling method when sampling decision is explicitly set', () => { - const tracesSampler = jest.fn().mockReturnValue(0.1121); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark', sampled: true }); - - expect(Transaction.prototype.setAttribute).toHaveBeenCalledWith(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, 1); - }); - - it('should record sampling method and rate when sampling decision comes from tracesSampler', () => { - const tracesSampler = jest.fn().mockReturnValue(0.1121); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(Transaction.prototype.setAttribute).toHaveBeenCalledWith(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, 0.1121); - }); - - it('should record sampling method when sampling decision is inherited', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0.1121 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark', parentSampled: true }); - - // length 2 because origin and op are set as attributes on span initialization - expect(Transaction.prototype.setAttribute).toHaveBeenCalledTimes(2); - }); - - it('should record sampling method and rate when sampling decision comes from traceSampleRate', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0.1121 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(Transaction.prototype.setAttribute).toHaveBeenCalledWith(SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, 0.1121); - }); - }); - - describe('isValidSampleRate()', () => { - it("should reject tracesSampleRates which aren't numbers or booleans", () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 'dogs!' as any }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('Sample rate must be a boolean or a number')); - }); - - it('should reject tracesSampleRates which are NaN', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 'dogs!' as any }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('Sample rate must be a boolean or a number')); - }); - - // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 - it('should reject tracesSampleRates less than 0', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: -26 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('Sample rate must be between 0 and 1')); - }); - - // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 - it('should reject tracesSampleRates greater than 1', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 26 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('Sample rate must be between 0 and 1')); - }); - - it("should reject tracesSampler return values which aren't numbers or booleans", () => { - const tracesSampler = jest.fn().mockReturnValue('dogs!'); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('Sample rate must be a boolean or a number')); - }); - - it('should reject tracesSampler return values which are NaN', () => { - const tracesSampler = jest.fn().mockReturnValue(NaN); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('Sample rate must be a boolean or a number')); - }); - - // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 - it('should reject tracesSampler return values less than 0', () => { - const tracesSampler = jest.fn().mockReturnValue(-12); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('Sample rate must be between 0 and 1')); - }); - - // the rate might be a boolean, but for our purposes, false is equivalent to 0 and true is equivalent to 1 - it('should reject tracesSampler return values greater than 1', () => { - const tracesSampler = jest.fn().mockReturnValue(31); - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - hub.startTransaction({ name: 'dogpark' }); - - expect(logger.warn).toHaveBeenCalledWith(expect.stringContaining('Sample rate must be between 0 and 1')); - }); - }); - - it('should drop transactions with sampled = false', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0 }); - const client = new BrowserClient(options); - jest.spyOn(client, 'captureEvent'); - - const hub = new Hub(client); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - jest.spyOn(transaction, 'end'); - transaction.end(); - - expect(transaction.sampled).toBe(false); - expect(transaction.end).toReturnWith(undefined); - expect(client.captureEvent).not.toBeCalled(); - }); - - it('should drop transactions when using wrong instrumenter', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1, instrumenter: 'otel' }); - const client = new BrowserClient(options); - jest.spyOn(client, 'captureEvent'); - - const hub = new Hub(client); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - - jest.spyOn(transaction, 'end'); - transaction.end(); - - expect(transaction.sampled).toBe(false); - expect(transaction.end).toReturnWith(undefined); - expect(client.captureEvent).not.toBeCalled(); - expect(logger.error).toHaveBeenCalledWith( - `A transaction was started with instrumenter=\`sentry\`, but the SDK is configured with the \`otel\` instrumenter. -The transaction will not be sampled. Please use the otel instrumentation to start transactions.`, - ); - }); - - describe('sampling inheritance', () => { - it('should propagate sampling decision to child spans', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: Math.random() }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark' }); - const child = transaction.startChild({ op: 'ball.chase' }); - - expect(child.sampled).toBe(transaction.sampled); - }); - - // TODO the way we dig out the headers to test them doesn't work on Node < 10 - testOnlyIfNodeVersionAtLeast(10)( - 'should propagate positive sampling decision to child transactions in XHR header', - async () => { - const options = getDefaultBrowserClientOptions({ - dsn: 'https://1231@dogs.are.great/1121', - tracesSampleRate: 1, - integrations: [new BrowserTracing()], - }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - - const transaction = hub.startTransaction({ name: 'dogpark' }); - hub.getScope().setSpan(transaction); - - const request = new XMLHttpRequest(); - await new Promise(resolve => { - request.timeout = 1; - request.onloadend = request.ontimeout = resolve; - request.open('GET', '/chase-partners'); - request.send(''); - }); - - // this looks weird, it's true, but it's really just `request.impl.flag.requestHeaders` - it's just that the - // `impl` key is a symbol rather than a string, and therefore needs to be referred to by reference rather than - // value - const headers = (request as any)[getSymbolObjectKeyByName(request, 'impl') as symbol].flag.requestHeaders; - - // check that sentry-trace header is added to request - expect(headers).toEqual( - expect.objectContaining({ 'sentry-trace': expect.stringMatching(TRACEPARENT_REGEXP) }), - ); - - // check that sampling decision is passed down correctly - expect(transaction.sampled).toBe(true); - expect(extractTraceparentData(headers['sentry-trace'])!.parentSampled).toBe(true); - }, - ); - - // TODO the way we dig out the headers to test them doesn't work on Node < 10 - testOnlyIfNodeVersionAtLeast(10)( - 'should propagate negative sampling decision to child transactions in XHR header', - async () => { - const options = getDefaultBrowserClientOptions({ - dsn: 'https://1231@dogs.are.great/1121', - tracesSampleRate: 1, - integrations: [new BrowserTracing()], - }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - - const transaction = hub.startTransaction({ name: 'dogpark', sampled: false }); - hub.getScope().setSpan(transaction); - - const request = new XMLHttpRequest(); - await new Promise(resolve => { - request.timeout = 1; - request.onloadend = request.ontimeout = resolve; - request.open('GET', '/chase-partners'); - request.send(''); - }); - - // this looks weird, it's true, but it's really just `request.impl.flag.requestHeaders` - it's just that the - // `impl` key is a symbol rather than a string, and therefore needs to be referred to by reference rather than - // value - const headers = (request as any)[getSymbolObjectKeyByName(request, 'impl') as symbol].flag.requestHeaders; - - // check that sentry-trace header is added to request - expect(headers).toEqual( - expect.objectContaining({ 'sentry-trace': expect.stringMatching(TRACEPARENT_REGEXP) }), - ); - - // check that sampling decision is passed down correctly - expect(transaction.sampled).toBe(false); - expect(extractTraceparentData(headers['sentry-trace'])!.parentSampled).toBe(false); - }, - ); - - it('should propagate positive sampling decision to child transactions in fetch header', () => { - // TODO - }); - - it('should propagate negative sampling decision to child transactions in fetch header', () => { - // TODO - }); - - it("should inherit parent's positive sampling decision if tracesSampler is undefined", () => { - // we know that without inheritance we'll get sampled = false (since our "random" number won't be below the - // sample rate), so make parent's decision the opposite to prove that inheritance takes precedence over - // tracesSampleRate - mathRandom.mockReturnValueOnce(1); - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 0.5 }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const parentSamplingDecsion = true; - - const transaction = hub.startTransaction({ - name: 'dogpark', - parentSpanId: '12312012', - parentSampled: parentSamplingDecsion, - }); - - expect(transaction.sampled).toBe(parentSamplingDecsion); - }); - - it("should inherit parent's negative sampling decision if tracesSampler is undefined", () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - // tracesSampleRate = 1 means every transaction should end up with sampled = true, so make parent's decision the - // opposite to prove that inheritance takes precedence over tracesSampleRate - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - const parentSamplingDecsion = false; - - const transaction = hub.startTransaction({ - name: 'dogpark', - parentSpanId: '12312012', - parentSampled: parentSamplingDecsion, - }); - - expect(transaction.sampled).toBe(parentSamplingDecsion); - }); - - it("should ignore parent's positive sampling decision when tracesSampler is defined", () => { - // this tracesSampler causes every transaction to end up with sampled = true, so make parent's decision the - // opposite to prove that tracesSampler takes precedence over inheritance - const tracesSampler = () => true; - const parentSamplingDecsion = false; - - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - - const transaction = hub.startTransaction({ - name: 'dogpark', - parentSpanId: '12312012', - parentSampled: parentSamplingDecsion, - }); - - expect(transaction.sampled).not.toBe(parentSamplingDecsion); - }); - - it("should ignore parent's negative sampling decision when tracesSampler is defined", () => { - // this tracesSampler causes every transaction to end up with sampled = false, so make parent's decision the - // opposite to prove that tracesSampler takes precedence over inheritance - const tracesSampler = () => false; - const parentSamplingDecsion = true; - - const options = getDefaultBrowserClientOptions({ tracesSampler }); - const hub = new Hub(new BrowserClient(options)); - makeMain(hub); - - const transaction = hub.startTransaction({ - name: 'dogpark', - parentSpanId: '12312012', - parentSampled: parentSamplingDecsion, - }); - - expect(transaction.sampled).not.toBe(parentSamplingDecsion); - }); - }); - }); - - describe('trimming transaction', () => { - describe('it should trim a transaction to the span timestamp if trimEnd is true', () => { - const options = getDefaultBrowserClientOptions({ - tracesSampleRate: 1, - dsn: 'https://username@domain/123', - }); - const client = new BrowserClient(options); - const hub = new Hub(client); - - const captureEventSpy = jest.spyOn(hub, 'captureEvent'); - - makeMain(hub); - const transaction = hub.startTransaction({ name: 'dogpark', startTimestamp: 1000, trimEnd: true }); - - transaction.startChild({ op: 'test', startTimestamp: 1200, endTimestamp: 1500 }); - - transaction.end(2000); - - expect(captureEventSpy).toHaveBeenCalledTimes(1); - expect(captureEventSpy.mock.calls[0][0].timestamp).toEqual(1500); - }); - }); -}); diff --git a/packages/tracing/test/index.test.ts b/packages/tracing/test/index.test.ts deleted file mode 100644 index ea35353868ca..000000000000 --- a/packages/tracing/test/index.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { getCurrentHub } from '@sentry/core'; - -import { BrowserTracing, Integrations } from '../src'; - -describe('index', () => { - it('patches the global hub to add an implementation for `Hub.startTransaction` as a side effect', () => { - // eslint-disable-next-line deprecation/deprecation - const hub = getCurrentHub(); - // eslint-disable-next-line deprecation/deprecation - const transaction = hub.startTransaction({ name: 'test', endTimestamp: 123 }); - expect(transaction).toBeDefined(); - }); - - describe('Integrations', () => { - it('is exported correctly', () => { - Object.keys(Integrations).forEach(key => { - // Skip BrowserTracing because it doesn't have a static id field. - if (key === 'BrowserTracing') { - return; - } - - expect(Integrations[key as keyof Omit].id).toStrictEqual( - expect.any(String), - ); - }); - }); - - it('contains BrowserTracing', () => { - // eslint-disable-next-line deprecation/deprecation - expect(Integrations.BrowserTracing).toEqual(BrowserTracing); - }); - }); -}); diff --git a/packages/tracing/test/integrations/apollo-nestjs.test.ts b/packages/tracing/test/integrations/apollo-nestjs.test.ts deleted file mode 100644 index 7e9866146385..000000000000 --- a/packages/tracing/test/integrations/apollo-nestjs.test.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope } from '@sentry/core'; -import { logger } from '@sentry/utils'; - -import { Integrations, Span } from '../../src'; -import { getTestClient } from '../testutils'; - -type ApolloResolverGroup = { - [key: string]: () => unknown; -}; - -type ApolloModelResolvers = { - [key: string]: ApolloResolverGroup; -}; - -class GraphQLFactory { - _resolvers: ApolloModelResolvers[]; - resolversExplorerService = { - explore: () => this._resolvers, - }; - constructor() { - this._resolvers = [ - { - Query: { - res_1(..._args: unknown[]) { - return 'foo'; - }, - }, - Mutation: { - res_2(..._args: unknown[]) { - return 'bar'; - }, - }, - }, - ]; - - this.mergeWithSchema(); - } - - public mergeWithSchema(..._args: unknown[]) { - return this.resolversExplorerService.explore(); - } -} - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockFactory = GraphQLFactory; - -// mock for @nestjs/graphql package -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule() { - return { - GraphQLFactory: mockFactory, - }; - }, - }; -}); - -describe('setupOnce', () => { - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - let GraphQLFactoryInstance: GraphQLFactory; - - beforeAll(() => { - new Integrations.Apollo({ - useNestjs: true, - }).setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - - GraphQLFactoryInstance = new GraphQLFactory(); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new Span(); - childSpan = parentSpan.startChild(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(scope, 'setSpan'); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it('should wrap a simple resolver', () => { - GraphQLFactoryInstance._resolvers[0]?.['Query']?.['res_1']?.(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - description: 'Query.res_1', - op: 'graphql.resolve', - origin: 'auto.graphql.apollo', - }); - expect(childSpan.end).toBeCalled(); - }); - - it('should wrap another simple resolver', () => { - GraphQLFactoryInstance._resolvers[0]?.['Mutation']?.['res_2']?.(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - description: 'Mutation.res_2', - op: 'graphql.resolve', - origin: 'auto.graphql.apollo', - }); - expect(childSpan.end).toBeCalled(); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.Apollo({ useNestjs: true }); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('Apollo Integration is skipped because of instrumenter configuration.'); - }); -}); diff --git a/packages/tracing/test/integrations/apollo.test.ts b/packages/tracing/test/integrations/apollo.test.ts deleted file mode 100644 index ea861dcdec1f..000000000000 --- a/packages/tracing/test/integrations/apollo.test.ts +++ /dev/null @@ -1,126 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope } from '@sentry/core'; -import { logger } from '@sentry/utils'; - -import { Integrations, Span } from '../../src'; -import { getTestClient } from '../testutils'; - -type ApolloResolverGroup = { - [key: string]: () => any; -}; - -type ApolloModelResolvers = { - [key: string]: ApolloResolverGroup; -}; - -class ApolloServerBase { - config: { - resolvers: ApolloModelResolvers[]; - }; - - constructor() { - this.config = { - resolvers: [ - { - Query: { - res_1(..._args: unknown[]) { - return 'foo'; - }, - }, - Mutation: { - res_2(..._args: unknown[]) { - return 'bar'; - }, - }, - }, - ], - }; - - this.constructSchema(); - } - - public constructSchema(..._args: unknown[]) { - return null; - } -} - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockClient = ApolloServerBase; - -// mock for ApolloServer package -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule() { - return { - ApolloServerBase: mockClient, - }; - }, - }; -}); - -describe('setupOnce', () => { - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - let ApolloServer: ApolloServerBase; - - beforeAll(() => { - new Integrations.Apollo().setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - - ApolloServer = new ApolloServerBase(); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new Span(); - childSpan = parentSpan.startChild(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(scope, 'setSpan'); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it('should wrap a simple resolver', () => { - ApolloServer.config.resolvers[0]?.['Query']?.['res_1']?.(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - description: 'Query.res_1', - op: 'graphql.resolve', - origin: 'auto.graphql.apollo', - }); - expect(childSpan.end).toBeCalled(); - }); - - it('should wrap another simple resolver', () => { - ApolloServer.config.resolvers[0]?.['Mutation']?.['res_2']?.(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - description: 'Mutation.res_2', - op: 'graphql.resolve', - origin: 'auto.graphql.apollo', - }); - expect(childSpan.end).toBeCalled(); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.Apollo(); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('Apollo Integration is skipped because of instrumenter configuration.'); - }); -}); diff --git a/packages/tracing/test/integrations/graphql.test.ts b/packages/tracing/test/integrations/graphql.test.ts deleted file mode 100644 index 06b9495d8061..000000000000 --- a/packages/tracing/test/integrations/graphql.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope } from '@sentry/core'; -import { logger } from '@sentry/utils'; - -import { Integrations, Span } from '../../src'; -import { getTestClient } from '../testutils'; - -const GQLExecute = { - execute() { - return Promise.resolve(); - }, -}; - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockClient = GQLExecute; - -// mock for 'graphql/execution/execution.js' package -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule() { - return mockClient; - }, - }; -}); - -describe('setupOnce', () => { - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - - beforeAll(() => { - new Integrations.GraphQL().setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new Span(); - childSpan = parentSpan.startChild(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(scope, 'setSpan'); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it('should wrap execute method', async () => { - await GQLExecute.execute(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - description: 'execute', - op: 'graphql.execute', - origin: 'auto.graphql.graphql', - }); - expect(childSpan.end).toBeCalled(); - expect(scope.setSpan).toHaveBeenCalledTimes(2); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.GraphQL(); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('GraphQL Integration is skipped because of instrumenter configuration.'); - }); -}); diff --git a/packages/tracing/test/integrations/node/mongo.test.ts b/packages/tracing/test/integrations/node/mongo.test.ts deleted file mode 100644 index 8caa5f35750f..000000000000 --- a/packages/tracing/test/integrations/node/mongo.test.ts +++ /dev/null @@ -1,160 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope } from '@sentry/core'; -import { logger } from '@sentry/utils'; - -import { Integrations, Span } from '../../../src'; -import { getTestClient } from '../../testutils'; - -class Collection { - public collectionName: string = 'mockedCollectionName'; - public dbName: string = 'mockedDbName'; - public namespace: string = 'mockedNamespace'; - - // Method that can have a callback as last argument, or return a promise otherwise. - public insertOne(_doc: unknown, _options: unknown, callback?: () => void) { - if (typeof callback === 'function') { - callback(); - return; - } - return Promise.resolve(); - } - // Method that has no callback as last argument, and doesnt return promise. - public initializeOrderedBulkOp() { - return {}; - } -} - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockCollection = Collection; - -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule() { - return { - Collection: mockCollection, - }; - }, - }; -}); - -describe('patchOperation()', () => { - const doc = { - name: 'PickleRick', - answer: 42, - }; - const collection: Collection = new Collection(); - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - let testClient = getTestClient({}); - - beforeAll(() => { - new Integrations.Mongo({ - operations: ['insertOne', 'initializeOrderedBulkOp'], - }).setupOnce( - () => undefined, - () => new Hub(testClient, scope), - ); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new Span(); - childSpan = parentSpan.startChild(); - testClient = getTestClient({}); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it('should wrap method accepting callback as the last argument', done => { - collection.insertOne(doc, {}, function () { - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - data: { - 'db.mongodb.collection': 'mockedCollectionName', - 'db.name': 'mockedDbName', - 'db.operation': 'insertOne', - 'db.system': 'mongodb', - }, - op: 'db', - origin: 'auto.db.mongo', - description: 'insertOne', - }); - expect(childSpan.end).toBeCalled(); - done(); - }) as void; - }); - - it('should wrap method accepting no callback as the last argument but returning promise', async () => { - await collection.insertOne(doc, {}); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - data: { - 'db.mongodb.collection': 'mockedCollectionName', - 'db.name': 'mockedDbName', - 'db.operation': 'insertOne', - 'db.system': 'mongodb', - }, - op: 'db', - origin: 'auto.db.mongo', - description: 'insertOne', - }); - expect(childSpan.end).toBeCalled(); - }); - - it('attaches mongodb operation spans if sendDefaultPii is enabled', async () => { - testClient.getOptions().sendDefaultPii = true; - await collection.insertOne(doc, {}); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - data: { - 'db.mongodb.collection': 'mockedCollectionName', - 'db.mongodb.doc': '{"name":"PickleRick","answer":42}', - 'db.name': 'mockedDbName', - 'db.operation': 'insertOne', - 'db.system': 'mongodb', - }, - op: 'db', - origin: 'auto.db.mongo', - description: 'insertOne', - }); - expect(childSpan.end).toBeCalled(); - }); - - it('should wrap method accepting no callback as the last argument and not returning promise', () => { - collection.initializeOrderedBulkOp(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - data: { - 'db.mongodb.collection': 'mockedCollectionName', - 'db.name': 'mockedDbName', - 'db.operation': 'initializeOrderedBulkOp', - 'db.system': 'mongodb', - }, - op: 'db', - origin: 'auto.db.mongo', - description: 'initializeOrderedBulkOp', - }); - expect(childSpan.end).toBeCalled(); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.Mongo(); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('Mongo Integration is skipped because of instrumenter configuration.'); - }); -}); diff --git a/packages/tracing/test/integrations/node/postgres.test.ts b/packages/tracing/test/integrations/node/postgres.test.ts deleted file mode 100644 index c94b9870907b..000000000000 --- a/packages/tracing/test/integrations/node/postgres.test.ts +++ /dev/null @@ -1,153 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope } from '@sentry/core'; -import { loadModule, logger } from '@sentry/utils'; -import pg from 'pg'; - -import { Integrations, Span } from '../../../src'; -import { getTestClient } from '../../testutils'; - -class PgClient { - // https://node-postgres.com/api/client#clientquery - public query(_text: unknown, values: unknown, callback?: (err: unknown, result: unknown) => void) { - if (typeof callback === 'function') { - callback(null, null); - return; - } - - if (typeof values === 'function') { - values(); - return; - } - - return Promise.resolve(); - } -} - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockModule = { - Client: PgClient, - native: { - Client: PgClient, - }, -}; - -// mock for 'pg' / 'pg-native' package -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule: jest.fn(() => mockModule), - }; -}); - -describe('setupOnce', () => { - beforeEach(() => { - jest.clearAllMocks(); - jest.resetAllMocks(); - }); - - ['pg', 'pg-native'].forEach(pgApi => { - const Client: PgClient = new PgClient(); - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - - beforeAll(() => { - (pgApi === 'pg' ? new Integrations.Postgres() : new Integrations.Postgres({ usePgNative: true })).setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new Span(); - childSpan = parentSpan.startChild(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it(`should wrap ${pgApi}'s query method accepting callback as the last argument`, done => { - Client.query('SELECT NOW()', {}, function () { - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - description: 'SELECT NOW()', - op: 'db', - origin: 'auto.db.postgres', - data: { - 'db.system': 'postgresql', - }, - }); - expect(childSpan.end).toBeCalled(); - done(); - }) as void; - }); - - it(`should wrap ${pgApi}'s query method accepting callback as the second argument`, done => { - Client.query('SELECT NOW()', function () { - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - description: 'SELECT NOW()', - op: 'db', - origin: 'auto.db.postgres', - data: { - 'db.system': 'postgresql', - }, - }); - expect(childSpan.end).toBeCalled(); - done(); - }) as void; - }); - - it(`should wrap ${pgApi}'s query method accepting no callback as the last argument but returning promise`, async () => { - await Client.query('SELECT NOW()', null); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - description: 'SELECT NOW()', - op: 'db', - origin: 'auto.db.postgres', - data: { - 'db.system': 'postgresql', - }, - }); - expect(childSpan.end).toBeCalled(); - }); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.Postgres(); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('Postgres Integration is skipped because of instrumenter configuration.'); - }); - - it('does not attempt resolution when module is passed directly', async () => { - const scope = new Scope(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(new Span()); - - new Integrations.Postgres({ module: mockModule }).setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - - await new PgClient().query('SELECT NOW()', null); - - expect(loadModule).not.toBeCalled(); - expect(scope.getSpan).toBeCalled(); - }); - - it('has valid module type', () => { - expect(() => new Integrations.Postgres({ module: pg })).not.toThrow(); - }); -}); diff --git a/packages/tracing/test/integrations/node/prisma.test.ts b/packages/tracing/test/integrations/node/prisma.test.ts deleted file mode 100644 index 2541eebf8f91..000000000000 --- a/packages/tracing/test/integrations/node/prisma.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -import * as sentryCore from '@sentry/core'; -import { Hub } from '@sentry/core'; - -import { Integrations } from '../../../src'; -import { getTestClient } from '../../testutils'; - -const mockStartSpan = jest.fn(); - -jest.mock('@sentry/core', () => { - const original = jest.requireActual('@sentry/core'); - return { - ...original, - startSpan: (...args: unknown[]) => { - mockStartSpan(...args); - return original.startSpan(...args); - }, - }; -}); - -type PrismaMiddleware = (params: unknown, next: (params?: unknown) => Promise) => Promise; - -class PrismaClient { - public user: { create: () => Promise | undefined } = { - create: () => this._middleware?.({ action: 'create', model: 'user' }, () => Promise.resolve('result')), - }; - - public _engineConfig = { - activeProvider: 'postgresql', - clientVersion: '3.1.2', - }; - - private _middleware?: PrismaMiddleware; - - constructor() { - this._middleware = undefined; - } - - public $use(cb: PrismaMiddleware) { - this._middleware = cb; - } -} - -describe('setupOnce', function () { - beforeEach(() => { - mockStartSpan.mockClear(); - mockStartSpan.mockReset(); - }); - - it('should add middleware with $use method correctly', done => { - const prismaClient = new PrismaClient(); - new Integrations.Prisma({ client: prismaClient }); - void prismaClient.user.create()?.then(() => { - expect(mockStartSpan).toHaveBeenCalledTimes(1); - expect(mockStartSpan).toHaveBeenLastCalledWith( - { - attributes: { - 'sentry.origin': 'auto.db.prisma', - }, - name: 'user create', - onlyIfParent: true, - op: 'db.prisma', - data: { 'db.system': 'postgresql', 'db.prisma.version': '3.1.2', 'db.operation': 'create' }, - }, - expect.any(Function), - ); - done(); - }); - }); - - it("doesn't trace when using otel instrumenter", done => { - const prismaClient = new PrismaClient(); - new Integrations.Prisma({ client: prismaClient }); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - jest.spyOn(sentryCore, 'getCurrentHub').mockReturnValue(hub); - - void prismaClient.user.create()?.then(() => { - expect(mockStartSpan).not.toHaveBeenCalled(); - done(); - }); - }); -}); diff --git a/packages/tracing/test/span.test.ts b/packages/tracing/test/span.test.ts deleted file mode 100644 index ae13f42ea698..000000000000 --- a/packages/tracing/test/span.test.ts +++ /dev/null @@ -1,691 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -import { BrowserClient } from '@sentry/browser'; -import { Hub, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, Scope, makeMain, spanToJSON } from '@sentry/core'; -import type { BaseTransportOptions, ClientOptions, TransactionSource } from '@sentry/types'; - -import { Span, TRACEPARENT_REGEXP, Transaction } from '../src'; -import { getDefaultBrowserClientOptions } from './testutils'; - -describe('Span', () => { - let hub: Hub; - - beforeEach(() => { - const myScope = new Scope(); - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - hub = new Hub(new BrowserClient(options), myScope); - makeMain(hub); - }); - - describe('new Span', () => { - test('simple', () => { - const span = new Span({ sampled: true }); - const span2 = span.startChild(); - expect((span2 as any).parentSpanId).toBe((span as any).spanId); - expect((span2 as any).traceId).toBe((span as any).traceId); - expect((span2 as any).sampled).toBe((span as any).sampled); - }); - - test('sets instrumenter to `sentry` if not specified in constructor', () => { - const span = new Span({}); - - expect(span.instrumenter).toBe('sentry'); - }); - - test('allows to set instrumenter in constructor', () => { - const span = new Span({ instrumenter: 'otel' }); - - expect(span.instrumenter).toBe('otel'); - }); - }); - - describe('new Transaction', () => { - test('simple', () => { - const transaction = new Transaction({ name: 'test', sampled: true }); - const span2 = transaction.startChild(); - expect((span2 as any).parentSpanId).toBe((transaction as any).spanId); - expect((span2 as any).traceId).toBe((transaction as any).traceId); - expect((span2 as any).sampled).toBe((transaction as any).sampled); - }); - - test('gets currentHub', () => { - const transaction = new Transaction({ name: 'test' }); - expect((transaction as any)._hub).toBeInstanceOf(Hub); - }); - - test('inherit span list', () => { - const transaction = new Transaction({ name: 'test', sampled: true }); - const span2 = transaction.startChild(); - const span3 = span2.startChild(); - span3.end(); - expect(transaction.spanRecorder).toBe(span2.spanRecorder); - expect(transaction.spanRecorder).toBe(span3.spanRecorder); - }); - }); - - describe('setters', () => { - test('setTag', () => { - const span = new Span({}); - expect(span.tags.foo).toBeUndefined(); - span.setTag('foo', 'bar'); - expect(span.tags.foo).toBe('bar'); - span.setTag('foo', 'baz'); - expect(span.tags.foo).toBe('baz'); - }); - - test('setData', () => { - const span = new Span({}); - expect(span.data.foo).toBeUndefined(); - span.setData('foo', null); - expect(span.data.foo).toBe(null); - span.setData('foo', 2); - expect(span.data.foo).toBe(2); - span.setData('foo', true); - expect(span.data.foo).toBe(true); - }); - - test('setName', () => { - const span = new Span({}); - expect(span.description).toBeUndefined(); - span.updateName('foo'); - expect(span.description).toBe('foo'); - }); - }); - - describe('status', () => { - test('setStatus', () => { - const span = new Span({}); - span.setStatus('permission_denied'); - expect((span.getTraceContext() as any).status).toBe('permission_denied'); - }); - - // TODO (v8): Remove - test('setHttpStatus', () => { - const span = new Span({}); - span.setHttpStatus(404); - expect((span.getTraceContext() as any).status).toBe('not_found'); - expect(span.tags['http.status_code']).toBe('404'); - expect(span.data['http.response.status_code']).toBe(404); - }); - - // TODO (v8): Remove - test('isSuccess', () => { - const span = new Span({}); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(200); - expect(span.isSuccess()).toBe(true); - expect(spanToJSON(span).status).toBe('ok'); - span.setStatus('permission_denied'); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(0); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(-1); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(99); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(100); - expect(span.isSuccess()).toBe(true); - expect(spanToJSON(span).status).toBe('ok'); - }); - }); - - describe('toTraceparent', () => { - test('simple', () => { - expect(new Span().toTraceparent()).toMatch(TRACEPARENT_REGEXP); - }); - test('with sample', () => { - expect(new Span({ sampled: true }).toTraceparent()).toMatch(TRACEPARENT_REGEXP); - }); - }); - - describe('toJSON', () => { - test('simple', () => { - const span = JSON.parse( - JSON.stringify(new Span({ traceId: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', spanId: 'bbbbbbbbbbbbbbbb' })), - ); - expect(span).toHaveProperty('span_id', 'bbbbbbbbbbbbbbbb'); - expect(span).toHaveProperty('trace_id', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); - }); - - test('with parent', () => { - const spanA = new Span({ traceId: 'a', spanId: 'b' }) as any; - const spanB = new Span({ traceId: 'c', spanId: 'd', sampled: false, parentSpanId: spanA.spanId }); - const serialized = JSON.parse(JSON.stringify(spanB)); - expect(serialized).toHaveProperty('parent_span_id', 'b'); - expect(serialized).toHaveProperty('span_id', 'd'); - expect(serialized).toHaveProperty('trace_id', 'c'); - }); - - test('should drop all `undefined` values', () => { - const spanA = new Span({ traceId: 'a', spanId: 'b' }) as any; - const spanB = new Span({ - parentSpanId: spanA.spanId, - spanId: 'd', - traceId: 'c', - }); - const serialized = spanB.toJSON(); - expect(serialized).toStrictEqual({ - start_timestamp: expect.any(Number), - parent_span_id: 'b', - span_id: 'd', - trace_id: 'c', - origin: 'manual', - data: { - 'sentry.origin': 'manual', - }, - }); - }); - }); - - describe('finish', () => { - test('simple', () => { - const span = new Span({}); - expect(spanToJSON(span).timestamp).toBeUndefined(); - span.end(); - expect(spanToJSON(span).timestamp).toBeGreaterThan(1); - }); - - describe('hub.startTransaction', () => { - test('finish a transaction', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(0); - expect(spy.mock.calls[0][0].timestamp).toBeTruthy(); - expect(spy.mock.calls[0][0].start_timestamp).toBeTruthy(); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test('finish a transaction + child span', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpan = transaction.startChild(); - childSpan.end(); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(1); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - // See https://github.com/getsentry/sentry-javascript/issues/3254 - test('finish a transaction + child span + sampled:true', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test', op: 'parent', sampled: true }); - const childSpan = transaction.startChild({ op: 'child' }); - childSpan.end(); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(1); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test("finish a child span shouldn't trigger captureEvent", () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpan = transaction.startChild(); - childSpan.end(); - expect(spy).not.toHaveBeenCalled(); - }); - - test("finish a span with another one on the scope shouldn't override contexts.trace", () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpanOne = transaction.startChild(); - childSpanOne.end(); - - hub.getScope().setSpan(childSpanOne); - - const spanTwo = transaction.startChild(); - spanTwo.end(); - transaction.end(); - - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(2); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test('maxSpans correctly limits number of spans', () => { - const options = getDefaultBrowserClientOptions({ - _experiments: { maxSpans: 3 }, - tracesSampleRate: 1, - }); - const _hub = new Hub(new BrowserClient(options)); - const spy = jest.spyOn(_hub as any, 'captureEvent') as any; - const transaction = _hub.startTransaction({ name: 'test' }); - for (let i = 0; i < 10; i++) { - const child = transaction.startChild(); - child.end(); - } - transaction.end(); - expect(spy.mock.calls[0][0].spans).toHaveLength(3); - }); - - test('no span recorder created if transaction.sampled is false', () => { - const options = getDefaultBrowserClientOptions({ - tracesSampleRate: 1, - }); - const _hub = new Hub(new BrowserClient(options)); - const spy = jest.spyOn(_hub as any, 'captureEvent') as any; - const transaction = _hub.startTransaction({ name: 'test', sampled: false }); - for (let i = 0; i < 10; i++) { - const child = transaction.startChild(); - child.end(); - } - transaction.end(); - expect((transaction as any).spanRecorder).toBeUndefined(); - expect(spy).not.toHaveBeenCalled(); - }); - - test('tree structure of spans should be correct when mixing it with span on scope', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - - const transaction = hub.startTransaction({ name: 'test' }); - const childSpanOne = transaction.startChild(); - - const childSpanTwo = childSpanOne.startChild(); - childSpanTwo.end(); - - childSpanOne.end(); - - hub.getScope().setSpan(transaction); - - const spanTwo = transaction.startChild({}); - spanTwo.end(); - transaction.end(); - - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(3); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - expect(childSpanOne.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); - expect(childSpanTwo.toJSON().parent_span_id).toEqual(childSpanOne.toJSON().span_id); - expect(spanTwo.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); - }); - }); - }); - - describe('end', () => { - test('simple', () => { - const span = new Span({}); - expect(spanToJSON(span).timestamp).toBeUndefined(); - span.end(); - expect(spanToJSON(span).timestamp).toBeGreaterThan(1); - }); - - test('with endTime in seconds', () => { - const span = new Span({}); - expect(spanToJSON(span).timestamp).toBeUndefined(); - const endTime = Date.now() / 1000; - span.end(endTime); - expect(spanToJSON(span).timestamp).toBe(endTime); - }); - - test('with endTime in milliseconds', () => { - const span = new Span({}); - expect(spanToJSON(span).timestamp).toBeUndefined(); - const endTime = Date.now(); - span.end(endTime); - expect(spanToJSON(span).timestamp).toBe(endTime / 1000); - }); - - describe('hub.startTransaction', () => { - test('finish a transaction', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(0); - expect(spy.mock.calls[0][0].timestamp).toBeTruthy(); - expect(spy.mock.calls[0][0].start_timestamp).toBeTruthy(); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test('finish a transaction + child span', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpan = transaction.startChild(); - childSpan.end(); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(1); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - // See https://github.com/getsentry/sentry-javascript/issues/3254 - test('finish a transaction + child span + sampled:true', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test', op: 'parent', sampled: true }); - const childSpan = transaction.startChild({ op: 'child' }); - childSpan.end(); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(1); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test("finish a child span shouldn't trigger captureEvent", () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpan = transaction.startChild(); - childSpan.end(); - expect(spy).not.toHaveBeenCalled(); - }); - - test("finish a span with another one on the scope shouldn't override contexts.trace", () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpanOne = transaction.startChild(); - childSpanOne.end(); - - hub.getScope().setSpan(childSpanOne); - - const spanTwo = transaction.startChild(); - spanTwo.end(); - transaction.end(); - - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(2); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test('maxSpans correctly limits number of spans', () => { - const options = getDefaultBrowserClientOptions({ - _experiments: { maxSpans: 3 }, - tracesSampleRate: 1, - }); - const _hub = new Hub(new BrowserClient(options)); - const spy = jest.spyOn(_hub as any, 'captureEvent') as any; - const transaction = _hub.startTransaction({ name: 'test' }); - for (let i = 0; i < 10; i++) { - const child = transaction.startChild(); - child.end(); - } - transaction.end(); - expect(spy.mock.calls[0][0].spans).toHaveLength(3); - }); - - test('no span recorder created if transaction.sampled is false', () => { - const options = getDefaultBrowserClientOptions({ - tracesSampleRate: 1, - }); - const _hub = new Hub(new BrowserClient(options)); - const spy = jest.spyOn(_hub as any, 'captureEvent') as any; - const transaction = _hub.startTransaction({ name: 'test', sampled: false }); - for (let i = 0; i < 10; i++) { - const child = transaction.startChild(); - child.end(); - } - transaction.end(); - expect((transaction as any).spanRecorder).toBeUndefined(); - expect(spy).not.toHaveBeenCalled(); - }); - - test('tree structure of spans should be correct when mixing it with span on scope', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - - const transaction = hub.startTransaction({ name: 'test' }); - const childSpanOne = transaction.startChild(); - - const childSpanTwo = childSpanOne.startChild(); - childSpanTwo.end(); - - childSpanOne.end(); - - hub.getScope().setSpan(transaction); - - const spanTwo = transaction.startChild({}); - spanTwo.end(); - transaction.end(); - - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(3); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - expect(childSpanOne.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); - expect(childSpanTwo.toJSON().parent_span_id).toEqual(childSpanOne.toJSON().span_id); - expect(spanTwo.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); - }); - }); - }); - - describe('getTraceContext', () => { - test('should have status attribute undefined if no status tag is available', () => { - const span = new Span({}); - const context = span.getTraceContext(); - expect((context as any).status).toBeUndefined(); - }); - - test('should have success status extracted from tags', () => { - const span = new Span({}); - span.setStatus('ok'); - const context = span.getTraceContext(); - expect((context as any).status).toBe('ok'); - }); - - test('should have failure status extracted from tags', () => { - const span = new Span({}); - span.setStatus('resource_exhausted'); - const context = span.getTraceContext(); - expect((context as any).status).toBe('resource_exhausted'); - }); - - test('should drop all `undefined` values', () => { - const spanB = new Span({ spanId: 'd', traceId: 'c' }); - const context = spanB.getTraceContext(); - expect(context).toStrictEqual({ - span_id: 'd', - trace_id: 'c', - data: { - 'sentry.origin': 'manual', - }, - origin: 'manual', - }); - }); - }); - - describe('toContext and updateWithContext', () => { - test('toContext should return correct context', () => { - const originalContext = { - traceId: 'a', - spanId: 'b', - sampled: false, - description: 'test', - op: 'op', - }; - const span = new Span(originalContext); - - const newContext = span.toContext(); - - expect(newContext).toStrictEqual({ - ...originalContext, - spanId: expect.any(String), - startTimestamp: expect.any(Number), - tags: {}, - traceId: expect.any(String), - data: { - 'sentry.op': 'op', - 'sentry.origin': 'manual', - }, - }); - }); - - test('updateWithContext should completely change span properties', () => { - const originalContext = { - traceId: 'a', - spanId: 'b', - sampled: false, - description: 'test', - op: 'op', - tags: { - tag0: 'hello', - }, - }; - const span = new Span(originalContext); - - span.updateWithContext({ - traceId: 'c', - spanId: 'd', - sampled: true, - }); - - expect(span.spanContext().traceId).toBe('c'); - expect(span.spanContext().spanId).toBe('d'); - expect(span.sampled).toBe(true); - expect(span.description).toBe(undefined); - expect(span.op).toBe(undefined); - expect(span.tags).toStrictEqual({}); - }); - - test('using toContext and updateWithContext together should update only changed properties', () => { - const originalContext = { - traceId: 'a', - spanId: 'b', - sampled: false, - description: 'test', - op: 'op', - tags: { tag0: 'hello' }, - data: { data0: 'foo' }, - }; - const span = new Span(originalContext); - - const newContext = { - ...span.toContext(), - description: 'new', - endTimestamp: 1, - op: 'new-op', - sampled: true, - tags: { - tag1: 'bye', - }, - data: { - ...span.toContext().data, - }, - }; - - if (newContext.data) newContext.data.data1 = 'bar'; - - span.updateWithContext(newContext); - - expect(span.spanContext().traceId).toBe('a'); - expect(span.spanContext().spanId).toBe('b'); - expect(span.description).toBe('new'); - expect(spanToJSON(span).timestamp).toBe(1); - expect(span.op).toBe('new-op'); - expect(span.sampled).toBe(true); - expect(span.tags).toStrictEqual({ tag1: 'bye' }); - expect(span.data).toStrictEqual({ - data0: 'foo', - data1: 'bar', - 'sentry.op': 'op', - 'sentry.origin': 'manual', - }); - }); - }); - - describe('getDynamicSamplingContext', () => { - beforeEach(() => { - hub.getClient()!.getOptions = () => { - return { - release: '1.0.1', - environment: 'production', - } as ClientOptions; - }; - }); - - test('should return DSC that was provided during transaction creation, if it was provided', () => { - const transaction = new Transaction( - { - name: 'tx', - metadata: { dynamicSamplingContext: { environment: 'myEnv' } }, - }, - hub, - ); - - const dynamicSamplingContext = transaction.getDynamicSamplingContext(); - - expect(dynamicSamplingContext).toStrictEqual({ environment: 'myEnv' }); - }); - - test('should return new DSC, if no DSC was provided during transaction creation', () => { - const transaction = new Transaction({ - name: 'tx', - metadata: { - sampleRate: 0.56, - }, - sampled: true, - }); - - const getOptionsSpy = jest.spyOn(hub.getClient()!, 'getOptions'); - - const dynamicSamplingContext = transaction.getDynamicSamplingContext(); - - expect(getOptionsSpy).toHaveBeenCalledTimes(1); - expect(dynamicSamplingContext).toStrictEqual({ - release: '1.0.1', - environment: 'production', - sampled: 'true', - sample_rate: '0.56', - trace_id: expect.any(String), - transaction: 'tx', - }); - }); - - describe('Including transaction name in DSC', () => { - test('is not included if transaction source is url', () => { - const transaction = new Transaction( - { - name: 'tx', - metadata: { - source: 'url', - }, - }, - hub, - ); - - const dsc = transaction.getDynamicSamplingContext()!; - expect(dsc.transaction).toBeUndefined(); - }); - - test.each([ - ['is included if transaction source is paremeterized route/url', 'route'], - ['is included if transaction source is a custom name', 'custom'], - ])('%s', (_: string, source) => { - const transaction = new Transaction( - { - name: 'tx', - metadata: { - ...(source && { source: source as TransactionSource }), - }, - }, - hub, - ); - - const dsc = transaction.getDynamicSamplingContext()!; - - expect(dsc.transaction).toEqual('tx'); - }); - }); - }); - - describe('Transaction source', () => { - test('is included when transaction metadata is set', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test', sampled: true }); - transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'url'); - expect(spy).toHaveBeenCalledTimes(0); - - transaction.end(); - expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenLastCalledWith( - expect.objectContaining({ - transaction_info: { - source: 'url', - }, - }), - ); - }); - }); -}); diff --git a/packages/tracing/test/testutils.ts b/packages/tracing/test/testutils.ts deleted file mode 100644 index 5ce79099d38f..000000000000 --- a/packages/tracing/test/testutils.ts +++ /dev/null @@ -1,100 +0,0 @@ -import { createTransport } from '@sentry/browser'; -import type { Client, ClientOptions } from '@sentry/types'; -import { GLOBAL_OBJ, parseSemver, resolvedSyncPromise } from '@sentry/utils'; -import { JSDOM } from 'jsdom'; - -/** - * Injects DOM properties into node global object. - * - * Useful for running tests where some of the tested code is isomorphic (apply to both node and browser). - * Note that not all properties from the browser `window` object are available. - * - * @param properties The names of the properties to add - */ -export function addDOMPropertiesToGlobal(properties: string[]): void { - // we have to add things into the real global object - // because there are modules which call GLOBAL_OBJ as they load, which is too early for jest to intervene - const { window } = new JSDOM('', { url: 'http://dogs.are.great/' }); - - properties.forEach(prop => { - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - (GLOBAL_OBJ as any)[prop] = window[prop]; - }); -} - -/** - * Returns the symbol with the given description being used as a key in the given object. - * - * In the case where there are multiple symbols in the object with the same description, it throws an error. - * - * @param obj The object whose symbol-type key you want - * @param description The symbol's descriptor - * @returns The first symbol found in the object with the given description, or undefined if not found. - */ -export function getSymbolObjectKeyByName(obj: Record, description: string): symbol | undefined { - const symbols = Object.getOwnPropertySymbols(obj); - - const matches = symbols.filter(sym => sym.toString() === `Symbol(${description})`); - - if (matches.length > 1) { - throw new Error(`More than one symbol key found with description '${description}'.`); - } - - return matches[0] || undefined; -} - -export const testOnlyIfNodeVersionAtLeast = (minVersion: number): jest.It => { - const currentNodeVersion = process.env.NODE_VERSION; - - try { - if (Number(currentNodeVersion?.split('.')[0]) < minVersion) { - return it.skip; - } - } catch (oO) { - // we can't tell, so err on the side of running the test - } - - return it; -}; - -/** - * Returns`describe` or `describe.skip` depending on allowed major versions of Node. - * - * @param {{ min?: number; max?: number }} allowedVersion - * @return {*} {jest.Describe} - */ -export const conditionalTest = (allowedVersion: { min?: number; max?: number }): jest.Describe => { - const NODE_VERSION = parseSemver(process.versions.node).major; - if (!NODE_VERSION) { - return describe.skip; - } - - return NODE_VERSION < (allowedVersion.min || -Infinity) || NODE_VERSION > (allowedVersion.max || Infinity) - ? describe.skip - : describe; -}; - -export function getDefaultBrowserClientOptions(options: Partial = {}): ClientOptions { - return { - integrations: [], - transport: () => createTransport({ recordDroppedEvent: () => undefined }, _ => resolvedSyncPromise({})), - stackParser: () => [], - ...options, - }; -} - -export function getTestClient(options: Partial): Client { - class TestClient { - _options: Partial; - - constructor(options: Partial) { - this._options = options; - } - - getOptions(): Partial { - return this._options; - } - } - - return new TestClient(options) as unknown as Client; -} diff --git a/packages/tracing/test/transaction.test.ts b/packages/tracing/test/transaction.test.ts deleted file mode 100644 index f9e950dd9cb9..000000000000 --- a/packages/tracing/test/transaction.test.ts +++ /dev/null @@ -1,214 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -import { BrowserClient, Hub } from '@sentry/browser'; -import { - SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, - SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, -} from '@sentry/core'; - -import { Transaction, addExtensionMethods } from '../src'; -import { getDefaultBrowserClientOptions } from './testutils'; - -describe('`Transaction` class', () => { - beforeAll(() => { - addExtensionMethods(); - }); - - describe('transaction name source', () => { - it('sets source in constructor if provided', () => { - const transaction = new Transaction({ name: 'dogpark', metadata: { source: 'route' } }); - - expect(transaction.name).toEqual('dogpark'); - expect(transaction.metadata.source).toEqual('route'); - }); - - it("sets source to be `'custom'` in constructor if not provided", () => { - const transaction = new Transaction({ name: 'dogpark' }); - - expect(transaction.name).toEqual('dogpark'); - expect(transaction.metadata.source).toBe('custom'); - }); - - it("sets source to `'custom'` when assigning to `name` property", () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.name = 'ballpit'; - - expect(transaction.name).toEqual('ballpit'); - expect(transaction.metadata.source).toEqual('custom'); - }); - - it('sets instrumenter to be `sentry` in constructor if not provided', () => { - const transaction = new Transaction({ name: 'dogpark' }); - - expect(transaction.instrumenter).toEqual('sentry'); - }); - - it('allows to set instrumenter', () => { - const transaction = new Transaction({ name: 'dogpark', instrumenter: 'otel' }); - - expect(transaction.instrumenter).toEqual('otel'); - }); - - describe('`setName` method', () => { - it("sets source to `'custom'` if no source provided", () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setName('ballpit'); - - expect(transaction.name).toEqual('ballpit'); - expect(transaction.metadata.source).toEqual('custom'); - }); - - it('uses given `source` value', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setName('ballpit', 'route'); - - expect(transaction.name).toEqual('ballpit'); - expect(transaction.metadata.source).toEqual('route'); - }); - }); - - describe('`updateName` method', () => { - it('does not change the source', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route'); - transaction.updateName('ballpit'); - - expect(transaction.name).toEqual('ballpit'); - expect(transaction.metadata.source).toEqual('route'); - }); - }); - }); - - describe('setContext', () => { - it('sets context', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setContext('foo', { - key: 'val', - key2: 'val2', - }); - - // @ts-expect-error accessing private property - expect(transaction._contexts).toEqual({ - foo: { - key: 'val', - key2: 'val2', - }, - }); - }); - - it('overwrites context', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setContext('foo', { - key: 'val', - key2: 'val2', - }); - transaction.setContext('foo', { - key3: 'val3', - }); - - // @ts-expect-error accessing private property - expect(transaction._contexts).toEqual({ - foo: { - key3: 'val3', - }, - }); - }); - - it('merges context', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setContext('foo', { - key: 'val', - key2: 'val2', - }); - transaction.setContext('bar', { - anotherKey: 'anotherVal', - }); - - // @ts-expect-error accessing private property - expect(transaction._contexts).toEqual({ - foo: { - key: 'val', - key2: 'val2', - }, - bar: { - anotherKey: 'anotherVal', - }, - }); - }); - - it('deletes context', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setContext('foo', { - key: 'val', - key2: 'val2', - }); - transaction.setContext('foo', null); - - // @ts-expect-error accessing private property - expect(transaction._contexts).toEqual({}); - }); - - it('sets contexts on the event', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const client = new BrowserClient(options); - const hub = new Hub(client); - - jest.spyOn(hub, 'captureEvent'); - - const transaction = hub.startTransaction({ name: 'dogpark' }); - transaction.setContext('foo', { key: 'val' }); - transaction.end(); - - // eslint-disable-next-line @typescript-eslint/unbound-method - expect(hub.captureEvent).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/unbound-method - expect(hub.captureEvent).toHaveBeenLastCalledWith( - expect.objectContaining({ - contexts: { - foo: { key: 'val' }, - trace: { - data: { - [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', - }, - span_id: transaction.spanId, - trace_id: transaction.traceId, - origin: 'manual', - }, - }, - }), - ); - }); - - it('does not override trace context', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const client = new BrowserClient(options); - const hub = new Hub(client); - - jest.spyOn(hub, 'captureEvent'); - - const transaction = hub.startTransaction({ name: 'dogpark' }); - transaction.setContext('trace', { key: 'val' }); - transaction.end(); - - // eslint-disable-next-line @typescript-eslint/unbound-method - expect(hub.captureEvent).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/unbound-method - expect(hub.captureEvent).toHaveBeenLastCalledWith( - expect.objectContaining({ - contexts: { - trace: { - data: { - [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', - }, - span_id: transaction.spanId, - trace_id: transaction.traceId, - origin: 'manual', - }, - }, - }), - ); - }); - }); -}); diff --git a/packages/tracing/test/utils.test.ts b/packages/tracing/test/utils.test.ts deleted file mode 100644 index e7b582ab94be..000000000000 --- a/packages/tracing/test/utils.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -import { hasTracingEnabled } from '../src'; - -describe('hasTracingEnabled (deprecated)', () => { - const tracesSampler = () => 1; - const tracesSampleRate = 1; - it.each([ - ['No options', undefined, false], - ['No tracesSampler or tracesSampleRate or enableTracing', {}, false], - ['With tracesSampler', { tracesSampler }, true], - ['With tracesSampleRate', { tracesSampleRate }, true], - ['With enableTracing=true', { enableTracing: true }, true], - ['With enableTracing=false', { enableTracing: false }, false], - ['With tracesSampler && enableTracing=false', { tracesSampler, enableTracing: false }, true], - ['With tracesSampleRate && enableTracing=false', { tracesSampler, enableTracing: false }, true], - ['With tracesSampler and tracesSampleRate', { tracesSampler, tracesSampleRate }, true], - [ - 'With tracesSampler and tracesSampleRate and enableTracing=true', - { tracesSampler, tracesSampleRate, enableTracing: true }, - true, - ], - [ - 'With tracesSampler and tracesSampleRate and enableTracing=false', - { tracesSampler, tracesSampleRate, enableTracing: false }, - true, - ], - ])( - '%s', - // eslint-disable-next-line deprecation/deprecation - (_: string, input: Parameters[0], output: ReturnType) => { - // eslint-disable-next-line deprecation/deprecation - expect(hasTracingEnabled(input)).toBe(output); - }, - ); -}); diff --git a/packages/tracing/tsconfig.json b/packages/tracing/tsconfig.json deleted file mode 100644 index bf45a09f2d71..000000000000 --- a/packages/tracing/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - - "include": ["src/**/*"], - - "compilerOptions": { - // package-specific options - } -} diff --git a/packages/tracing/tsconfig.test.json b/packages/tracing/tsconfig.test.json deleted file mode 100644 index 87f6afa06b86..000000000000 --- a/packages/tracing/tsconfig.test.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "include": ["test/**/*"], - - "compilerOptions": { - // should include all types from `./tsconfig.json` plus types for all test frameworks used - "types": ["node", "jest"] - - // other package-specific, test-specific options - } -} diff --git a/packages/tracing/tsconfig.types.json b/packages/tracing/tsconfig.types.json deleted file mode 100644 index 374fd9bc9364..000000000000 --- a/packages/tracing/tsconfig.types.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "emitDeclarationOnly": true, - "outDir": "build/npm/types" - } -} diff --git a/packages/types/src/span.ts b/packages/types/src/span.ts index 6aa6ea1113f6..6d305330cbd9 100644 --- a/packages/types/src/span.ts +++ b/packages/types/src/span.ts @@ -118,7 +118,7 @@ export interface SpanContext { /** * Completion status of the Span. - * See: {@sentry/tracing SpanStatus} for possible values + * See: {SpanStatusType} for possible values */ status?: string; @@ -267,7 +267,7 @@ export interface Span extends Omit { /** * Completion status of the Span. * - * See: {@sentry/tracing SpanStatus} for possible values + * See: {SpanStatusType} for possible values * * @deprecated Use `.setStatus` to set or update and `spanToJSON()` to read the status. */ @@ -333,7 +333,7 @@ export interface Span extends Omit { /** * Sets the status attribute on the current span - * See: {@sentry/tracing SpanStatus} for possible values + * See: {@sentry/core SpanStatusType} for possible values * @param status http code used to set the status */ setStatus(status: string): this; diff --git a/yarn.lock b/yarn.lock index 56b525f02a77..30c9de7464b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5575,6 +5575,15 @@ fflate "^0.4.4" mitt "^3.0.0" +"@sentry-internal/tracing@7.100.1": + version "7.100.1" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.100.1.tgz#4329492e50c390567197a4acbf7e3672b1db7820" + integrity sha512-+u9RRf5eL3StiyiRyAHZmdkAR7GTSGx4Mt4Lmi5NEtCcWlTGZ1QgW2r8ZbhouVmTiJkjhQgYCyej3cojtazeJg== + dependencies: + "@sentry/core" "7.100.1" + "@sentry/types" "7.100.1" + "@sentry/utils" "7.100.1" + "@sentry-internal/tracing@7.93.0": version "7.93.0" resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.93.0.tgz#8cee8b610695d828af75edd2929b64b7caf0385d" @@ -5678,6 +5687,14 @@ "@sentry/cli-win32-i686" "2.28.5" "@sentry/cli-win32-x64" "2.28.5" +"@sentry/core@7.100.1": + version "7.100.1" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.100.1.tgz#7b8e101a931af8e8b3b2449534749f882772df4f" + integrity sha512-f+ItUge/o9AjlveQq0ZUbQauKlPH1FIJbC1TRaYLJ4KNfOdrsh8yZ29RmWv0cFJ/e+FGTr603gWpRPObF5rM8Q== + dependencies: + "@sentry/types" "7.100.1" + "@sentry/utils" "7.100.1" + "@sentry/core@7.93.0": version "7.93.0" resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.93.0.tgz#50a14bf305130dfef51810e4c97fcba4972a57ef" @@ -5697,11 +5714,30 @@ "@sentry/utils" "7.93.0" https-proxy-agent "^5.0.0" +"@sentry/tracing@^7.19.0": + version "7.100.1" + resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-7.100.1.tgz#d40fb7099219d58bda5a5e5740178cb1808ac4d0" + integrity sha512-cmm2yz0qvOcW0RPegCn88X5nwbJdLx3w+Wl8319Kzkivc200e2tXQiDNwJ8kQdUvFsJg7Jz3G+hfZoy3ejtH7Q== + dependencies: + "@sentry-internal/tracing" "7.100.1" + +"@sentry/types@7.100.1": + version "7.100.1" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.100.1.tgz#1349b77269cecf4e80c087842575bd1a001e9995" + integrity sha512-fLM+LedHuKzOd8IhXBqaQuym+AA519MGjeczBa5kGakes/BbAsUMwsNfjsKQedp7Kh44RgYF99jwoRPK2oDrXw== + "@sentry/types@7.93.0": version "7.93.0" resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.93.0.tgz#d76d26259b40cd0688e1d634462fbff31476c1ec" integrity sha512-UnzUccNakhFRA/esWBWP+0v7cjNg+RilFBQC03Mv9OEMaZaS29zSbcOGtRzuFOXXLBdbr44BWADqpz3VW0XaNw== +"@sentry/utils@7.100.1": + version "7.100.1" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.100.1.tgz#6e26f3b06b1e485a2180f464ab3374ecb8d5e407" + integrity sha512-Ve6dXr1o6xiBe3VCoJgiutmBKrugryI65EZAbYto5XI+t+PjiLLf9wXtEMF24ZrwImo4Lv3E9Uqza+fWkEbw6A== + dependencies: + "@sentry/types" "7.100.1" + "@sentry/utils@7.93.0": version "7.93.0" resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.93.0.tgz#36225038661fe977baf01e4695ef84794d591e45" From a711e6cbcbb569643edb127717b456874a2f7581 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 21 Feb 2024 15:55:45 -0500 Subject: [PATCH 02/14] span clean up --- packages/core/test/lib/tracing/span.test.ts | 42 ++------------------- 1 file changed, 4 insertions(+), 38 deletions(-) diff --git a/packages/core/test/lib/tracing/span.test.ts b/packages/core/test/lib/tracing/span.test.ts index 199ceca0615c..353636846596 100644 --- a/packages/core/test/lib/tracing/span.test.ts +++ b/packages/core/test/lib/tracing/span.test.ts @@ -86,40 +86,6 @@ describe('span', () => { expect(span.tags['http.status_code']).toBe('404'); expect(span.data['http.response.status_code']).toBe(404); }); - - // TODO (v8): Remove - test('isSuccess', () => { - const span = new SentrySpan({}); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(200); - expect(span.isSuccess()).toBe(true); - expect(spanToJSON(span).status).toBe('ok'); - span.setStatus('permission_denied'); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(0); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(-1); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(99); - expect(span.isSuccess()).toBe(false); - expect(spanToJSON(span).status).not.toBe('ok'); - span.setHttpStatus(100); - expect(span.isSuccess()).toBe(true); - expect(spanToJSON(span).status).toBe('ok'); - }); - }); - - describe('toTraceparent', () => { - test('simple', () => { - expect(new SentrySpan().toTraceparent()).toMatch(TRACEPARENT_REGEXP); - }); - test('with sample', () => { - expect(new SentrySpan({ sampled: true }).toTraceparent()).toMatch(TRACEPARENT_REGEXP); - }); }); describe('toJSON', () => { @@ -278,8 +244,8 @@ describe('span', () => { expect(span.spanContext().traceId).toBe('c'); expect(span.spanContext().spanId).toBe('d'); expect(span.sampled).toBe(true); - expect(span.description).toBe(undefined); - expect(span.op).toBe(undefined); + expect(spanToJSON(span).description).toBe(undefined); + expect(spanToJSON(span).op).toBe(undefined); expect(span.tags).toStrictEqual({}); }); @@ -315,9 +281,9 @@ describe('span', () => { expect(span.spanContext().traceId).toBe('a'); expect(span.spanContext().spanId).toBe('b'); - expect(span.description).toBe('new'); + expect(spanToJSON(span).description).toBe('new'); expect(spanToJSON(span).timestamp).toBe(1); - expect(span.op).toBe('new-op'); + expect(spanToJSON(span).op).toBe('new-op'); expect(span.sampled).toBe(true); expect(span.tags).toStrictEqual({ tag1: 'bye' }); expect(span.data).toStrictEqual({ From 86f2d6c05faa93e8941c3c07cd9a8df3714f6e54 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Wed, 21 Feb 2024 16:26:40 -0500 Subject: [PATCH 03/14] accidently brought back some files --- .../startTransaction/basic-usage/scenario.ts | 12 ----- .../with-nested-spans/scenario.ts | 44 ----------------- .../httpIntegration/spansDisabled/scenario.ts | 18 ------- .../scenario.ts | 17 ------- .../suites/tracing/apollo-graphql/scenario.ts | 44 ----------------- .../auto-instrument/mongodb/scenario.ts | 46 ------------------ .../tracing/auto-instrument/mysql/scenario.ts | 35 -------------- .../tracing/auto-instrument/pg/scenario.ts | 24 ---------- .../suites/tracing/prisma-orm/scenario.ts | 48 ------------------- 9 files changed, 288 deletions(-) delete mode 100644 dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts delete mode 100644 dev-packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts delete mode 100644 dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spansDisabled/scenario.ts delete mode 100644 dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargetsDisabled/scenario.ts delete mode 100644 dev-packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts delete mode 100644 dev-packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts delete mode 100644 dev-packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts delete mode 100644 dev-packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts delete mode 100644 dev-packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts diff --git a/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts deleted file mode 100644 index 436bbfc9ba37..000000000000 --- a/dev-packages/node-integration-tests/suites/public-api/startTransaction/basic-usage/scenario.ts +++ /dev/null @@ -1,12 +0,0 @@ -import * as Sentry from '@sentry/node'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - tracesSampleRate: 1.0, -}); - -// eslint-disable-next-line deprecation/deprecation -const transaction = Sentry.startTransaction({ name: 'test_transaction_1' }); - -transaction.end(); diff --git a/dev-packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts deleted file mode 100644 index 6e508de02fb4..000000000000 --- a/dev-packages/node-integration-tests/suites/public-api/startTransaction/with-nested-spans/scenario.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as Sentry from '@sentry/node'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - tracesSampleRate: 1.0, -}); - -// eslint-disable-next-line deprecation/deprecation -const transaction = Sentry.startTransaction({ name: 'test_transaction_1' }); -// eslint-disable-next-line deprecation/deprecation -const span_1 = transaction.startChild({ - op: 'span_1', - data: { - foo: 'bar', - baz: [1, 2, 3], - }, -}); -for (let i = 0; i < 2000; i++); - -// span_1 finishes -span_1.end(); - -// span_2 doesn't finish -// eslint-disable-next-line deprecation/deprecation -transaction.startChild({ op: 'span_2' }); -for (let i = 0; i < 4000; i++); - -// eslint-disable-next-line deprecation/deprecation -const span_3 = transaction.startChild({ op: 'span_3' }); -for (let i = 0; i < 4000; i++); - -// span_4 is the child of span_3 but doesn't finish. -// eslint-disable-next-line deprecation/deprecation -span_3.startChild({ op: 'span_4', data: { qux: 'quux' } }); - -// span_5 is another child of span_3 but finishes. -// eslint-disable-next-line deprecation/deprecation -span_3.startChild({ op: 'span_5' }).end(); - -// span_3 also finishes -span_3.end(); - -transaction.end(); diff --git a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spansDisabled/scenario.ts b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spansDisabled/scenario.ts deleted file mode 100644 index 29e6bfdbc5a3..000000000000 --- a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/spansDisabled/scenario.ts +++ /dev/null @@ -1,18 +0,0 @@ -import * as http from 'http'; -import * as Sentry from '@sentry/node'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - tracesSampleRate: 1.0, - integrations: [Sentry.httpIntegration({ tracing: false })], -}); - -// eslint-disable-next-line @typescript-eslint/no-floating-promises -Sentry.startSpan({ name: 'test_transaction' }, async () => { - http.get('http://match-this-url.com/api/v0'); - http.get('http://match-this-url.com/api/v1'); - - // Give it a tick to resolve... - await new Promise(resolve => setTimeout(resolve, 100)); -}); diff --git a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargetsDisabled/scenario.ts b/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargetsDisabled/scenario.ts deleted file mode 100644 index eade81b4febc..000000000000 --- a/dev-packages/node-integration-tests/suites/tracing-new/httpIntegration/tracePropagationTargetsDisabled/scenario.ts +++ /dev/null @@ -1,17 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-unused-vars -import * as http from 'http'; -import * as Sentry from '@sentry/node'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - tracePropagationTargets: [/\/v0/, 'v1'], - integrations: [Sentry.httpIntegration({})], -}); - -Sentry.startSpan({ name: 'test_transaction' }, () => { - http.get('http://match-this-url.com/api/v0'); - http.get('http://match-this-url.com/api/v1'); - http.get('http://dont-match-this-url.com/api/v2'); - http.get('http://dont-match-this-url.com/api/v3'); -}); diff --git a/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts deleted file mode 100644 index 1584274bce7d..000000000000 --- a/dev-packages/node-integration-tests/suites/tracing/apollo-graphql/scenario.ts +++ /dev/null @@ -1,44 +0,0 @@ -import * as Sentry from '@sentry/node'; -import { ApolloServer, gql } from 'apollo-server'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - tracesSampleRate: 1.0, - integrations: [new Sentry.Integrations.GraphQL(), new Sentry.Integrations.Apollo()], -}); - -const typeDefs = gql` - type Query { - hello: String - } -`; - -const resolvers = { - Query: { - hello: () => { - return 'Hello world!'; - }, - }, -}; - -const server = new ApolloServer({ - typeDefs, - resolvers, -}); - -// eslint-disable-next-line deprecation/deprecation -const transaction = Sentry.startTransaction({ name: 'test_transaction', op: 'transaction' }); - -// eslint-disable-next-line deprecation/deprecation -Sentry.getCurrentScope().setSpan(transaction); - -// eslint-disable-next-line @typescript-eslint/no-floating-promises -(async () => { - // Ref: https://www.apollographql.com/docs/apollo-server/testing/testing/#testing-using-executeoperation - await server.executeOperation({ - query: '{hello}', - }); - - transaction.end(); -})(); diff --git a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts deleted file mode 100644 index 549f36504761..000000000000 --- a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mongodb/scenario.ts +++ /dev/null @@ -1,46 +0,0 @@ -import * as Sentry from '@sentry/node'; -import { MongoClient } from 'mongodb'; - -// suppress logging of the mongo download -global.console.log = () => null; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - tracesSampleRate: 1.0, -}); - -const client = new MongoClient(process.env.MONGO_URL || '', { - useUnifiedTopology: true, -}); - -async function run(): Promise { - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.startTransaction({ - name: 'Test Transaction', - op: 'transaction', - }); - - // eslint-disable-next-line deprecation/deprecation - Sentry.getCurrentScope().setSpan(transaction); - - try { - await client.connect(); - - const database = client.db('admin'); - const collection = database.collection('movies'); - - await collection.insertOne({ title: 'Rick and Morty' }); - await collection.findOne({ title: 'Back to the Future' }); - await collection.updateOne({ title: 'Back to the Future' }, { $set: { title: 'South Park' } }); - await collection.findOne({ title: 'South Park' }); - - await collection.find({ title: 'South Park' }).toArray(); - } finally { - if (transaction) transaction.end(); - await client.close(); - } -} - -// eslint-disable-next-line @typescript-eslint/no-floating-promises -run(); diff --git a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts deleted file mode 100644 index ae69aad2f2c0..000000000000 --- a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/mysql/scenario.ts +++ /dev/null @@ -1,35 +0,0 @@ -import * as Sentry from '@sentry/node'; -import mysql from 'mysql'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - tracesSampleRate: 1.0, -}); - -const connection = mysql.createConnection({ - user: 'root', - password: 'docker', -}); - -connection.connect(function (err: unknown) { - if (err) { - return; - } -}); - -// eslint-disable-next-line deprecation/deprecation -const transaction = Sentry.startTransaction({ - op: 'transaction', - name: 'Test Transaction', -}); - -// eslint-disable-next-line deprecation/deprecation -Sentry.getCurrentScope().setSpan(transaction); - -connection.query('SELECT 1 + 1 AS solution', function () { - connection.query('SELECT NOW()', ['1', '2'], () => { - if (transaction) transaction.end(); - connection.end(); - }); -}); diff --git a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts deleted file mode 100644 index 948564a952d0..000000000000 --- a/dev-packages/node-integration-tests/suites/tracing/auto-instrument/pg/scenario.ts +++ /dev/null @@ -1,24 +0,0 @@ -import * as Sentry from '@sentry/node'; -import pg from 'pg'; - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - tracesSampleRate: 1.0, -}); - -// eslint-disable-next-line deprecation/deprecation -const transaction = Sentry.startTransaction({ - op: 'transaction', - name: 'Test Transaction', -}); - -// eslint-disable-next-line deprecation/deprecation -Sentry.getCurrentScope().setSpan(transaction); - -const client = new pg.Client(); -client.query('SELECT * FROM foo where bar ilike "baz%"', ['a', 'b'], () => - client.query('SELECT * FROM bazz', () => { - client.query('SELECT NOW()', () => transaction.end()); - }), -); diff --git a/dev-packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts b/dev-packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts deleted file mode 100644 index 6191dbf31d75..000000000000 --- a/dev-packages/node-integration-tests/suites/tracing/prisma-orm/scenario.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { randomBytes } from 'crypto'; -/* eslint-disable @typescript-eslint/no-unsafe-member-access */ -import { PrismaClient } from '@prisma/client'; -import * as Sentry from '@sentry/node'; - -const client = new PrismaClient(); - -Sentry.init({ - dsn: 'https://public@dsn.ingest.sentry.io/1337', - release: '1.0', - tracesSampleRate: 1.0, - integrations: [new Sentry.Integrations.Prisma({ client })], -}); - -async function run(): Promise { - // eslint-disable-next-line deprecation/deprecation - const transaction = Sentry.startTransaction({ - name: 'Test Transaction', - op: 'transaction', - }); - - // eslint-disable-next-line deprecation/deprecation - Sentry.getCurrentScope().setSpan(transaction); - - try { - await client.user.create({ - data: { - name: 'Tilda', - email: `tilda_${randomBytes(4).toString('hex')}@sentry.io`, - }, - }); - - await client.user.findMany(); - - await client.user.deleteMany({ - where: { - email: { - contains: 'sentry.io', - }, - }, - }); - } finally { - if (transaction) transaction.end(); - } -} - -// eslint-disable-next-line @typescript-eslint/no-floating-promises -run(); From 8e15a4d80d9c5f55d8bc723f70ca1ae8ba36ef4a Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 10:37:22 -0500 Subject: [PATCH 04/14] delete fr --- packages/tracing/src/index.ts | 240 ------- .../test/integrations/apollo-nestjs.test.ts | 127 ---- .../tracing/test/integrations/apollo.test.ts | 127 ---- .../tracing/test/integrations/graphql.test.ts | 79 --- .../test/integrations/node/mongo.test.ts | 161 ----- .../test/integrations/node/postgres.test.ts | 154 ---- packages/tracing/test/span.test.ts | 656 ------------------ packages/tracing/test/transaction.test.ts | 210 ------ 8 files changed, 1754 deletions(-) delete mode 100644 packages/tracing/src/index.ts delete mode 100644 packages/tracing/test/integrations/apollo-nestjs.test.ts delete mode 100644 packages/tracing/test/integrations/apollo.test.ts delete mode 100644 packages/tracing/test/integrations/graphql.test.ts delete mode 100644 packages/tracing/test/integrations/node/mongo.test.ts delete mode 100644 packages/tracing/test/integrations/node/postgres.test.ts delete mode 100644 packages/tracing/test/span.test.ts delete mode 100644 packages/tracing/test/transaction.test.ts diff --git a/packages/tracing/src/index.ts b/packages/tracing/src/index.ts deleted file mode 100644 index 2887963e1149..000000000000 --- a/packages/tracing/src/index.ts +++ /dev/null @@ -1,240 +0,0 @@ -import type { - RequestInstrumentationOptions as RequestInstrumentationOptionsT, - SpanStatusType as SpanStatusTypeT, -} from '@sentry-internal/tracing'; -import { - Apollo, - BROWSER_TRACING_INTEGRATION_ID as BROWSER_TRACING_INTEGRATION_ID_T, - BrowserTracing as BrowserTracingT, - Express, - GraphQL, - IdleTransaction as IdleTransactionT, - Mongo, - Mysql, - Postgres, - Prisma, - SpanStatus as SpanStatusT, - TRACEPARENT_REGEXP as TRACEPARENT_REGEXP_T, - Transaction as TransactionT, - addExtensionMethods as addExtensionMethodsT, - defaultRequestInstrumentationOptions as defaultRequestInstrumentationOptionsT, - getActiveTransaction as getActiveTransactionT, - hasTracingEnabled as hasTracingEnabledT, - instrumentOutgoingRequests as instrumentOutgoingRequestsT, - startIdleTransaction as startIdleTransactionT, - stripUrlQueryAndFragment as stripUrlQueryAndFragmentT, -} from '@sentry-internal/tracing'; - -// BrowserTracing is already exported as part of `Integrations` below (and for the moment will remain so for -// backwards compatibility), but that interferes with treeshaking, so we also export it separately -// here. -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `BrowserTracing` can be imported from `@sentry/browser` or your framework SDK - * - * import { BrowserTracing } from '@sentry/browser'; - * new BrowserTracing() - */ -// eslint-disable-next-line deprecation/deprecation -export const BrowserTracing = BrowserTracingT; - -// BrowserTracing is already exported as part of `Integrations` below (and for the moment will remain so for -// backwards compatibility), but that interferes with treeshaking, so we also export it separately -// here. -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `BrowserTracing` can be imported from `@sentry/browser` or your framework SDK - * - * import { BrowserTracing } from '@sentry/browser'; - * new BrowserTracing() - */ -// eslint-disable-next-line deprecation/deprecation -export type BrowserTracing = BrowserTracingT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const addExtensionMethods = addExtensionMethodsT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `getActiveTransaction` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -// eslint-disable-next-line deprecation/deprecation -export const getActiveTransaction = getActiveTransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `SpanStatusType` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -export type SpanStatusType = SpanStatusTypeT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `Transaction` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -export const Transaction = TransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `Transaction` can be imported from `@sentry/node`, `@sentry/browser`, or your framework SDK - */ -export type Transaction = TransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const BROWSER_TRACING_INTEGRATION_ID = BROWSER_TRACING_INTEGRATION_ID_T; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `defaultRequestInstrumentationOptions` can be imported from `@sentry/browser`, or your framework SDK - */ -export const defaultRequestInstrumentationOptions = defaultRequestInstrumentationOptionsT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `hasTracingEnabled` can be imported from `@sentry/utils` - */ -export const hasTracingEnabled = hasTracingEnabledT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `stripUrlQueryAndFragment` can be imported from `@sentry/utils` - */ -export const stripUrlQueryAndFragment = stripUrlQueryAndFragmentT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * - * `TRACEPARENT_REGEXP` can be imported from `@sentry/utils` - */ -export const TRACEPARENT_REGEXP = TRACEPARENT_REGEXP_T; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const IdleTransaction = IdleTransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export type IdleTransaction = IdleTransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const instrumentOutgoingRequests = instrumentOutgoingRequestsT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export const startIdleTransaction = startIdleTransactionT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -// eslint-disable-next-line deprecation/deprecation -export const SpanStatus = SpanStatusT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -// eslint-disable-next-line deprecation/deprecation -export type SpanStatus = SpanStatusT; - -/** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - */ -export type RequestInstrumentationOptions = RequestInstrumentationOptionsT; - -export const Integrations = { - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `BrowserTracing` can be imported from `@sentry/browser` or your framework SDK - * - * import { BrowserTracing } from '@sentry/browser'; - * new BrowserTracing() - */ - // eslint-disable-next-line deprecation/deprecation - BrowserTracing: BrowserTracing, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Apollo` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Apollo({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Apollo: Apollo, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Express` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Express({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Express: Express, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `GraphQL` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.GraphQL({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - GraphQL: GraphQL, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Mongo` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Mongo({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Mongo: Mongo, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Mysql` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Mysql({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Mysql: Mysql, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Postgres` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Postgres({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Postgres: Postgres, - /** - * @deprecated `@sentry/tracing` has been deprecated and will be moved to to `@sentry/node`, `@sentry/browser`, or your framework SDK in the next major version. - * `Prisma` can be imported from `@sentry/node` - * - * import { Integrations } from '@sentry/node'; - * new Integrations.Prisma({ ... }) - */ - // eslint-disable-next-line deprecation/deprecation - Prisma: Prisma, -}; - -// Treeshakable guard to remove all code related to tracing -declare const __SENTRY_TRACING__: boolean; - -// Guard for tree -if (typeof __SENTRY_TRACING__ === 'undefined' || __SENTRY_TRACING__) { - // We are patching the global object with our hub extension methods - addExtensionMethodsT(); -} diff --git a/packages/tracing/test/integrations/apollo-nestjs.test.ts b/packages/tracing/test/integrations/apollo-nestjs.test.ts deleted file mode 100644 index dbb9a4841c9c..000000000000 --- a/packages/tracing/test/integrations/apollo-nestjs.test.ts +++ /dev/null @@ -1,127 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope, SentrySpan } from '@sentry/core'; -import type { Span } from '@sentry/types'; -import { logger } from '@sentry/utils'; - -import { Integrations } from '../../src'; -import { getTestClient } from '../testutils'; - -type ApolloResolverGroup = { - [key: string]: () => unknown; -}; - -type ApolloModelResolvers = { - [key: string]: ApolloResolverGroup; -}; - -class GraphQLFactory { - _resolvers: ApolloModelResolvers[]; - resolversExplorerService = { - explore: () => this._resolvers, - }; - constructor() { - this._resolvers = [ - { - Query: { - res_1(..._args: unknown[]) { - return 'foo'; - }, - }, - Mutation: { - res_2(..._args: unknown[]) { - return 'bar'; - }, - }, - }, - ]; - - this.mergeWithSchema(); - } - - public mergeWithSchema(..._args: unknown[]) { - return this.resolversExplorerService.explore(); - } -} - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockFactory = GraphQLFactory; - -// mock for @nestjs/graphql package -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule() { - return { - GraphQLFactory: mockFactory, - }; - }, - }; -}); - -describe('setupOnce', () => { - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - let GraphQLFactoryInstance: GraphQLFactory; - - beforeAll(() => { - new Integrations.Apollo({ - useNestjs: true, - }).setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - - GraphQLFactoryInstance = new GraphQLFactory(); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new SentrySpan(); - childSpan = parentSpan.startChild(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(scope, 'setSpan'); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it('should wrap a simple resolver', () => { - GraphQLFactoryInstance._resolvers[0]?.['Query']?.['res_1']?.(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - name: 'Query.res_1', - op: 'graphql.resolve', - origin: 'auto.graphql.apollo', - }); - expect(childSpan.end).toBeCalled(); - }); - - it('should wrap another simple resolver', () => { - GraphQLFactoryInstance._resolvers[0]?.['Mutation']?.['res_2']?.(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - name: 'Mutation.res_2', - op: 'graphql.resolve', - origin: 'auto.graphql.apollo', - }); - expect(childSpan.end).toBeCalled(); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.Apollo({ useNestjs: true }); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('Apollo Integration is skipped because of instrumenter configuration.'); - }); -}); diff --git a/packages/tracing/test/integrations/apollo.test.ts b/packages/tracing/test/integrations/apollo.test.ts deleted file mode 100644 index 305acdcee186..000000000000 --- a/packages/tracing/test/integrations/apollo.test.ts +++ /dev/null @@ -1,127 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope, SentrySpan } from '@sentry/core'; -import type { Span } from '@sentry/types'; -import { logger } from '@sentry/utils'; - -import { Integrations } from '../../src'; -import { getTestClient } from '../testutils'; - -type ApolloResolverGroup = { - [key: string]: () => any; -}; - -type ApolloModelResolvers = { - [key: string]: ApolloResolverGroup; -}; - -class ApolloServerBase { - config: { - resolvers: ApolloModelResolvers[]; - }; - - constructor() { - this.config = { - resolvers: [ - { - Query: { - res_1(..._args: unknown[]) { - return 'foo'; - }, - }, - Mutation: { - res_2(..._args: unknown[]) { - return 'bar'; - }, - }, - }, - ], - }; - - this.constructSchema(); - } - - public constructSchema(..._args: unknown[]) { - return null; - } -} - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockClient = ApolloServerBase; - -// mock for ApolloServer package -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule() { - return { - ApolloServerBase: mockClient, - }; - }, - }; -}); - -describe('setupOnce', () => { - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - let ApolloServer: ApolloServerBase; - - beforeAll(() => { - new Integrations.Apollo().setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - - ApolloServer = new ApolloServerBase(); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new SentrySpan(); - childSpan = parentSpan.startChild(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(scope, 'setSpan'); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it('should wrap a simple resolver', () => { - ApolloServer.config.resolvers[0]?.['Query']?.['res_1']?.(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - name: 'Query.res_1', - op: 'graphql.resolve', - origin: 'auto.graphql.apollo', - }); - expect(childSpan.end).toBeCalled(); - }); - - it('should wrap another simple resolver', () => { - ApolloServer.config.resolvers[0]?.['Mutation']?.['res_2']?.(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - name: 'Mutation.res_2', - op: 'graphql.resolve', - origin: 'auto.graphql.apollo', - }); - expect(childSpan.end).toBeCalled(); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.Apollo(); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('Apollo Integration is skipped because of instrumenter configuration.'); - }); -}); diff --git a/packages/tracing/test/integrations/graphql.test.ts b/packages/tracing/test/integrations/graphql.test.ts deleted file mode 100644 index 2b3c3aa7e307..000000000000 --- a/packages/tracing/test/integrations/graphql.test.ts +++ /dev/null @@ -1,79 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope, SentrySpan } from '@sentry/core'; -import type { Span } from '@sentry/types'; -import { logger } from '@sentry/utils'; - -import { Integrations } from '../../src'; -import { getTestClient } from '../testutils'; - -const GQLExecute = { - execute() { - return Promise.resolve(); - }, -}; - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockClient = GQLExecute; - -// mock for 'graphql/execution/execution.js' package -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule() { - return mockClient; - }, - }; -}); - -describe('setupOnce', () => { - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - - beforeAll(() => { - new Integrations.GraphQL().setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new SentrySpan(); - childSpan = parentSpan.startChild(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(scope, 'setSpan'); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it('should wrap execute method', async () => { - await GQLExecute.execute(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - name: 'execute', - op: 'graphql.execute', - origin: 'auto.graphql.graphql', - }); - expect(childSpan.end).toBeCalled(); - expect(scope.setSpan).toHaveBeenCalledTimes(2); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.GraphQL(); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('GraphQL Integration is skipped because of instrumenter configuration.'); - }); -}); diff --git a/packages/tracing/test/integrations/node/mongo.test.ts b/packages/tracing/test/integrations/node/mongo.test.ts deleted file mode 100644 index d6baafa71e7c..000000000000 --- a/packages/tracing/test/integrations/node/mongo.test.ts +++ /dev/null @@ -1,161 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope, SentrySpan } from '@sentry/core'; -import type { Span } from '@sentry/types'; -import { logger } from '@sentry/utils'; - -import { Integrations } from '../../../src'; -import { getTestClient } from '../../testutils'; - -class Collection { - public collectionName: string = 'mockedCollectionName'; - public dbName: string = 'mockedDbName'; - public namespace: string = 'mockedNamespace'; - - // Method that can have a callback as last argument, or return a promise otherwise. - public insertOne(_doc: unknown, _options: unknown, callback?: () => void) { - if (typeof callback === 'function') { - callback(); - return; - } - return Promise.resolve(); - } - // Method that has no callback as last argument, and doesnt return promise. - public initializeOrderedBulkOp() { - return {}; - } -} - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockCollection = Collection; - -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule() { - return { - Collection: mockCollection, - }; - }, - }; -}); - -describe('patchOperation()', () => { - const doc = { - name: 'PickleRick', - answer: 42, - }; - const collection: Collection = new Collection(); - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - let testClient = getTestClient({}); - - beforeAll(() => { - new Integrations.Mongo({ - operations: ['insertOne', 'initializeOrderedBulkOp'], - }).setupOnce( - () => undefined, - () => new Hub(testClient, scope), - ); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new SentrySpan(); - childSpan = parentSpan.startChild(); - testClient = getTestClient({}); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it('should wrap method accepting callback as the last argument', done => { - collection.insertOne(doc, {}, function () { - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - data: { - 'db.mongodb.collection': 'mockedCollectionName', - 'db.name': 'mockedDbName', - 'db.operation': 'insertOne', - 'db.system': 'mongodb', - }, - op: 'db', - origin: 'auto.db.mongo', - name: 'insertOne', - }); - expect(childSpan.end).toBeCalled(); - done(); - }) as void; - }); - - it('should wrap method accepting no callback as the last argument but returning promise', async () => { - await collection.insertOne(doc, {}); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - data: { - 'db.mongodb.collection': 'mockedCollectionName', - 'db.name': 'mockedDbName', - 'db.operation': 'insertOne', - 'db.system': 'mongodb', - }, - op: 'db', - origin: 'auto.db.mongo', - name: 'insertOne', - }); - expect(childSpan.end).toBeCalled(); - }); - - it('attaches mongodb operation spans if sendDefaultPii is enabled', async () => { - testClient.getOptions().sendDefaultPii = true; - await collection.insertOne(doc, {}); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - data: { - 'db.mongodb.collection': 'mockedCollectionName', - 'db.mongodb.doc': '{"name":"PickleRick","answer":42}', - 'db.name': 'mockedDbName', - 'db.operation': 'insertOne', - 'db.system': 'mongodb', - }, - op: 'db', - origin: 'auto.db.mongo', - name: 'insertOne', - }); - expect(childSpan.end).toBeCalled(); - }); - - it('should wrap method accepting no callback as the last argument and not returning promise', () => { - collection.initializeOrderedBulkOp(); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - data: { - 'db.mongodb.collection': 'mockedCollectionName', - 'db.name': 'mockedDbName', - 'db.operation': 'initializeOrderedBulkOp', - 'db.system': 'mongodb', - }, - op: 'db', - origin: 'auto.db.mongo', - name: 'initializeOrderedBulkOp', - }); - expect(childSpan.end).toBeCalled(); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.Mongo(); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('Mongo Integration is skipped because of instrumenter configuration.'); - }); -}); diff --git a/packages/tracing/test/integrations/node/postgres.test.ts b/packages/tracing/test/integrations/node/postgres.test.ts deleted file mode 100644 index 0608fbaf85ad..000000000000 --- a/packages/tracing/test/integrations/node/postgres.test.ts +++ /dev/null @@ -1,154 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -/* eslint-disable @typescript-eslint/unbound-method */ -import { Hub, Scope, SentrySpan } from '@sentry/core'; -import type { Span } from '@sentry/types'; -import { loadModule, logger } from '@sentry/utils'; -import pg from 'pg'; - -import { Integrations } from '../../../src'; -import { getTestClient } from '../../testutils'; - -class PgClient { - // https://node-postgres.com/api/client#clientquery - public query(_text: unknown, values: unknown, callback?: (err: unknown, result: unknown) => void) { - if (typeof callback === 'function') { - callback(null, null); - return; - } - - if (typeof values === 'function') { - values(); - return; - } - - return Promise.resolve(); - } -} - -// Jest mocks get hoisted. vars starting with `mock` are hoisted before imports. -/* eslint-disable no-var */ -var mockModule = { - Client: PgClient, - native: { - Client: PgClient, - }, -}; - -// mock for 'pg' / 'pg-native' package -jest.mock('@sentry/utils', () => { - const actual = jest.requireActual('@sentry/utils'); - return { - ...actual, - loadModule: jest.fn(() => mockModule), - }; -}); - -describe('setupOnce', () => { - beforeEach(() => { - jest.clearAllMocks(); - jest.resetAllMocks(); - }); - - ['pg', 'pg-native'].forEach(pgApi => { - const Client: PgClient = new PgClient(); - let scope = new Scope(); - let parentSpan: Span; - let childSpan: Span; - - beforeAll(() => { - (pgApi === 'pg' ? new Integrations.Postgres() : new Integrations.Postgres({ usePgNative: true })).setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - }); - - beforeEach(() => { - scope = new Scope(); - parentSpan = new SentrySpan(); - childSpan = parentSpan.startChild(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(parentSpan); - jest.spyOn(parentSpan, 'startChild').mockReturnValueOnce(childSpan); - jest.spyOn(childSpan, 'end'); - }); - - it(`should wrap ${pgApi}'s query method accepting callback as the last argument`, done => { - Client.query('SELECT NOW()', {}, function () { - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - name: 'SELECT NOW()', - op: 'db', - origin: 'auto.db.postgres', - data: { - 'db.system': 'postgresql', - }, - }); - expect(childSpan.end).toBeCalled(); - done(); - }) as void; - }); - - it(`should wrap ${pgApi}'s query method accepting callback as the second argument`, done => { - Client.query('SELECT NOW()', function () { - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - name: 'SELECT NOW()', - op: 'db', - origin: 'auto.db.postgres', - data: { - 'db.system': 'postgresql', - }, - }); - expect(childSpan.end).toBeCalled(); - done(); - }) as void; - }); - - it(`should wrap ${pgApi}'s query method accepting no callback as the last argument but returning promise`, async () => { - await Client.query('SELECT NOW()', null); - expect(scope.getSpan).toBeCalled(); - expect(parentSpan.startChild).toBeCalledWith({ - name: 'SELECT NOW()', - op: 'db', - origin: 'auto.db.postgres', - data: { - 'db.system': 'postgresql', - }, - }); - expect(childSpan.end).toBeCalled(); - }); - }); - - it("doesn't attach when using otel instrumenter", () => { - const loggerLogSpy = jest.spyOn(logger, 'log'); - - const client = getTestClient({ instrumenter: 'otel' }); - const hub = new Hub(client); - - const integration = new Integrations.Postgres(); - integration.setupOnce( - () => {}, - () => hub, - ); - - expect(loggerLogSpy).toBeCalledWith('Postgres Integration is skipped because of instrumenter configuration.'); - }); - - it('does not attempt resolution when module is passed directly', async () => { - const scope = new Scope(); - jest.spyOn(scope, 'getSpan').mockReturnValueOnce(new SentrySpan()); - - new Integrations.Postgres({ module: mockModule }).setupOnce( - () => undefined, - () => new Hub(undefined, scope), - ); - - await new PgClient().query('SELECT NOW()', null); - - expect(loadModule).not.toBeCalled(); - expect(scope.getSpan).toBeCalled(); - }); - - it('has valid module type', () => { - expect(() => new Integrations.Postgres({ module: pg })).not.toThrow(); - }); -}); diff --git a/packages/tracing/test/span.test.ts b/packages/tracing/test/span.test.ts deleted file mode 100644 index 3fc72e58e6d4..000000000000 --- a/packages/tracing/test/span.test.ts +++ /dev/null @@ -1,656 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -import { BrowserClient } from '@sentry/browser'; -import { - Hub, - SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - SentrySpan, - getClient, - getCurrentHub, - getCurrentScope, - getGlobalScope, - getIsolationScope, - setCurrentClient, - spanToJSON, -} from '@sentry/core'; -import type { BaseTransportOptions, ClientOptions } from '@sentry/types'; - -import { Transaction } from '../src'; -import { getDefaultBrowserClientOptions } from './testutils'; - -describe('SentrySpan', () => { - beforeEach(() => { - getGlobalScope().clear(); - getIsolationScope().clear(); - getCurrentScope().clear(); - - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const client = new BrowserClient(options); - setCurrentClient(client); - client.init(); - }); - - afterEach(() => { - jest.clearAllMocks(); - }); - - describe('new SentrySpan', () => { - test('simple', () => { - const span = new SentrySpan({ sampled: true }); - const span2 = span.startChild(); - expect((span2 as any).parentSpanId).toBe((span as any).spanId); - expect((span2 as any).traceId).toBe((span as any).traceId); - expect((span2 as any).sampled).toBe((span as any).sampled); - }); - - test('sets instrumenter to `sentry` if not specified in constructor', () => { - const span = new SentrySpan({}); - - expect(span.instrumenter).toBe('sentry'); - }); - - test('allows to set instrumenter in constructor', () => { - const span = new SentrySpan({ instrumenter: 'otel' }); - - expect(span.instrumenter).toBe('otel'); - }); - }); - - describe('new Transaction', () => { - test('simple', () => { - const transaction = new Transaction({ name: 'test', sampled: true }); - const span2 = transaction.startChild(); - expect((span2 as any).parentSpanId).toBe((transaction as any).spanId); - expect((span2 as any).traceId).toBe((transaction as any).traceId); - expect((span2 as any).sampled).toBe((transaction as any).sampled); - }); - - test('gets currentHub', () => { - const transaction = new Transaction({ name: 'test' }); - expect((transaction as any)._hub).toBeInstanceOf(Hub); - }); - - test('inherit span list', () => { - const transaction = new Transaction({ name: 'test', sampled: true }); - const span2 = transaction.startChild(); - const span3 = span2.startChild(); - span3.end(); - expect(transaction.spanRecorder).toBe((span2 as SentrySpan).spanRecorder); - expect(transaction.spanRecorder).toBe((span3 as SentrySpan).spanRecorder); - }); - }); - - describe('setters', () => { - test('setTag', () => { - const span = new SentrySpan({}); - expect(span.tags.foo).toBeUndefined(); - span.setTag('foo', 'bar'); - expect(span.tags.foo).toBe('bar'); - span.setTag('foo', 'baz'); - expect(span.tags.foo).toBe('baz'); - }); - - test('setData', () => { - const span = new SentrySpan({}); - expect(span.data.foo).toBeUndefined(); - span.setData('foo', null); - expect(span.data.foo).toBe(null); - span.setData('foo', 2); - expect(span.data.foo).toBe(2); - span.setData('foo', true); - expect(span.data.foo).toBe(true); - }); - - test('setName', () => { - const span = new SentrySpan({}); - expect(spanToJSON(span).description).toBeUndefined(); - span.updateName('foo'); - expect(spanToJSON(span).description).toBe('foo'); - }); - }); - - describe('status', () => { - test('setStatus', () => { - const span = new SentrySpan({}); - span.setStatus('permission_denied'); - expect((span.getTraceContext() as any).status).toBe('permission_denied'); - }); - - // TODO (v8): Remove - test('setHttpStatus', () => { - const span = new SentrySpan({}); - span.setHttpStatus(404); - expect((span.getTraceContext() as any).status).toBe('not_found'); - expect(span.tags['http.status_code']).toBe('404'); - expect(span.data['http.response.status_code']).toBe(404); - }); - }); - - describe('toJSON', () => { - test('simple', () => { - const span = JSON.parse( - JSON.stringify(new SentrySpan({ traceId: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', spanId: 'bbbbbbbbbbbbbbbb' })), - ); - expect(span).toHaveProperty('span_id', 'bbbbbbbbbbbbbbbb'); - expect(span).toHaveProperty('trace_id', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); - }); - - test('with parent', () => { - const spanA = new SentrySpan({ traceId: 'a', spanId: 'b' }) as any; - const spanB = new SentrySpan({ traceId: 'c', spanId: 'd', sampled: false, parentSpanId: spanA.spanId }); - const serialized = JSON.parse(JSON.stringify(spanB)); - expect(serialized).toHaveProperty('parent_span_id', 'b'); - expect(serialized).toHaveProperty('span_id', 'd'); - expect(serialized).toHaveProperty('trace_id', 'c'); - }); - - test('should drop all `undefined` values', () => { - const spanA = new SentrySpan({ traceId: 'a', spanId: 'b' }) as any; - const spanB = new SentrySpan({ - parentSpanId: spanA.spanId, - spanId: 'd', - traceId: 'c', - }); - const serialized = spanB.toJSON(); - expect(serialized).toStrictEqual({ - start_timestamp: expect.any(Number), - parent_span_id: 'b', - span_id: 'd', - trace_id: 'c', - origin: 'manual', - data: { - 'sentry.origin': 'manual', - }, - }); - }); - }); - - describe('finish', () => { - test('simple', () => { - const span = new SentrySpan({}); - expect(spanToJSON(span).timestamp).toBeUndefined(); - span.end(); - expect(spanToJSON(span).timestamp).toBeGreaterThan(1); - }); - - describe('hub.startTransaction', () => { - let hub: Hub; - - beforeEach(() => { - hub = getCurrentHub() as Hub; - }); - - test('finish a transaction', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(0); - expect(spy.mock.calls[0][0].timestamp).toBeTruthy(); - expect(spy.mock.calls[0][0].start_timestamp).toBeTruthy(); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test('finish a transaction + child span', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpan = transaction.startChild(); - childSpan.end(); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(1); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - // See https://github.com/getsentry/sentry-javascript/issues/3254 - test('finish a transaction + child span + sampled:true', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test', op: 'parent', sampled: true }); - const childSpan = transaction.startChild({ op: 'child' }); - childSpan.end(); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(1); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test("finish a child span shouldn't trigger captureEvent", () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpan = transaction.startChild(); - childSpan.end(); - expect(spy).not.toHaveBeenCalled(); - }); - - test("finish a span with another one on the scope shouldn't override contexts.trace", () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpanOne = transaction.startChild(); - childSpanOne.end(); - - hub.getScope().setSpan(childSpanOne); - - const spanTwo = transaction.startChild(); - spanTwo.end(); - transaction.end(); - - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(2); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test('no span recorder created if transaction.sampled is false', () => { - const options = getDefaultBrowserClientOptions({ - tracesSampleRate: 1, - }); - const _hub = new Hub(new BrowserClient(options)); - const spy = jest.spyOn(_hub as any, 'captureEvent') as any; - const transaction = _hub.startTransaction({ name: 'test', sampled: false }); - for (let i = 0; i < 10; i++) { - const child = transaction.startChild(); - child.end(); - } - transaction.end(); - expect((transaction as any).spanRecorder).toBeUndefined(); - expect(spy).not.toHaveBeenCalled(); - }); - - test('tree structure of spans should be correct when mixing it with span on scope', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - - const transaction = hub.startTransaction({ name: 'test' }); - const childSpanOne = transaction.startChild(); - - const childSpanTwo = childSpanOne.startChild(); - childSpanTwo.end(); - - childSpanOne.end(); - - hub.getScope().setSpan(transaction); - - const spanTwo = transaction.startChild({}); - spanTwo.end(); - transaction.end(); - - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(3); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - expect(childSpanOne.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); - expect(childSpanTwo.toJSON().parent_span_id).toEqual(childSpanOne.toJSON().span_id); - expect(spanTwo.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); - }); - }); - }); - - describe('end', () => { - test('simple', () => { - const span = new SentrySpan({}); - expect(spanToJSON(span).timestamp).toBeUndefined(); - span.end(); - expect(spanToJSON(span).timestamp).toBeGreaterThan(1); - }); - - test('with endTime in seconds', () => { - const span = new SentrySpan({}); - expect(spanToJSON(span).timestamp).toBeUndefined(); - const endTime = Date.now() / 1000; - span.end(endTime); - expect(spanToJSON(span).timestamp).toBe(endTime); - }); - - test('with endTime in milliseconds', () => { - const span = new SentrySpan({}); - expect(spanToJSON(span).timestamp).toBeUndefined(); - const endTime = Date.now(); - span.end(endTime); - expect(spanToJSON(span).timestamp).toBe(endTime / 1000); - }); - - describe('hub.startTransaction', () => { - let hub: Hub; - - beforeEach(() => { - hub = getCurrentHub() as Hub; - }); - - test('finish a transaction', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(0); - expect(spy.mock.calls[0][0].timestamp).toBeTruthy(); - expect(spy.mock.calls[0][0].start_timestamp).toBeTruthy(); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test('finish a transaction + child span', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpan = transaction.startChild(); - childSpan.end(); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(1); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - // See https://github.com/getsentry/sentry-javascript/issues/3254 - test('finish a transaction + child span + sampled:true', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test', op: 'parent', sampled: true }); - const childSpan = transaction.startChild({ op: 'child' }); - childSpan.end(); - transaction.end(); - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(1); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test("finish a child span shouldn't trigger captureEvent", () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpan = transaction.startChild(); - childSpan.end(); - expect(spy).not.toHaveBeenCalled(); - }); - - test("finish a span with another one on the scope shouldn't override contexts.trace", () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test' }); - const childSpanOne = transaction.startChild(); - childSpanOne.end(); - - hub.getScope().setSpan(childSpanOne); - - const spanTwo = transaction.startChild(); - spanTwo.end(); - transaction.end(); - - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(2); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - }); - - test('no span recorder created if transaction.sampled is false', () => { - const options = getDefaultBrowserClientOptions({ - tracesSampleRate: 1, - }); - const _hub = new Hub(new BrowserClient(options)); - const spy = jest.spyOn(_hub as any, 'captureEvent') as any; - const transaction = _hub.startTransaction({ name: 'test', sampled: false }); - for (let i = 0; i < 10; i++) { - const child = transaction.startChild(); - child.end(); - } - transaction.end(); - expect((transaction as any).spanRecorder).toBeUndefined(); - expect(spy).not.toHaveBeenCalled(); - }); - - test('tree structure of spans should be correct when mixing it with span on scope', () => { - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - - const transaction = hub.startTransaction({ name: 'test' }); - const childSpanOne = transaction.startChild(); - - const childSpanTwo = childSpanOne.startChild(); - childSpanTwo.end(); - - childSpanOne.end(); - - hub.getScope().setSpan(transaction); - - const spanTwo = transaction.startChild({}); - spanTwo.end(); - transaction.end(); - - expect(spy).toHaveBeenCalled(); - expect(spy.mock.calls[0][0].spans).toHaveLength(3); - expect(spy.mock.calls[0][0].contexts.trace).toEqual(transaction.getTraceContext()); - expect(childSpanOne.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); - expect(childSpanTwo.toJSON().parent_span_id).toEqual(childSpanOne.toJSON().span_id); - expect(spanTwo.toJSON().parent_span_id).toEqual(transaction.toJSON().span_id); - }); - }); - }); - - describe('getTraceContext', () => { - test('should have status attribute undefined if no status tag is available', () => { - const span = new SentrySpan({}); - const context = span.getTraceContext(); - expect((context as any).status).toBeUndefined(); - }); - - test('should have success status extracted from tags', () => { - const span = new SentrySpan({}); - span.setStatus('ok'); - const context = span.getTraceContext(); - expect((context as any).status).toBe('ok'); - }); - - test('should have failure status extracted from tags', () => { - const span = new SentrySpan({}); - span.setStatus('resource_exhausted'); - const context = span.getTraceContext(); - expect((context as any).status).toBe('resource_exhausted'); - }); - - test('should drop all `undefined` values', () => { - const spanB = new SentrySpan({ spanId: 'd', traceId: 'c' }); - const context = spanB.getTraceContext(); - expect(context).toStrictEqual({ - span_id: 'd', - trace_id: 'c', - data: { - 'sentry.origin': 'manual', - }, - origin: 'manual', - }); - }); - }); - - describe('toContext and updateWithContext', () => { - test('toContext should return correct context', () => { - const originalContext = { - traceId: 'a', - spanId: 'b', - sampled: false, - name: 'test', - op: 'op', - }; - const span = new SentrySpan(originalContext); - - const newContext = span.toContext(); - - expect(newContext).toStrictEqual({ - ...originalContext, - spanId: expect.any(String), - startTimestamp: expect.any(Number), - tags: {}, - traceId: expect.any(String), - data: { - 'sentry.op': 'op', - 'sentry.origin': 'manual', - }, - }); - }); - - test('updateWithContext should completely change span properties', () => { - const originalContext = { - traceId: 'a', - spanId: 'b', - sampled: false, - name: 'test', - op: 'op', - tags: { - tag0: 'hello', - }, - }; - const span = new SentrySpan(originalContext); - - span.updateWithContext({ - traceId: 'c', - spanId: 'd', - sampled: true, - }); - - expect(span.spanContext().traceId).toBe('c'); - expect(span.spanContext().spanId).toBe('d'); - expect(span.sampled).toBe(true); - expect(spanToJSON(span).description).toBe(undefined); - expect(spanToJSON(span).op).toBe(undefined); - expect(span.tags).toStrictEqual({}); - }); - - test('using toContext and updateWithContext together should update only changed properties', () => { - const originalContext = { - traceId: 'a', - spanId: 'b', - sampled: false, - name: 'test', - op: 'op', - tags: { tag0: 'hello' }, - data: { data0: 'foo' }, - }; - const span = new SentrySpan(originalContext); - - const newContext = { - ...span.toContext(), - name: 'new', - endTimestamp: 1, - op: 'new-op', - sampled: true, - tags: { - tag1: 'bye', - }, - data: { - ...span.toContext().data, - }, - }; - - if (newContext.data) newContext.data.data1 = 'bar'; - - span.updateWithContext(newContext); - - expect(span.spanContext().traceId).toBe('a'); - expect(span.spanContext().spanId).toBe('b'); - expect(spanToJSON(span).description).toBe('new'); - expect(spanToJSON(span).timestamp).toBe(1); - expect(spanToJSON(span).op).toBe('new-op'); - expect(span.sampled).toBe(true); - expect(span.tags).toStrictEqual({ tag1: 'bye' }); - expect(span.data).toStrictEqual({ - data0: 'foo', - data1: 'bar', - 'sentry.op': 'op', - 'sentry.origin': 'manual', - }); - }); - }); - - describe('getDynamicSamplingContext', () => { - beforeEach(() => { - getClient()!.getOptions = () => { - return { - release: '1.0.1', - environment: 'production', - } as ClientOptions; - }; - }); - - test('should return DSC that was provided during transaction creation, if it was provided', () => { - const transaction = new Transaction( - { - name: 'tx', - metadata: { dynamicSamplingContext: { environment: 'myEnv' } }, - }, - getCurrentHub(), - ); - - const dynamicSamplingContext = transaction.getDynamicSamplingContext(); - - expect(dynamicSamplingContext).toStrictEqual({ environment: 'myEnv' }); - }); - - test('should return new DSC, if no DSC was provided during transaction creation', () => { - const transaction = new Transaction({ - name: 'tx', - metadata: { - sampleRate: 0.56, - }, - sampled: true, - }); - - const getOptionsSpy = jest.spyOn(getClient()!, 'getOptions'); - - const dynamicSamplingContext = transaction.getDynamicSamplingContext(); - - expect(getOptionsSpy).toHaveBeenCalledTimes(1); - expect(dynamicSamplingContext).toStrictEqual({ - release: '1.0.1', - environment: 'production', - sampled: 'true', - sample_rate: '0.56', - trace_id: expect.any(String), - transaction: 'tx', - }); - }); - - describe('Including transaction name in DSC', () => { - test('is not included if transaction source is url', () => { - const transaction = new Transaction( - { - name: 'tx', - attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url', - }, - }, - getCurrentHub(), - ); - - const dsc = transaction.getDynamicSamplingContext()!; - expect(dsc.transaction).toBeUndefined(); - }); - - test.each([ - ['is included if transaction source is paremeterized route/url', 'route'], - ['is included if transaction source is a custom name', 'custom'], - ] as const)('%s', (_, source) => { - const transaction = new Transaction( - { - name: 'tx', - attributes: { - ...(source && { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source }), - }, - }, - getCurrentHub(), - ); - - const dsc = transaction.getDynamicSamplingContext()!; - - expect(dsc.transaction).toEqual('tx'); - }); - }); - }); - - describe('Transaction source', () => { - test('is included when transaction metadata is set', () => { - const hub = getCurrentHub(); - - const spy = jest.spyOn(hub as any, 'captureEvent') as any; - const transaction = hub.startTransaction({ name: 'test', sampled: true }); - transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'url'); - expect(spy).toHaveBeenCalledTimes(0); - - transaction.end(); - expect(spy).toHaveBeenCalledTimes(1); - expect(spy).toHaveBeenLastCalledWith( - expect.objectContaining({ - transaction_info: { - source: 'url', - }, - }), - ); - }); - }); -}); diff --git a/packages/tracing/test/transaction.test.ts b/packages/tracing/test/transaction.test.ts deleted file mode 100644 index 43f5a4d76544..000000000000 --- a/packages/tracing/test/transaction.test.ts +++ /dev/null @@ -1,210 +0,0 @@ -/* eslint-disable deprecation/deprecation */ -import { BrowserClient, Hub } from '@sentry/browser'; -import { - SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, - SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, - spanToJSON, -} from '@sentry/core'; - -import { Transaction, addExtensionMethods } from '../src'; -import { getDefaultBrowserClientOptions } from './testutils'; - -describe('`Transaction` class', () => { - beforeAll(() => { - addExtensionMethods(); - }); - - describe('transaction name source', () => { - it('sets source in constructor if provided', () => { - const transaction = new Transaction({ - name: 'dogpark', - attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route' }, - }); - - expect(spanToJSON(transaction).description).toEqual('dogpark'); - expect(spanToJSON(transaction).data?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('route'); - }); - - it("sets source to be `'custom'` in constructor if not provided", () => { - const transaction = new Transaction({ name: 'dogpark' }); - - expect(spanToJSON(transaction).description).toEqual('dogpark'); - expect(spanToJSON(transaction).data?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toBe('custom'); - }); - - it("sets source to `'custom'` when assigning to `name` property", () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.updateName('ballpit'); - - expect(spanToJSON(transaction).description).toEqual('ballpit'); - expect(spanToJSON(transaction).data?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('custom'); - }); - - it('sets instrumenter to be `sentry` in constructor if not provided', () => { - const transaction = new Transaction({ name: 'dogpark' }); - - expect(transaction.instrumenter).toEqual('sentry'); - }); - - it('allows to set instrumenter', () => { - const transaction = new Transaction({ name: 'dogpark', instrumenter: 'otel' }); - - expect(transaction.instrumenter).toEqual('otel'); - }); - - describe('`updateName` method', () => { - it("sets source to `'custom'` if no source provided", () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.updateName('ballpit'); - - expect(spanToJSON(transaction).description).toEqual('ballpit'); - expect(spanToJSON(transaction).data?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('custom'); - }); - - it('uses given `source` value', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.updateName('ballpit'); - transaction.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route'); - - expect(spanToJSON(transaction).description).toEqual('ballpit'); - expect(spanToJSON(transaction).data?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toEqual('route'); - }); - }); - }); - - describe('setContext', () => { - it('sets context', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setContext('foo', { - key: 'val', - key2: 'val2', - }); - - // @ts-expect-error accessing private property - expect(transaction._contexts).toEqual({ - foo: { - key: 'val', - key2: 'val2', - }, - }); - }); - - it('overwrites context', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setContext('foo', { - key: 'val', - key2: 'val2', - }); - transaction.setContext('foo', { - key3: 'val3', - }); - - // @ts-expect-error accessing private property - expect(transaction._contexts).toEqual({ - foo: { - key3: 'val3', - }, - }); - }); - - it('merges context', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setContext('foo', { - key: 'val', - key2: 'val2', - }); - transaction.setContext('bar', { - anotherKey: 'anotherVal', - }); - - // @ts-expect-error accessing private property - expect(transaction._contexts).toEqual({ - foo: { - key: 'val', - key2: 'val2', - }, - bar: { - anotherKey: 'anotherVal', - }, - }); - }); - - it('deletes context', () => { - const transaction = new Transaction({ name: 'dogpark' }); - transaction.setContext('foo', { - key: 'val', - key2: 'val2', - }); - transaction.setContext('foo', null); - - // @ts-expect-error accessing private property - expect(transaction._contexts).toEqual({}); - }); - - it('sets contexts on the event', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const client = new BrowserClient(options); - const hub = new Hub(client); - - jest.spyOn(hub, 'captureEvent'); - - const transaction = hub.startTransaction({ name: 'dogpark' }); - transaction.setContext('foo', { key: 'val' }); - transaction.end(); - - // eslint-disable-next-line @typescript-eslint/unbound-method - expect(hub.captureEvent).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/unbound-method - expect(hub.captureEvent).toHaveBeenLastCalledWith( - expect.objectContaining({ - contexts: { - foo: { key: 'val' }, - trace: { - data: { - [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', - [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', - }, - span_id: transaction.spanId, - trace_id: transaction.traceId, - origin: 'manual', - }, - }, - }), - ); - }); - - it('does not override trace context', () => { - const options = getDefaultBrowserClientOptions({ tracesSampleRate: 1 }); - const client = new BrowserClient(options); - const hub = new Hub(client); - - jest.spyOn(hub, 'captureEvent'); - - const transaction = hub.startTransaction({ name: 'dogpark' }); - transaction.setContext('trace', { key: 'val' }); - transaction.end(); - - // eslint-disable-next-line @typescript-eslint/unbound-method - expect(hub.captureEvent).toHaveBeenCalledTimes(1); - // eslint-disable-next-line @typescript-eslint/unbound-method - expect(hub.captureEvent).toHaveBeenLastCalledWith( - expect.objectContaining({ - contexts: { - trace: { - data: { - [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'manual', - [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', - }, - span_id: transaction.spanId, - trace_id: transaction.traceId, - origin: 'manual', - }, - }, - }), - ); - }); - }); -}); From 45f83eb159f9217e0f769356c2e05512eb0ea671 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 11:54:31 -0500 Subject: [PATCH 05/14] fix test import --- packages/core/test/lib/tracing/idletransaction.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/core/test/lib/tracing/idletransaction.test.ts b/packages/core/test/lib/tracing/idletransaction.test.ts index b4704e96e5ea..8f61b43164c3 100644 --- a/packages/core/test/lib/tracing/idletransaction.test.ts +++ b/packages/core/test/lib/tracing/idletransaction.test.ts @@ -15,6 +15,7 @@ import { import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; import { IdleTransaction, SentrySpan, getClient } from '../../../src'; +import { IdleTransactionSpanRecorder } from '../../../src/tracing/idletransaction'; const dsn = 'https://123@sentry.io/42'; beforeEach(() => { From 6aa5ccfc0c7c5e7b6d27e9e4e716d3a77d86ddd6 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 12:08:07 -0500 Subject: [PATCH 06/14] more test fixes --- packages/core/test/lib/tracing/span.test.ts | 191 +------------------- 1 file changed, 7 insertions(+), 184 deletions(-) diff --git a/packages/core/test/lib/tracing/span.test.ts b/packages/core/test/lib/tracing/span.test.ts index 353636846596..0a89b5acc5ff 100644 --- a/packages/core/test/lib/tracing/span.test.ts +++ b/packages/core/test/lib/tracing/span.test.ts @@ -1,10 +1,9 @@ import { timestampInSeconds } from '@sentry/utils'; import { SentrySpan } from '../../../src'; -import { TRACE_FLAG_NONE, TRACE_FLAG_SAMPLED, spanToJSON } from '../../../src/utils/spanUtils'; +import { TRACE_FLAG_NONE, TRACE_FLAG_SAMPLED, spanToJSON, spanToTraceContext } from '../../../src/utils/spanUtils'; describe('span', () => { describe('name', () => { - /* eslint-disable deprecation/deprecation */ it('works with name', () => { const span = new SentrySpan({ name: 'span name' }); expect(spanToJSON(span).description).toEqual('span name'); @@ -23,46 +22,15 @@ describe('span', () => { describe('new SentrySpan', () => { test('simple', () => { const span = new SentrySpan({ sampled: true }); + // eslint-disable-next-line deprecation/deprecation const span2 = span.startChild(); expect((span2 as any).parentSpanId).toBe((span as any).spanId); expect((span2 as any).traceId).toBe((span as any).traceId); expect((span2 as any).sampled).toBe((span as any).sampled); }); - - test('sets instrumenter to `sentry` if not specified in constructor', () => { - const span = new SentrySpan({}); - - expect(span.instrumenter).toBe('sentry'); - }); - - test('allows to set instrumenter in constructor', () => { - const span = new SentrySpan({ instrumenter: 'otel' }); - - expect(span.instrumenter).toBe('otel'); - }); }); describe('setters', () => { - test('setTag', () => { - const span = new SentrySpan({}); - expect(span.tags.foo).toBeUndefined(); - span.setTag('foo', 'bar'); - expect(span.tags.foo).toBe('bar'); - span.setTag('foo', 'baz'); - expect(span.tags.foo).toBe('baz'); - }); - - test('setData', () => { - const span = new SentrySpan({}); - expect(span.data.foo).toBeUndefined(); - span.setData('foo', null); - expect(span.data.foo).toBe(null); - span.setData('foo', 2); - expect(span.data.foo).toBe(2); - span.setData('foo', true); - expect(span.data.foo).toBe(true); - }); - test('setName', () => { const span = new SentrySpan({}); expect(spanToJSON(span).description).toBeUndefined(); @@ -75,23 +43,14 @@ describe('span', () => { test('setStatus', () => { const span = new SentrySpan({}); span.setStatus('permission_denied'); - expect((span.getTraceContext() as any).status).toBe('permission_denied'); - }); - - // TODO (v8): Remove - test('setHttpStatus', () => { - const span = new SentrySpan({}); - span.setHttpStatus(404); - expect((span.getTraceContext() as any).status).toBe('not_found'); - expect(span.tags['http.status_code']).toBe('404'); - expect(span.data['http.response.status_code']).toBe(404); + expect(spanToTraceContext(span).status).toBe('permission_denied'); }); }); describe('toJSON', () => { test('simple', () => { - const span = JSON.parse( - JSON.stringify(new SentrySpan({ traceId: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', spanId: 'bbbbbbbbbbbbbbbb' })), + const span = spanToJSON( + new SentrySpan({ traceId: 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', spanId: 'bbbbbbbbbbbbbbbb' }), ); expect(span).toHaveProperty('span_id', 'bbbbbbbbbbbbbbbb'); expect(span).toHaveProperty('trace_id', 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'); @@ -100,7 +59,7 @@ describe('span', () => { test('with parent', () => { const spanA = new SentrySpan({ traceId: 'a', spanId: 'b' }) as any; const spanB = new SentrySpan({ traceId: 'c', spanId: 'd', sampled: false, parentSpanId: spanA.spanId }); - const serialized = JSON.parse(JSON.stringify(spanB)); + const serialized = spanToJSON(spanB); expect(serialized).toHaveProperty('parent_span_id', 'b'); expect(serialized).toHaveProperty('span_id', 'd'); expect(serialized).toHaveProperty('trace_id', 'c'); @@ -113,7 +72,7 @@ describe('span', () => { spanId: 'd', traceId: 'c', }); - const serialized = spanB.toJSON(); + const serialized = spanToJSON(spanB); expect(serialized).toStrictEqual({ start_timestamp: expect.any(Number), parent_span_id: 'b', @@ -161,142 +120,6 @@ describe('span', () => { }); }); - describe('getTraceContext', () => { - test('should have status attribute undefined if no status tag is available', () => { - const span = new SentrySpan({}); - const context = span.getTraceContext(); - expect((context as any).status).toBeUndefined(); - }); - - test('should have success status extracted from tags', () => { - const span = new SentrySpan({}); - span.setStatus('ok'); - const context = span.getTraceContext(); - expect((context as any).status).toBe('ok'); - }); - - test('should have failure status extracted from tags', () => { - const span = new SentrySpan({}); - span.setStatus('resource_exhausted'); - const context = span.getTraceContext(); - expect((context as any).status).toBe('resource_exhausted'); - }); - - test('should drop all `undefined` values', () => { - const spanB = new SentrySpan({ spanId: 'd', traceId: 'c' }); - const context = spanB.getTraceContext(); - expect(context).toStrictEqual({ - span_id: 'd', - trace_id: 'c', - data: { - 'sentry.origin': 'manual', - }, - origin: 'manual', - }); - }); - }); - - describe('toContext and updateWithContext', () => { - test('toContext should return correct context', () => { - const originalContext = { - traceId: 'a', - spanId: 'b', - sampled: false, - description: 'test', - op: 'op', - }; - const span = new SentrySpan(originalContext); - - const newContext = span.toContext(); - - expect(newContext).toStrictEqual({ - ...originalContext, - spanId: expect.any(String), - startTimestamp: expect.any(Number), - tags: {}, - traceId: expect.any(String), - data: { - 'sentry.op': 'op', - 'sentry.origin': 'manual', - }, - }); - }); - - test('updateWithContext should completely change span properties', () => { - const originalContext = { - traceId: 'a', - spanId: 'b', - sampled: false, - description: 'test', - op: 'op', - tags: { - tag0: 'hello', - }, - }; - const span = new SentrySpan(originalContext); - - span.updateWithContext({ - traceId: 'c', - spanId: 'd', - sampled: true, - }); - - expect(span.spanContext().traceId).toBe('c'); - expect(span.spanContext().spanId).toBe('d'); - expect(span.sampled).toBe(true); - expect(spanToJSON(span).description).toBe(undefined); - expect(spanToJSON(span).op).toBe(undefined); - expect(span.tags).toStrictEqual({}); - }); - - test('using toContext and updateWithContext together should update only changed properties', () => { - const originalContext = { - traceId: 'a', - spanId: 'b', - sampled: false, - description: 'test', - op: 'op', - tags: { tag0: 'hello' }, - data: { data0: 'foo' }, - }; - const span = new SentrySpan(originalContext); - - const newContext = { - ...span.toContext(), - description: 'new', - endTimestamp: 1, - op: 'new-op', - sampled: true, - tags: { - tag1: 'bye', - }, - data: { - ...span.toContext().data, - }, - }; - - if (newContext.data) newContext.data.data1 = 'bar'; - - span.updateWithContext(newContext); - - expect(span.spanContext().traceId).toBe('a'); - expect(span.spanContext().spanId).toBe('b'); - expect(spanToJSON(span).description).toBe('new'); - expect(spanToJSON(span).timestamp).toBe(1); - expect(spanToJSON(span).op).toBe('new-op'); - expect(span.sampled).toBe(true); - expect(span.tags).toStrictEqual({ tag1: 'bye' }); - expect(span.data).toStrictEqual({ - data0: 'foo', - data1: 'bar', - 'sentry.op': 'op', - 'sentry.origin': 'manual', - }); - }); - }); - - /* eslint-enable deprecation/deprecation */ - describe('setAttribute', () => { it('allows to set attributes', () => { const span = new SentrySpan(); From 5522112dcbcc2c2f6b9ca950e6bf15e9f1a25ac4 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 13:11:47 -0500 Subject: [PATCH 07/14] fix serialized event --- .../long-tasks-disabled/test.ts | 5 ++--- .../browserTracingIntegration/long-tasks-enabled/test.ts | 9 ++++----- .../tracing/browsertracing/long-tasks-disabled/test.ts | 5 ++--- .../tracing/browsertracing/long-tasks-enabled/test.ts | 9 ++++----- .../tracing/metrics/pageload-browser-spans/test.ts | 5 ++--- .../tracing/metrics/pageload-resource-spans/test.ts | 5 ++--- .../suites/tracing/request/fetch/test.ts | 5 ++--- .../suites/tracing/request/xhr/test.ts | 5 ++--- 8 files changed, 20 insertions(+), 28 deletions(-) diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-disabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-disabled/test.ts index 1f7bb54bb36a..d460d2883afd 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-disabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-disabled/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { SerializedEvent } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -15,8 +15,7 @@ sentryTest('should not capture long task when flag is disabled.', async ({ brows const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getFirstSentryEnvelopeRequest(page, url); - // eslint-disable-next-line deprecation/deprecation + const eventData = await getFirstSentryEnvelopeRequest(page, url); const uiSpans = eventData.spans?.filter(({ op }) => op?.startsWith('ui')); expect(uiSpans?.length).toBe(0); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-enabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-enabled/test.ts index 32819fd784e0..1ed0bcda2a89 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-enabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/long-tasks-enabled/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { SerializedEvent } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -15,8 +15,7 @@ sentryTest('should capture long task.', async ({ browserName, getLocalTestPath, const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getFirstSentryEnvelopeRequest(page, url); - // eslint-disable-next-line deprecation/deprecation + const eventData = await getFirstSentryEnvelopeRequest(page, url); const uiSpans = eventData.spans?.filter(({ op }) => op?.startsWith('ui')); expect(uiSpans?.length).toBeGreaterThan(0); @@ -29,8 +28,8 @@ sentryTest('should capture long task.', async ({ browserName, getLocalTestPath, parent_span_id: eventData.contexts?.trace?.span_id, }), ); - const start = (firstUISpan as Event)['start_timestamp'] ?? 0; - const end = (firstUISpan as Event)['timestamp'] ?? 0; + const start = firstUISpan.start_timestamp ?? 0; + const end = firstUISpan.timestamp ?? 0; const duration = end - start; expect(duration).toBeGreaterThanOrEqual(0.1); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-disabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-disabled/test.ts index 1f7bb54bb36a..d460d2883afd 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-disabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-disabled/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { SerializedEvent } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -15,8 +15,7 @@ sentryTest('should not capture long task when flag is disabled.', async ({ brows const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getFirstSentryEnvelopeRequest(page, url); - // eslint-disable-next-line deprecation/deprecation + const eventData = await getFirstSentryEnvelopeRequest(page, url); const uiSpans = eventData.spans?.filter(({ op }) => op?.startsWith('ui')); expect(uiSpans?.length).toBe(0); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-enabled/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-enabled/test.ts index 32819fd784e0..1ed0bcda2a89 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-enabled/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browsertracing/long-tasks-enabled/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { SerializedEvent } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -15,8 +15,7 @@ sentryTest('should capture long task.', async ({ browserName, getLocalTestPath, const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getFirstSentryEnvelopeRequest(page, url); - // eslint-disable-next-line deprecation/deprecation + const eventData = await getFirstSentryEnvelopeRequest(page, url); const uiSpans = eventData.spans?.filter(({ op }) => op?.startsWith('ui')); expect(uiSpans?.length).toBeGreaterThan(0); @@ -29,8 +28,8 @@ sentryTest('should capture long task.', async ({ browserName, getLocalTestPath, parent_span_id: eventData.contexts?.trace?.span_id, }), ); - const start = (firstUISpan as Event)['start_timestamp'] ?? 0; - const end = (firstUISpan as Event)['timestamp'] ?? 0; + const start = firstUISpan.start_timestamp ?? 0; + const end = firstUISpan.timestamp ?? 0; const duration = end - start; expect(duration).toBeGreaterThanOrEqual(0.1); diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-browser-spans/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-browser-spans/test.ts index 504ac975621e..0730d2ba4645 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-browser-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-browser-spans/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { SerializedEvent } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -11,8 +11,7 @@ sentryTest('should add browser-related spans to pageload transaction', async ({ const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getFirstSentryEnvelopeRequest(page, url); - // eslint-disable-next-line deprecation/deprecation + const eventData = await getFirstSentryEnvelopeRequest(page, url); const browserSpans = eventData.spans?.filter(({ op }) => op === 'browser'); // Spans `connect`, `cache` and `DNS` are not always inside `pageload` transaction. diff --git a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-resource-spans/test.ts b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-resource-spans/test.ts index 9ce848384f7b..40159d39ea25 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-resource-spans/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/metrics/pageload-resource-spans/test.ts @@ -1,6 +1,6 @@ import type { Route } from '@playwright/test'; import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { SerializedEvent } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -17,8 +17,7 @@ sentryTest('should add resource spans to pageload transaction', async ({ getLoca const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getFirstSentryEnvelopeRequest(page, url); - // eslint-disable-next-line deprecation/deprecation + const eventData = await getFirstSentryEnvelopeRequest(page, url); const resourceSpans = eventData.spans?.filter(({ op }) => op?.startsWith('resource')); // Webkit 16.0 (which is linked to Playwright 1.27.1) consistently creates 2 consectutive spans for `css`, diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts index 7bffc0131b2f..ab4c29906f5c 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/fetch/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { SerializedEvent } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; import { getMultipleSentryEnvelopeRequests, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -21,10 +21,9 @@ sentryTest('should create spans for multiple fetch requests', async ({ getLocalT // If we are on FF or webkit: // 1st envelope contains CORS error // 2nd envelope contains the tracing data we want to check here - const envelopes = await getMultipleSentryEnvelopeRequests(page, 2, { url, timeout: 10000 }); + const envelopes = await getMultipleSentryEnvelopeRequests(page, 2, { url, timeout: 10000 }); const tracingEvent = envelopes[envelopes.length - 1]; // last envelope contains tracing data on all browsers - // eslint-disable-next-line deprecation/deprecation const requestSpans = tracingEvent.spans?.filter(({ op }) => op === 'http.client'); expect(requestSpans).toHaveLength(3); diff --git a/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts b/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts index d1c64e253e71..bd4ee0bbb003 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/request/xhr/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/types'; +import type { SerializedEvent } from '@sentry/types'; import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; @@ -11,8 +11,7 @@ sentryTest('should create spans for multiple XHR requests', async ({ getLocalTes const url = await getLocalTestPath({ testDir: __dirname }); - const eventData = await getFirstSentryEnvelopeRequest(page, url); - // eslint-disable-next-line deprecation/deprecation + const eventData = await getFirstSentryEnvelopeRequest(page, url); const requestSpans = eventData.spans?.filter(({ op }) => op === 'http.client'); expect(requestSpans).toHaveLength(3); From cd6a518c9bc6b484aaa600f8d1a0c16a50a9b71b Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 14:57:02 -0500 Subject: [PATCH 08/14] remove tracing extension call --- .../suites/public-api/startSpan/init.js | 2 -- .../suites/public-api/startTransaction/init.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js b/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js index d6e849bc7cae..18d7bb50d3d3 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js @@ -1,7 +1,5 @@ import * as Sentry from '@sentry/browser'; -Sentry.addTracingExtensions(); - window.Sentry = Sentry; Sentry.init({ diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js b/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js index 1c155f323586..3364667c960c 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js +++ b/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js @@ -1,7 +1,5 @@ import * as Sentry from '@sentry/browser'; -Sentry.addTracingExtensions(); - window.Sentry = Sentry; Sentry.init({ From f59da926679b4b971f9ed3324751ebd36d641ad0 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 15:19:54 -0500 Subject: [PATCH 09/14] fix tracing exports --- .../suites/public-api/startSpan/init.js | 2 + .../index.bundle.tracing.replay.feedback.ts | 7 +- .../src/index.bundle.tracing.replay.ts | 7 +- packages/browser/src/index.bundle.tracing.ts | 7 +- packages/tracing-internal/src/extensions.ts | 67 ------------------- packages/tracing-internal/src/index.ts | 2 - 6 files changed, 14 insertions(+), 78 deletions(-) delete mode 100644 packages/tracing-internal/src/extensions.ts diff --git a/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js b/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js index 18d7bb50d3d3..5724df357e8b 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js +++ b/dev-packages/browser-integration-tests/suites/public-api/startSpan/init.js @@ -2,6 +2,8 @@ import * as Sentry from '@sentry/browser'; window.Sentry = Sentry; +Sentry.addTracingExtensions(); + Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', tracesSampleRate: 1.0, diff --git a/packages/browser/src/index.bundle.tracing.replay.feedback.ts b/packages/browser/src/index.bundle.tracing.replay.feedback.ts index 8a4a05dba6b6..b103b6f4583d 100644 --- a/packages/browser/src/index.bundle.tracing.replay.feedback.ts +++ b/packages/browser/src/index.bundle.tracing.replay.feedback.ts @@ -1,5 +1,6 @@ import { Feedback, feedbackIntegration } from '@sentry-internal/feedback'; -import { BrowserTracing, addExtensionMethods } from '@sentry-internal/tracing'; +import { BrowserTracing } from '@sentry-internal/tracing'; +import { addTracingExtensions } from '@sentry/core'; import { Replay, replayIntegration } from '@sentry/replay'; import { bundleBrowserTracingIntegration as browserTracingIntegration } from './helpers'; @@ -15,7 +16,7 @@ Sentry.Integrations.Replay = Replay; Sentry.Integrations.BrowserTracing = BrowserTracing; // We are patching the global object with our hub extension methods -addExtensionMethods(); +addTracingExtensions(); export { // eslint-disable-next-line deprecation/deprecation @@ -27,6 +28,6 @@ export { // eslint-disable-next-line deprecation/deprecation BrowserTracing, browserTracingIntegration, - addExtensionMethods, + addTracingExtensions, }; export * from './index.bundle.base'; diff --git a/packages/browser/src/index.bundle.tracing.replay.ts b/packages/browser/src/index.bundle.tracing.replay.ts index 20bbf135ace5..e817390aa39d 100644 --- a/packages/browser/src/index.bundle.tracing.replay.ts +++ b/packages/browser/src/index.bundle.tracing.replay.ts @@ -1,5 +1,6 @@ import { Feedback, feedbackIntegration } from '@sentry-internal/integration-shims'; -import { BrowserTracing, addExtensionMethods } from '@sentry-internal/tracing'; +import { BrowserTracing } from '@sentry-internal/tracing'; +import { addTracingExtensions } from '@sentry/core'; import { Replay, replayIntegration } from '@sentry/replay'; import { bundleBrowserTracingIntegration as browserTracingIntegration } from './helpers'; @@ -15,7 +16,7 @@ Sentry.Integrations.Replay = Replay; Sentry.Integrations.BrowserTracing = BrowserTracing; // We are patching the global object with our hub extension methods -addExtensionMethods(); +addTracingExtensions(); export { // eslint-disable-next-line deprecation/deprecation @@ -27,6 +28,6 @@ export { // eslint-disable-next-line deprecation/deprecation BrowserTracing, browserTracingIntegration, - addExtensionMethods, + addTracingExtensions, }; export * from './index.bundle.base'; diff --git a/packages/browser/src/index.bundle.tracing.ts b/packages/browser/src/index.bundle.tracing.ts index 5b1dc7f5d2de..704a646dcdb8 100644 --- a/packages/browser/src/index.bundle.tracing.ts +++ b/packages/browser/src/index.bundle.tracing.ts @@ -1,6 +1,7 @@ // This is exported so the loader does not fail when switching off Replay import { Feedback, Replay, feedbackIntegration, replayIntegration } from '@sentry-internal/integration-shims'; -import { BrowserTracing, addExtensionMethods } from '@sentry-internal/tracing'; +import { BrowserTracing } from '@sentry-internal/tracing'; +import { addTracingExtensions } from '@sentry/core'; import { bundleBrowserTracingIntegration as browserTracingIntegration } from './helpers'; import * as Sentry from './index.bundle.base'; @@ -15,7 +16,7 @@ Sentry.Integrations.Replay = Replay; Sentry.Integrations.BrowserTracing = BrowserTracing; // We are patching the global object with our hub extension methods -addExtensionMethods(); +addTracingExtensions(); export { // eslint-disable-next-line deprecation/deprecation @@ -27,6 +28,6 @@ export { // eslint-disable-next-line deprecation/deprecation BrowserTracing, browserTracingIntegration, - addExtensionMethods, + addTracingExtensions, }; export * from './index.bundle.base'; diff --git a/packages/tracing-internal/src/extensions.ts b/packages/tracing-internal/src/extensions.ts deleted file mode 100644 index 0d4c2b112e47..000000000000 --- a/packages/tracing-internal/src/extensions.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { addTracingExtensions, getMainCarrier } from '@sentry/core'; -import type { Integration, IntegrationClass } from '@sentry/types'; -import { dynamicRequire, isNodeEnv, loadModule } from '@sentry/utils'; - -/** - * @private - */ -function _autoloadDatabaseIntegrations(): void { - const carrier = getMainCarrier(); - if (!carrier.__SENTRY__) { - return; - } - - const packageToIntegrationMapping: Record Integration> = { - mongodb() { - const integration = dynamicRequire(module, './node/integrations/mongo') as { - Mongo: IntegrationClass; - }; - return new integration.Mongo(); - }, - mongoose() { - const integration = dynamicRequire(module, './node/integrations/mongo') as { - Mongo: IntegrationClass; - }; - return new integration.Mongo(); - }, - mysql() { - const integration = dynamicRequire(module, './node/integrations/mysql') as { - Mysql: IntegrationClass; - }; - return new integration.Mysql(); - }, - pg() { - const integration = dynamicRequire(module, './node/integrations/postgres') as { - Postgres: IntegrationClass; - }; - return new integration.Postgres(); - }, - }; - - const mappedPackages = Object.keys(packageToIntegrationMapping) - .filter(moduleName => !!loadModule(moduleName)) - .map(pkg => { - try { - return packageToIntegrationMapping[pkg](); - } catch (e) { - return undefined; - } - }) - .filter(p => p) as Integration[]; - - if (mappedPackages.length > 0) { - carrier.__SENTRY__.integrations = [...(carrier.__SENTRY__.integrations || []), ...mappedPackages]; - } -} - -/** - * This patches the global object and injects the Tracing extensions methods - */ -export function addExtensionMethods(): void { - addTracingExtensions(); - - // Detect and automatically load specified integrations. - if (isNodeEnv()) { - _autoloadDatabaseIntegrations(); - } -} diff --git a/packages/tracing-internal/src/index.ts b/packages/tracing-internal/src/index.ts index 4f09ca6a2e96..cbcd5324759a 100644 --- a/packages/tracing-internal/src/index.ts +++ b/packages/tracing-internal/src/index.ts @@ -30,5 +30,3 @@ export { export { addTracingHeadersToFetchRequest, instrumentFetchRequest } from './common/fetch'; export type { RequestInstrumentationOptions } from './browser'; - -export { addExtensionMethods } from './extensions'; From d36a78eec22294121031ebfc0203301c43f7c2f5 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 15:32:32 -0500 Subject: [PATCH 10/14] add to add transaction --- .../suites/public-api/startTransaction/init.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js b/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js index 3364667c960c..3fb0df7a75d4 100644 --- a/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js +++ b/dev-packages/browser-integration-tests/suites/public-api/startTransaction/init.js @@ -2,6 +2,8 @@ import * as Sentry from '@sentry/browser'; window.Sentry = Sentry; +Sentry.addTracingExtensions(); + Sentry.init({ dsn: 'https://public@dsn.ingest.sentry.io/1337', tracesSampleRate: 1.0, From 3ae2de205f65d1ee9272f474ece32cbd8fd9708e Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 16:20:47 -0500 Subject: [PATCH 11/14] try shimming out tracing exports again --- .../node-exports-test-app/package.json | 6 ++++++ .../node-exports-test-app/tracing-shim.js | 3 +++ .../test-applications/sveltekit-2/package.json | 3 ++- .../test-applications/sveltekit-2/tracing-shim.js | 3 +++ .../test-applications/sveltekit/package.json | 3 ++- dev-packages/e2e-tests/tracing-shim/index.js | 3 +++ dev-packages/e2e-tests/tracing-shim/package.json | 11 +++++++++++ 7 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 dev-packages/e2e-tests/test-applications/node-exports-test-app/tracing-shim.js create mode 100644 dev-packages/e2e-tests/test-applications/sveltekit-2/tracing-shim.js create mode 100644 dev-packages/e2e-tests/tracing-shim/index.js create mode 100644 dev-packages/e2e-tests/tracing-shim/package.json diff --git a/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json b/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json index 6d187f14c245..ade96ad5b3a6 100644 --- a/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json +++ b/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json @@ -23,6 +23,12 @@ "@types/node": "18.15.1", "typescript": "4.9.5" }, + "pnpm": { + "overrides": { + "@sentry/node": "latest || *", + "@sentry/tracing": "file:../../tracing-shim" + } + }, "devDependencies": { "ts-node": "10.9.1" }, diff --git a/dev-packages/e2e-tests/test-applications/node-exports-test-app/tracing-shim.js b/dev-packages/e2e-tests/test-applications/node-exports-test-app/tracing-shim.js new file mode 100644 index 000000000000..e245f86e5c40 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/node-exports-test-app/tracing-shim.js @@ -0,0 +1,3 @@ +// TODO(v8): Remove this file once we get rid of tracing dependency from sveltekit vite plugin +// This file is used as a shim for @sentry/tracing +module.exports = {}; diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json b/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json index 52e1ef9c98cf..4a6f4318548b 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2/package.json @@ -34,7 +34,8 @@ }, "pnpm": { "overrides": { - "@sentry/node": "latest || *" + "@sentry/node": "latest || *", + "@sentry/tracing": "file:../../tracing-shim" } }, "type": "module" diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2/tracing-shim.js b/dev-packages/e2e-tests/test-applications/sveltekit-2/tracing-shim.js new file mode 100644 index 000000000000..e245f86e5c40 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/sveltekit-2/tracing-shim.js @@ -0,0 +1,3 @@ +// TODO(v8): Remove this file once we get rid of tracing dependency from sveltekit vite plugin +// This file is used as a shim for @sentry/tracing +module.exports = {}; diff --git a/dev-packages/e2e-tests/test-applications/sveltekit/package.json b/dev-packages/e2e-tests/test-applications/sveltekit/package.json index a449961b97ea..01b3e5bad8ca 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit/package.json +++ b/dev-packages/e2e-tests/test-applications/sveltekit/package.json @@ -32,7 +32,8 @@ }, "pnpm": { "overrides": { - "@sentry/node": "latest || *" + "@sentry/node": "latest || *", + "@sentry/tracing": "file:../../tracing-shim" } }, "type": "module" diff --git a/dev-packages/e2e-tests/tracing-shim/index.js b/dev-packages/e2e-tests/tracing-shim/index.js new file mode 100644 index 000000000000..e245f86e5c40 --- /dev/null +++ b/dev-packages/e2e-tests/tracing-shim/index.js @@ -0,0 +1,3 @@ +// TODO(v8): Remove this file once we get rid of tracing dependency from sveltekit vite plugin +// This file is used as a shim for @sentry/tracing +module.exports = {}; diff --git a/dev-packages/e2e-tests/tracing-shim/package.json b/dev-packages/e2e-tests/tracing-shim/package.json new file mode 100644 index 000000000000..763f9da9cf17 --- /dev/null +++ b/dev-packages/e2e-tests/tracing-shim/package.json @@ -0,0 +1,11 @@ +{ + "name": "sveltekit", + "version": "0.0.1", + "private": true, + "main": "index.js", + "module": "index.js", + "scripts": {}, + "dependencies": {}, + "devDependencies": {}, + "type": "module" +} From f0903f83c7381ebe7cf8189ce9cf510647c321cd Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 17:11:15 -0500 Subject: [PATCH 12/14] esmify --- .../test-applications/node-exports-test-app/package.json | 2 +- .../test-applications/sveltekit-2/tracing-shim.js | 3 --- .../e2e-tests/test-applications/sveltekit/package.json | 2 +- .../tracing-shim.js => tracing-shim-esm/index.mjs} | 2 +- dev-packages/e2e-tests/tracing-shim-esm/package.json | 9 +++++++++ dev-packages/e2e-tests/tracing-shim/package.json | 5 ++--- 6 files changed, 14 insertions(+), 9 deletions(-) delete mode 100644 dev-packages/e2e-tests/test-applications/sveltekit-2/tracing-shim.js rename dev-packages/e2e-tests/{test-applications/node-exports-test-app/tracing-shim.js => tracing-shim-esm/index.mjs} (87%) create mode 100644 dev-packages/e2e-tests/tracing-shim-esm/package.json diff --git a/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json b/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json index ade96ad5b3a6..31c3a9207879 100644 --- a/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json +++ b/dev-packages/e2e-tests/test-applications/node-exports-test-app/package.json @@ -26,7 +26,7 @@ "pnpm": { "overrides": { "@sentry/node": "latest || *", - "@sentry/tracing": "file:../../tracing-shim" + "@sentry/tracing": "file:../../tracing-shim-esm" } }, "devDependencies": { diff --git a/dev-packages/e2e-tests/test-applications/sveltekit-2/tracing-shim.js b/dev-packages/e2e-tests/test-applications/sveltekit-2/tracing-shim.js deleted file mode 100644 index e245f86e5c40..000000000000 --- a/dev-packages/e2e-tests/test-applications/sveltekit-2/tracing-shim.js +++ /dev/null @@ -1,3 +0,0 @@ -// TODO(v8): Remove this file once we get rid of tracing dependency from sveltekit vite plugin -// This file is used as a shim for @sentry/tracing -module.exports = {}; diff --git a/dev-packages/e2e-tests/test-applications/sveltekit/package.json b/dev-packages/e2e-tests/test-applications/sveltekit/package.json index 01b3e5bad8ca..5871b00d31fd 100644 --- a/dev-packages/e2e-tests/test-applications/sveltekit/package.json +++ b/dev-packages/e2e-tests/test-applications/sveltekit/package.json @@ -33,7 +33,7 @@ "pnpm": { "overrides": { "@sentry/node": "latest || *", - "@sentry/tracing": "file:../../tracing-shim" + "@sentry/tracing": "file:../../tracing-shim-esm" } }, "type": "module" diff --git a/dev-packages/e2e-tests/test-applications/node-exports-test-app/tracing-shim.js b/dev-packages/e2e-tests/tracing-shim-esm/index.mjs similarity index 87% rename from dev-packages/e2e-tests/test-applications/node-exports-test-app/tracing-shim.js rename to dev-packages/e2e-tests/tracing-shim-esm/index.mjs index e245f86e5c40..504db0f709d0 100644 --- a/dev-packages/e2e-tests/test-applications/node-exports-test-app/tracing-shim.js +++ b/dev-packages/e2e-tests/tracing-shim-esm/index.mjs @@ -1,3 +1,3 @@ // TODO(v8): Remove this file once we get rid of tracing dependency from sveltekit vite plugin // This file is used as a shim for @sentry/tracing -module.exports = {}; +export {} diff --git a/dev-packages/e2e-tests/tracing-shim-esm/package.json b/dev-packages/e2e-tests/tracing-shim-esm/package.json new file mode 100644 index 000000000000..0b659b2cfbc6 --- /dev/null +++ b/dev-packages/e2e-tests/tracing-shim-esm/package.json @@ -0,0 +1,9 @@ +{ + "name": "tracing-shim-esm", + "version": "0.0.1", + "private": true, + "main": "index.mjs", + "scripts": {}, + "dependencies": {}, + "devDependencies": {} +} diff --git a/dev-packages/e2e-tests/tracing-shim/package.json b/dev-packages/e2e-tests/tracing-shim/package.json index 763f9da9cf17..48cb829a2524 100644 --- a/dev-packages/e2e-tests/tracing-shim/package.json +++ b/dev-packages/e2e-tests/tracing-shim/package.json @@ -1,11 +1,10 @@ { - "name": "sveltekit", + "name": "tracing-shim", "version": "0.0.1", "private": true, "main": "index.js", "module": "index.js", "scripts": {}, "dependencies": {}, - "devDependencies": {}, - "type": "module" + "devDependencies": {} } From b93d679d3ff99930b28003d6549f28dc24d4688c Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 17:36:01 -0500 Subject: [PATCH 13/14] yarn fix --- dev-packages/e2e-tests/tracing-shim-esm/index.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-packages/e2e-tests/tracing-shim-esm/index.mjs b/dev-packages/e2e-tests/tracing-shim-esm/index.mjs index 504db0f709d0..5ba2afe713b3 100644 --- a/dev-packages/e2e-tests/tracing-shim-esm/index.mjs +++ b/dev-packages/e2e-tests/tracing-shim-esm/index.mjs @@ -1,3 +1,3 @@ // TODO(v8): Remove this file once we get rid of tracing dependency from sveltekit vite plugin // This file is used as a shim for @sentry/tracing -export {} +export {}; From 22a433598431c4c7f17da419ac51e188461a2ea7 Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Thu, 22 Feb 2024 19:34:31 -0500 Subject: [PATCH 14/14] please --- dev-packages/e2e-tests/tracing-shim-esm/index.cjs | 3 +++ dev-packages/e2e-tests/tracing-shim-esm/package.json | 3 ++- dev-packages/e2e-tests/tracing-shim/package.json | 1 - 3 files changed, 5 insertions(+), 2 deletions(-) create mode 100644 dev-packages/e2e-tests/tracing-shim-esm/index.cjs diff --git a/dev-packages/e2e-tests/tracing-shim-esm/index.cjs b/dev-packages/e2e-tests/tracing-shim-esm/index.cjs new file mode 100644 index 000000000000..e245f86e5c40 --- /dev/null +++ b/dev-packages/e2e-tests/tracing-shim-esm/index.cjs @@ -0,0 +1,3 @@ +// TODO(v8): Remove this file once we get rid of tracing dependency from sveltekit vite plugin +// This file is used as a shim for @sentry/tracing +module.exports = {}; diff --git a/dev-packages/e2e-tests/tracing-shim-esm/package.json b/dev-packages/e2e-tests/tracing-shim-esm/package.json index 0b659b2cfbc6..577f7e2cef51 100644 --- a/dev-packages/e2e-tests/tracing-shim-esm/package.json +++ b/dev-packages/e2e-tests/tracing-shim-esm/package.json @@ -2,7 +2,8 @@ "name": "tracing-shim-esm", "version": "0.0.1", "private": true, - "main": "index.mjs", + "main": "index.cjs", + "module": "index.mjs", "scripts": {}, "dependencies": {}, "devDependencies": {} diff --git a/dev-packages/e2e-tests/tracing-shim/package.json b/dev-packages/e2e-tests/tracing-shim/package.json index 48cb829a2524..0ee353b22b5b 100644 --- a/dev-packages/e2e-tests/tracing-shim/package.json +++ b/dev-packages/e2e-tests/tracing-shim/package.json @@ -3,7 +3,6 @@ "version": "0.0.1", "private": true, "main": "index.js", - "module": "index.js", "scripts": {}, "dependencies": {}, "devDependencies": {}