diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/instrument.mjs b/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/instrument.mjs index 5fb6bd039fdb..b52053445456 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/instrument.mjs +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-express-vite-dev/instrument.mjs @@ -6,6 +6,5 @@ Sentry.init({ environment: 'qa', // dynamic sampling bias to keep transactions dsn: process.env.E2E_TEST_DSN, tunnel: 'http://localhost:3031/', // proxy server - autoInstrumentRemix: true, // auto instrument Remix integrations: [Sentry.nativeNodeFetchIntegration()], }); diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-express/instrument.mjs b/dev-packages/e2e-tests/test-applications/create-remix-app-express/instrument.mjs index f2e7d35fab80..0cbfe8ec4e5b 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-express/instrument.mjs +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-express/instrument.mjs @@ -7,7 +7,6 @@ Sentry.init({ dsn: process.env.E2E_TEST_DSN, tunnel: 'http://localhost:3031/', // proxy server sendDefaultPii: true, // Testing the FormData - autoInstrumentRemix: true, // auto instrument Remix captureActionFormDataKeys: { file: true, text: true, diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/instrument.server.cjs b/dev-packages/e2e-tests/test-applications/create-remix-app-v2/instrument.server.cjs index 5b80ca7b8695..6d211cac4592 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app-v2/instrument.server.cjs +++ b/dev-packages/e2e-tests/test-applications/create-remix-app-v2/instrument.server.cjs @@ -5,5 +5,4 @@ Sentry.init({ environment: 'qa', // dynamic sampling bias to keep transactions dsn: process.env.E2E_TEST_DSN, tunnel: 'http://localhost:3031/', // proxy server - autoInstrumentRemix: true, // auto instrument Remix }); diff --git a/dev-packages/e2e-tests/test-applications/create-remix-app/instrument.server.cjs b/dev-packages/e2e-tests/test-applications/create-remix-app/instrument.server.cjs index 5b80ca7b8695..6d211cac4592 100644 --- a/dev-packages/e2e-tests/test-applications/create-remix-app/instrument.server.cjs +++ b/dev-packages/e2e-tests/test-applications/create-remix-app/instrument.server.cjs @@ -5,5 +5,4 @@ Sentry.init({ environment: 'qa', // dynamic sampling bias to keep transactions dsn: process.env.E2E_TEST_DSN, tunnel: 'http://localhost:3031/', // proxy server - autoInstrumentRemix: true, // auto instrument Remix }); diff --git a/docs/migration/v8-to-v9.md b/docs/migration/v8-to-v9.md index bb0cfe487da0..fbb5f3aec298 100644 --- a/docs/migration/v8-to-v9.md +++ b/docs/migration/v8-to-v9.md @@ -82,6 +82,10 @@ If you need to support older browsers, we recommend transpiling your code using - When `skipOpenTelemetrySetup: true` is configured, `httpIntegration({ spans: false })` will be configured by default. This means that you no longer have to specify this yourself in this scenario. With this change, no spans are emitted once `skipOpenTelemetrySetup: true` is configured, without any further configuration being needed. +### `@sentry/remix` + +- The Remix SDK now uses OpenTelemetry instrumentation by default. This is identical to have used the v7 SDK with `autoInstrumentRemix: true`. + ### Uncategorized (TODO) - Next.js withSentryConfig returning Promise @@ -114,6 +118,7 @@ It will be removed in a future major version. - [General](#general) - [Server-side SDKs (Node, Deno, Bun, ...)](#server-side-sdks-node-deno-bun-) - [Next.js SDK](#nextjs-sdk) +- [Remix SDK](#remix-sdk) - [Vue/Nuxt SDK](#vuenuxt-sdk) ### General @@ -136,6 +141,12 @@ It will be removed in a future major version. - `experimental_captureRequestError` +### Remix SDK + +- `options.autoInstrumentRemix` + +The `autoInstrumentRemix` has been removed from the Remix SDK. The default behaviour of the Remix SDK is now as if `autoInstrumentRemix` was set to `true`. + ### Vue/Nuxt SDK - vueComponent tracking options diff --git a/packages/remix/README.md b/packages/remix/README.md index 7914555728f1..e4d5c60d8bd7 100644 --- a/packages/remix/README.md +++ b/packages/remix/README.md @@ -10,137 +10,44 @@ [![npm dm](https://img.shields.io/npm/dm/@sentry/remix.svg)](https://www.npmjs.com/package/@sentry/remix) [![npm dt](https://img.shields.io/npm/dt/@sentry/remix.svg)](https://www.npmjs.com/package/@sentry/remix) -## General - This package is a wrapper around `@sentry/node` for the server and `@sentry/react` for the client, with added functionality related to Remix. -To use this SDK, initialize Sentry in your Remix entry points for both the client and server. - -```ts -// entry.client.tsx - -import { useLocation, useMatches } from '@remix-run/react'; -import * as Sentry from '@sentry/remix'; -import { useEffect } from 'react'; - -Sentry.init({ - dsn: '__DSN__', - tracesSampleRate: 1, - integrations: [ - Sentry.browserTracingIntegration({ - useEffect, - useLocation, - useMatches, - }), - ], - // ... -}); -``` +## Compatibility -```ts -// entry.server.tsx +Currently, the minimum supported version of Remix is `1.0.0`. -import { prisma } from '~/db.server'; +## Installation -import * as Sentry from '@sentry/remix'; +To get started installing the SDK, use the Sentry Remix Wizard by running the following command in your terminal or +read the [Getting Started Docs](https://docs.sentry.io/platforms/javascript/guides/remix/): -Sentry.init({ - dsn: '__DSN__', - tracesSampleRate: 1, - integrations: [new Sentry.Integrations.Prisma({ client: prisma })], - // ... -}); +```sh +npx @sentry/wizard@latest -i remix ``` -Also, wrap your Remix root with `withSentry` to catch React component errors and to get parameterized router -transactions. - -```ts -// root.tsx - -import { - Links, - LiveReload, - Meta, - Outlet, - Scripts, - ScrollRestoration, -} from "@remix-run/react"; +The wizard will prompt you to log in to Sentry. After the wizard setup is completed, the SDK will automatically capture +unhandled errors, and monitor performance. -import { withSentry } from "@sentry/remix"; +## Custom Usage -function App() { - return ( - - - - - - - - - - - - - ); -} - -export default withSentry(App); -``` - -You can disable or configure `ErrorBoundary` using a second parameter to `withSentry`. +To set context information or to send manual events, you can use `@sentry/remix` as follows: ```ts - -withSentry(App, { - wrapWithErrorBoundary: false -}); - -// or - -withSentry(App, { - errorBoundaryOptions: { - fallback:

An error has occurred

- } -}); -``` - -To set context information or send manual events, use the exported functions of `@sentry/remix`. - -```ts -import * as Sentry from '@sentry/remix'; +import * as Sentry from '@sentry/nextjs'; // Set user information, as well as tags and further extras -Sentry.setExtra('battery', 0.7); Sentry.setTag('user_mode', 'admin'); Sentry.setUser({ id: '4711' }); +Sentry.setContext('application_area', { location: 'checkout' }); // Add a breadcrumb for future events Sentry.addBreadcrumb({ - message: 'My Breadcrumb', + message: '"Add to cart" clicked', // ... }); -// Capture exceptions, messages or manual events +// Capture exceptions or messages +Sentry.captureException(new Error('Oh no.')); Sentry.captureMessage('Hello, world!'); -Sentry.captureException(new Error('Good bye')); -Sentry.captureEvent({ - message: 'Manual', - stacktrace: [ - // ... - ], -}); ``` - -## Sourcemaps and Releases - -The Remix SDK provides a script that automatically creates a release and uploads sourcemaps. To generate sourcemaps with -Remix, you need to call `remix build` with the `--sourcemap` option. - -On release, call `sentry-upload-sourcemaps` to upload source maps and create a release. To see more details on how to -use the command, call `sentry-upload-sourcemaps --help`. - -For more advanced configuration, -[directly use `sentry-cli` to upload source maps.](https://github.com/getsentry/sentry-cli). diff --git a/packages/remix/package.json b/packages/remix/package.json index 9967c77676bc..b3a87413d8a5 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -12,10 +12,7 @@ "engines": { "node": ">=14.18" }, - "files": [ - "/build", - "/scripts" - ], + "files": ["/build", "/scripts"], "main": "build/cjs/index.server.js", "module": "build/esm/index.server.js", "browser": "build/esm/index.client.js", @@ -43,9 +40,7 @@ }, "typesVersions": { "<4.9": { - "build/types/index.d.ts": [ - "build/types-ts3.8/index.d.ts" - ] + "build/types/index.d.ts": ["build/types-ts3.8/index.d.ts"] } }, "publishConfig": { @@ -92,15 +87,10 @@ "fix": "eslint . --format stylish --fix", "lint": "eslint . --format stylish", "test": "yarn test:unit", - "test:integration": "run-s test:integration:otel test:integration:legacy", - "test:integration:otel": "export USE_OTEL=1 && run-s test:integration:v1 test:integration:v2", - "test:integration:legacy": "export USE_OTEL=0 && run-s test:integration:v1 test:integration:v2", + "test:integration": "run-s test:integration:v1 test:integration:v2", "test:integration:v1": "run-s test:integration:clean test:integration:prepare test:integration:client test:integration:server", "test:integration:v2": "export REMIX_VERSION=2 && yarn test:integration:v1", - "test:integration:ci": "run-s test:integration:ci:otel test:integration:ci:legacy", - "test:integration:ci:otel": "USE_OTEL=1 yarn test:integration:ci:common", - "test:integration:ci:legacy": "USE_OTEL=0 yarn test:integration:ci:common", - "test:integration:ci:common": "run-s test:integration:clean test:integration:prepare test:integration:client:ci test:integration:server", + "test:integration:ci": "run-s test:integration:clean test:integration:prepare test:integration:client:ci test:integration:server", "test:integration:prepare": "(cd test/integration && yarn install)", "test:integration:clean": "(cd test/integration && rimraf .cache node_modules build)", "test:integration:client": "yarn playwright install-deps && yarn playwright test test/integration/test/client/ --project='chromium'", @@ -113,8 +103,5 @@ "volta": { "extends": "../../package.json" }, - "sideEffects": [ - "./esm/index.server.js", - "./src/index.server.ts" - ] + "sideEffects": ["./esm/index.server.js", "./src/index.server.ts"] } diff --git a/packages/remix/playwright.config.ts b/packages/remix/playwright.config.ts index 142272a44740..6177eeb8f4c7 100644 --- a/packages/remix/playwright.config.ts +++ b/packages/remix/playwright.config.ts @@ -13,9 +13,6 @@ const config: PlaywrightTestConfig = { // Note that 3 is a random number selected to work well with our CI setup workers: process.env.CI ? 3 : undefined, webServer: { - env: { - NODE_OPTIONS: process.env.USE_OTEL === '1' ? '--require ./instrument.server.cjs' : '', - }, command: '(cd test/integration/ && yarn build && yarn start)', port: 3000, }, diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index f6a5f5060dd9..a2c7a4d35ab8 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -169,8 +169,7 @@ export function getRemixDefaultIntegrations(options: RemixOptions): Integration[ return [ ...getDefaultNodeIntegrations(options as NodeOptions).filter(integration => integration.name !== 'Http'), httpIntegration(), - // eslint-disable-next-line deprecation/deprecation - options.autoInstrumentRemix ? remixIntegration() : undefined, + remixIntegration(), ].filter(int => int) as Integration[]; } @@ -202,7 +201,7 @@ export function init(options: RemixOptions): NodeClient | undefined { const client = nodeInit(options as NodeOptions); - instrumentServer(options); + instrumentServer(); return client; } diff --git a/packages/remix/src/utils/instrumentServer.ts b/packages/remix/src/utils/instrumentServer.ts index 797c295b0abf..7e09c1c406bb 100644 --- a/packages/remix/src/utils/instrumentServer.ts +++ b/packages/remix/src/utils/instrumentServer.ts @@ -1,21 +1,12 @@ -/* eslint-disable max-lines */ -import type { RequestEventData, Span, TransactionSource, WrappedFunction } from '@sentry/core'; +import type { RequestEventData, WrappedFunction } from '@sentry/core'; import { - SEMANTIC_ATTRIBUTE_SENTRY_OP, - SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, - SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, fill, - getActiveSpan, getClient, - getRootSpan, getTraceData, hasTracingEnabled, isNodeEnv, loadModule, logger, - setHttpStatus, - spanToJSON, - startSpan, winterCGRequestToRequestData, withIsolationScope, } from '@sentry/core'; @@ -23,8 +14,6 @@ import { continueTrace } from '@sentry/opentelemetry'; import { DEBUG_BUILD } from './debug-build'; import { captureRemixServerException, errorHandleDataFunction, errorHandleDocumentRequestFunction } from './errors'; import { getFutureFlagsServer, getRemixVersionFromBuild } from './futureFlags'; -import type { RemixOptions } from './remixOptions'; -import { createRoutes, getTransactionName } from './utils'; import { extractData, isDeferredData, isResponse, isRouteErrorResponse, json } from './vendor/response'; import type { AppData, @@ -38,7 +27,6 @@ import type { RemixRequest, RequestHandler, ServerBuild, - ServerRoute, ServerRouteManifest, } from './vendor/types'; @@ -99,7 +87,7 @@ export function wrapHandleErrorWithSentry( }; } -function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean, remixVersion?: number) { +function makeWrappedDocumentRequestFunction(remixVersion?: number) { return function (origDocumentRequestFunction: HandleDocumentRequestFunction): HandleDocumentRequestFunction { return async function ( this: unknown, @@ -119,86 +107,38 @@ function makeWrappedDocumentRequestFunction(autoInstrumentRemix?: boolean, remix const isRemixV2 = FUTURE_FLAGS?.v2_errorBoundary || remixVersion === 2; - if (!autoInstrumentRemix) { - const activeSpan = getActiveSpan(); - const rootSpan = activeSpan && getRootSpan(activeSpan); - - const name = rootSpan ? spanToJSON(rootSpan).description : undefined; - - return startSpan( - { - // If we don't have a root span, `onlyIfParent` will lead to the span not being created anyhow - // So we don't need to care too much about the fallback name, it's just for typing purposes.... - name: name || '', - onlyIfParent: true, - attributes: { - method: request.method, - url: request.url, - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.remix', - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'function.remix.document_request', - }, - }, - () => { - return errorHandleDocumentRequestFunction.call( - this, - origDocumentRequestFunction, - documentRequestContext, - isRemixV2, - ); - }, - ); - } else { - return errorHandleDocumentRequestFunction.call( - this, - origDocumentRequestFunction, - documentRequestContext, - isRemixV2, - ); - } + return errorHandleDocumentRequestFunction.call( + this, + origDocumentRequestFunction, + documentRequestContext, + isRemixV2, + ); }; }; } function makeWrappedDataFunction( origFn: DataFunction, - id: string, + _id: string, name: 'action' | 'loader', remixVersion: number, - autoInstrumentRemix?: boolean, ): DataFunction { return async function (this: unknown, args: DataFunctionArgs): Promise { const isRemixV2 = FUTURE_FLAGS?.v2_errorBoundary || remixVersion === 2; - - if (!autoInstrumentRemix) { - return startSpan( - { - op: `function.remix.${name}`, - name: id, - attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.ui.remix', - name, - }, - }, - (span: Span) => { - return errorHandleDataFunction.call(this, origFn, name, args, isRemixV2, span); - }, - ); - } else { - return errorHandleDataFunction.call(this, origFn, name, args, isRemixV2); - } + return errorHandleDataFunction.call(this, origFn, name, args, isRemixV2); }; } const makeWrappedAction = - (id: string, remixVersion: number, autoInstrumentRemix?: boolean) => + (id: string, remixVersion: number) => (origAction: DataFunction): DataFunction => { - return makeWrappedDataFunction(origAction, id, 'action', remixVersion, autoInstrumentRemix); + return makeWrappedDataFunction(origAction, id, 'action', remixVersion); }; const makeWrappedLoader = - (id: string, remixVersion: number, autoInstrumentRemix?: boolean) => + (id: string, remixVersion: number) => (origLoader: DataFunction): DataFunction => { - return makeWrappedDataFunction(origLoader, id, 'loader', remixVersion, autoInstrumentRemix); + return makeWrappedDataFunction(origLoader, id, 'loader', remixVersion); }; function getTraceAndBaggage(): { @@ -262,16 +202,7 @@ function makeWrappedRootLoader(remixVersion: number) { }; } -function wrapRequestHandler( - origRequestHandler: RequestHandler, - build: ServerBuild | (() => ServerBuild | Promise), - autoInstrumentRemix: boolean, -): RequestHandler { - let resolvedBuild: ServerBuild; - let routes: ServerRoute[]; - let name: string; - let source: TransactionSource; - +function wrapRequestHandler(origRequestHandler: RequestHandler): RequestHandler { return async function (this: unknown, request: RemixRequest, loadContext?: AppLoadContext): Promise { const upperCaseMethod = request.method.toUpperCase(); // We don't want to wrap OPTIONS and HEAD requests @@ -279,16 +210,6 @@ function wrapRequestHandler( return origRequestHandler.call(this, request, loadContext); } - if (!autoInstrumentRemix) { - if (typeof build === 'function') { - resolvedBuild = await build(); - } else { - resolvedBuild = build; - } - - routes = createRoutes(resolvedBuild.routes); - } - return withIsolationScope(async isolationScope => { const options = getClient()?.getOptions(); @@ -300,13 +221,6 @@ function wrapRequestHandler( DEBUG_BUILD && logger.warn('Failed to normalize Remix request'); } - if (!autoInstrumentRemix) { - const url = new URL(request.url); - [name, source] = getTransactionName(routes, url); - - isolationScope.setTransactionName(name); - } - isolationScope.setSDKProcessingMetadata({ normalizedRequest }); if (!options || !hasTracingEnabled(options)) { @@ -318,38 +232,15 @@ function wrapRequestHandler( sentryTrace: request.headers.get('sentry-trace') || '', baggage: request.headers.get('baggage') || '', }, - async () => { - if (!autoInstrumentRemix) { - return startSpan( - { - name, - attributes: { - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.http.remix', - [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'http.server', - method: request.method, - }, - }, - async span => { - const res = (await origRequestHandler.call(this, request, loadContext)) as Response; - - if (isResponse(res)) { - setHttpStatus(span, res.status); - } - - return res; - }, - ); - } - - return (await origRequestHandler.call(this, request, loadContext)) as Response; + () => { + return origRequestHandler.call(this, request, loadContext) as Promise; }, ); }); }; } -function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolean): ServerBuild { +function instrumentBuildCallback(build: ServerBuild): ServerBuild { const routes: ServerRouteManifest = {}; const remixVersion = getRemixVersionFromBuild(build); const wrappedEntry = { ...build.entry, module: { ...build.entry.module } }; @@ -360,7 +251,7 @@ function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolea // We should be able to wrap them, as they may not be wrapped before. const defaultExport = wrappedEntry.module.default as undefined | WrappedFunction; if (defaultExport && !defaultExport.__sentry_original__) { - fill(wrappedEntry.module, 'default', makeWrappedDocumentRequestFunction(autoInstrumentRemix, remixVersion)); + fill(wrappedEntry.module, 'default', makeWrappedDocumentRequestFunction(remixVersion)); } for (const [id, route] of Object.entries(build.routes)) { @@ -368,12 +259,12 @@ function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolea const routeAction = wrappedRoute.module.action as undefined | WrappedFunction; if (routeAction && !routeAction.__sentry_original__) { - fill(wrappedRoute.module, 'action', makeWrappedAction(id, remixVersion, autoInstrumentRemix)); + fill(wrappedRoute.module, 'action', makeWrappedAction(id, remixVersion)); } const routeLoader = wrappedRoute.module.loader as undefined | WrappedFunction; if (routeLoader && !routeLoader.__sentry_original__) { - fill(wrappedRoute.module, 'loader', makeWrappedLoader(id, remixVersion, autoInstrumentRemix)); + fill(wrappedRoute.module, 'loader', makeWrappedLoader(id, remixVersion)); } // Entry module should have a loader function to provide `sentry-trace` and `baggage` @@ -398,11 +289,7 @@ function instrumentBuildCallback(build: ServerBuild, autoInstrumentRemix: boolea */ export function instrumentBuild( build: ServerBuild | (() => ServerBuild | Promise), - options: RemixOptions, ): ServerBuild | (() => ServerBuild | Promise) { - // eslint-disable-next-line deprecation/deprecation - const autoInstrumentRemix = options?.autoInstrumentRemix || false; - if (typeof build === 'function') { return function () { const resolvedBuild = build(); @@ -411,33 +298,32 @@ export function instrumentBuild( return resolvedBuild.then(build => { FUTURE_FLAGS = getFutureFlagsServer(build); - return instrumentBuildCallback(build, autoInstrumentRemix); + return instrumentBuildCallback(build); }); } else { FUTURE_FLAGS = getFutureFlagsServer(resolvedBuild); - return instrumentBuildCallback(resolvedBuild, autoInstrumentRemix); + return instrumentBuildCallback(resolvedBuild); } }; } else { FUTURE_FLAGS = getFutureFlagsServer(build); - return instrumentBuildCallback(build, autoInstrumentRemix); + return instrumentBuildCallback(build); } } -const makeWrappedCreateRequestHandler = (options: RemixOptions) => +const makeWrappedCreateRequestHandler = () => function (origCreateRequestHandler: CreateRequestHandlerFunction): CreateRequestHandlerFunction { return function ( this: unknown, build: ServerBuild | (() => Promise), ...args: unknown[] ): RequestHandler { - const newBuild = instrumentBuild(build, options); + const newBuild = instrumentBuild(build); const requestHandler = origCreateRequestHandler.call(this, newBuild, ...args); - // eslint-disable-next-line deprecation/deprecation - return wrapRequestHandler(requestHandler, newBuild, options.autoInstrumentRemix || false); + return wrapRequestHandler(requestHandler); }; }; @@ -445,7 +331,7 @@ const makeWrappedCreateRequestHandler = (options: RemixOptions) => * Monkey-patch Remix's `createRequestHandler` from `@remix-run/server-runtime` * which Remix Adapters (https://remix.run/docs/en/v1/api/remix) use underneath. */ -export function instrumentServer(options: RemixOptions): void { +export function instrumentServer(): void { const pkg = loadModule<{ createRequestHandler: CreateRequestHandlerFunction; }>('@remix-run/server-runtime'); @@ -456,5 +342,5 @@ export function instrumentServer(options: RemixOptions): void { return; } - fill(pkg, 'createRequestHandler', makeWrappedCreateRequestHandler(options)); + fill(pkg, 'createRequestHandler', makeWrappedCreateRequestHandler()); } diff --git a/packages/remix/src/utils/remixOptions.ts b/packages/remix/src/utils/remixOptions.ts index 58e8ae74b1d2..e65305c7696f 100644 --- a/packages/remix/src/utils/remixOptions.ts +++ b/packages/remix/src/utils/remixOptions.ts @@ -4,22 +4,4 @@ import type { BrowserOptions } from '@sentry/react'; export type RemixOptions = (Options | BrowserOptions | NodeOptions) & { captureActionFormDataKeys?: Record; -} & ( - | { - /** - * Enables OpenTelemetry Remix instrumentation. - * - * Note: This option will be the default behavior and will be removed in the next major version. - */ - autoInstrumentRemix?: true; - } - | { - /** - * Enables OpenTelemetry Remix instrumentation - * - * @deprecated Setting this option to `false` is deprecated as the next major version will default to behaving as if this option were `true` and the option itself will be removed. - * It is recommended to set this option to `true`. - */ - autoInstrumentRemix?: false; - } - ); +}; diff --git a/packages/remix/src/utils/utils.ts b/packages/remix/src/utils/utils.ts index 221ae4cf8e6c..bb936f0a4c38 100644 --- a/packages/remix/src/utils/utils.ts +++ b/packages/remix/src/utils/utils.ts @@ -1,9 +1,7 @@ import type { DataFunctionArgs } from '@remix-run/node'; import { logger } from '@sentry/core'; -import type { Span, TransactionSource } from '@sentry/core'; +import type { Span } from '@sentry/core'; import { DEBUG_BUILD } from './debug-build'; -import { getRequestMatch, matchServerRoutes } from './vendor/response'; -import type { ServerRoute, ServerRouteManifest } from './vendor/types'; /** * @@ -25,27 +23,3 @@ export async function storeFormDataKeys(args: DataFunctionArgs, span: Span): Pro DEBUG_BUILD && logger.warn('Failed to read FormData from request', e); } } - -/** - * Get transaction name from routes and url - */ -export function getTransactionName(routes: ServerRoute[], url: URL): [string, TransactionSource] { - const matches = matchServerRoutes(routes, url.pathname); - const match = matches && getRequestMatch(url, matches); - return match === null ? [url.pathname, 'url'] : [match.route.id || 'no-route-id', 'route']; -} - -/** - * Creates routes from the server route manifest - * - * @param manifest - * @param parentId - */ -export function createRoutes(manifest: ServerRouteManifest, parentId?: string): ServerRoute[] { - return Object.entries(manifest) - .filter(([, route]) => route.parentId === parentId) - .map(([id, route]) => ({ - ...route, - children: createRoutes(manifest, id), - })); -} diff --git a/packages/remix/test/integration/app_v1/entry.server.tsx b/packages/remix/test/integration/app_v1/entry.server.tsx index 9ecf5f467588..6db43d935cdc 100644 --- a/packages/remix/test/integration/app_v1/entry.server.tsx +++ b/packages/remix/test/integration/app_v1/entry.server.tsx @@ -1,7 +1,3 @@ -if (process.env.USE_OTEL !== '1') { - require('../instrument.server.cjs'); -} - import type { EntryContext } from '@remix-run/node'; import { RemixServer } from '@remix-run/react'; import { renderToString } from 'react-dom/server'; diff --git a/packages/remix/test/integration/app_v2/entry.server.tsx b/packages/remix/test/integration/app_v2/entry.server.tsx index 968ec19a5f59..86b0312eb92f 100644 --- a/packages/remix/test/integration/app_v2/entry.server.tsx +++ b/packages/remix/test/integration/app_v2/entry.server.tsx @@ -1,7 +1,3 @@ -if (process.env.USE_OTEL !== '1') { - require('../instrument.server.cjs'); -} - import * as Sentry from '@sentry/remix'; import type { EntryContext } from '@remix-run/node'; diff --git a/packages/remix/test/integration/instrument.server.cjs b/packages/remix/test/integration/instrument.server.cjs index 5e1d9e31ab46..199d4e309c41 100644 --- a/packages/remix/test/integration/instrument.server.cjs +++ b/packages/remix/test/integration/instrument.server.cjs @@ -6,5 +6,4 @@ Sentry.init({ tracePropagationTargets: ['example.org'], // Disabling to test series of envelopes deterministically. autoSessionTracking: false, - autoInstrumentRemix: process.env.USE_OTEL === '1', }); diff --git a/packages/remix/vitest.config.ts b/packages/remix/vitest.config.ts index 23c2383b9e8b..083616e28042 100644 --- a/packages/remix/vitest.config.ts +++ b/packages/remix/vitest.config.ts @@ -1,13 +1,11 @@ import { defineConfig } from 'vitest/config'; -const useOtel = process.env.USE_OTEL === '1'; - export default defineConfig({ test: { globals: true, disableConsoleIntercept: true, silent: false, - setupFiles: useOtel ? './test/integration/instrument.server.cjs' : undefined, - include: useOtel ? ['**/instrumentation-otel/*.test.ts'] : ['**/instrumentation-legacy/*.test.ts'], + setupFiles: './test/integration/instrument.server.cjs', + include: ['**/instrumentation-otel/*.test.ts'], }, });