diff --git a/static/app/gettingStartedDocs/bun/bun/index.tsx b/static/app/gettingStartedDocs/bun/bun/index.tsx
index a3722f3ad97c36..5c15b7742fbd2e 100644
--- a/static/app/gettingStartedDocs/bun/bun/index.tsx
+++ b/static/app/gettingStartedDocs/bun/bun/index.tsx
@@ -3,7 +3,7 @@ import {
feedbackOnboardingJsLoader,
replayOnboardingJsLoader,
} from 'sentry/gettingStartedDocs/javascript/jsLoader/jsLoader';
-import {getNodeLogsOnboarding} from 'sentry/utils/gettingStartedDocs/node';
+import {getNodeLogsOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
import {crashReport} from './crashReport';
import {onboarding} from './onboarding';
diff --git a/static/app/gettingStartedDocs/javascript/astro/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript/astro/agentMonitoring.tsx
index 750159f2f822ac..f423f3e687ed06 100644
--- a/static/app/gettingStartedDocs/javascript/astro/agentMonitoring.tsx
+++ b/static/app/gettingStartedDocs/javascript/astro/agentMonitoring.tsx
@@ -1,4 +1,4 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/utils/gettingStartedDocs/node';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
export const agentMonitoring = getNodeAgentMonitoringOnboarding({
packageName: '@sentry/astro',
diff --git a/static/app/gettingStartedDocs/javascript/nextjs.tsx b/static/app/gettingStartedDocs/javascript/nextjs.tsx
index c9e13b1ad7aa6e..7142dcaf47ce15 100644
--- a/static/app/gettingStartedDocs/javascript/nextjs.tsx
+++ b/static/app/gettingStartedDocs/javascript/nextjs.tsx
@@ -23,12 +23,12 @@ import {
getReplayVerifyStep,
} from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding';
import {featureFlag} from 'sentry/gettingStartedDocs/javascript/javascript/featureFlag';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
import {t, tct} from 'sentry/locale';
import {
getJavascriptFullStackOnboarding,
getJavascriptLogsFullStackOnboarding,
} from 'sentry/utils/gettingStartedDocs/javascript';
-import {getNodeAgentMonitoringOnboarding} from 'sentry/utils/gettingStartedDocs/node';
type Params = DocsParams;
diff --git a/static/app/gettingStartedDocs/javascript/nuxt.tsx b/static/app/gettingStartedDocs/javascript/nuxt.tsx
index 95e748b0b99872..531f3c77a25f99 100644
--- a/static/app/gettingStartedDocs/javascript/nuxt.tsx
+++ b/static/app/gettingStartedDocs/javascript/nuxt.tsx
@@ -23,12 +23,12 @@ import {
getReplayVerifyStep,
} from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding';
import {featureFlag} from 'sentry/gettingStartedDocs/javascript/javascript/featureFlag';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
import {t, tct, tctCode} from 'sentry/locale';
import {
getJavascriptLogsFullStackOnboarding,
getJavascriptProfilingOnboarding,
} from 'sentry/utils/gettingStartedDocs/javascript';
-import {getNodeAgentMonitoringOnboarding} from 'sentry/utils/gettingStartedDocs/node';
type Params = DocsParams;
diff --git a/static/app/gettingStartedDocs/javascript/react-router/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript/react-router/agentMonitoring.tsx
index 52dba4a21dced9..d51d08f49a97a4 100644
--- a/static/app/gettingStartedDocs/javascript/react-router/agentMonitoring.tsx
+++ b/static/app/gettingStartedDocs/javascript/react-router/agentMonitoring.tsx
@@ -1,4 +1,4 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/utils/gettingStartedDocs/node';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
export const agentMonitoring = getNodeAgentMonitoringOnboarding({
packageName: '@sentry/react-router',
diff --git a/static/app/gettingStartedDocs/javascript/remix.tsx b/static/app/gettingStartedDocs/javascript/remix.tsx
index 9262c57e7a473e..8ab98376eb096d 100644
--- a/static/app/gettingStartedDocs/javascript/remix.tsx
+++ b/static/app/gettingStartedDocs/javascript/remix.tsx
@@ -23,12 +23,12 @@ import {
getReplayVerifyStep,
} from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding';
import {featureFlag} from 'sentry/gettingStartedDocs/javascript/javascript/featureFlag';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
import {t, tct} from 'sentry/locale';
import {
getJavascriptFullStackOnboarding,
getJavascriptLogsFullStackOnboarding,
} from 'sentry/utils/gettingStartedDocs/javascript';
-import {getNodeAgentMonitoringOnboarding} from 'sentry/utils/gettingStartedDocs/node';
type Params = DocsParams;
diff --git a/static/app/gettingStartedDocs/javascript/solidstart/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript/solidstart/agentMonitoring.tsx
index a8d2e69c6fe6ee..cc154b059a7561 100644
--- a/static/app/gettingStartedDocs/javascript/solidstart/agentMonitoring.tsx
+++ b/static/app/gettingStartedDocs/javascript/solidstart/agentMonitoring.tsx
@@ -1,4 +1,4 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/utils/gettingStartedDocs/node';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
export const agentMonitoring = getNodeAgentMonitoringOnboarding({
packageName: '@sentry/solidstart',
diff --git a/static/app/gettingStartedDocs/javascript/sveltekit.tsx b/static/app/gettingStartedDocs/javascript/sveltekit.tsx
index 5d55c8fb3dac9e..4d5d64a950351e 100644
--- a/static/app/gettingStartedDocs/javascript/sveltekit.tsx
+++ b/static/app/gettingStartedDocs/javascript/sveltekit.tsx
@@ -23,12 +23,12 @@ import {
getReplayVerifyStep,
} from 'sentry/components/onboarding/gettingStartedDoc/utils/replayOnboarding';
import {featureFlag} from 'sentry/gettingStartedDocs/javascript/javascript/featureFlag';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
import {t, tct} from 'sentry/locale';
import {
getJavascriptFullStackOnboarding,
getJavascriptLogsFullStackOnboarding,
} from 'sentry/utils/gettingStartedDocs/javascript';
-import {getNodeAgentMonitoringOnboarding} from 'sentry/utils/gettingStartedDocs/node';
type Params = DocsParams;
diff --git a/static/app/gettingStartedDocs/javascript/tanstackstart-react/agentMonitoring.tsx b/static/app/gettingStartedDocs/javascript/tanstackstart-react/agentMonitoring.tsx
index 6485e1259204a9..e044f6055a8b4b 100644
--- a/static/app/gettingStartedDocs/javascript/tanstackstart-react/agentMonitoring.tsx
+++ b/static/app/gettingStartedDocs/javascript/tanstackstart-react/agentMonitoring.tsx
@@ -1,4 +1,4 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/utils/gettingStartedDocs/node';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
export const agentMonitoring = getNodeAgentMonitoringOnboarding({
packageName: '@sentry/tanstackstart-react',
diff --git a/static/app/gettingStartedDocs/node/awslambda/agentMonitoring.tsx b/static/app/gettingStartedDocs/node/awslambda/agentMonitoring.tsx
index c055f749aa2bbf..676c6136bcc5de 100644
--- a/static/app/gettingStartedDocs/node/awslambda/agentMonitoring.tsx
+++ b/static/app/gettingStartedDocs/node/awslambda/agentMonitoring.tsx
@@ -1,4 +1,4 @@
-import {getNodeAgentMonitoringOnboarding} from 'sentry/utils/gettingStartedDocs/node';
+import {getNodeAgentMonitoringOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
export const agentMonitoring = getNodeAgentMonitoringOnboarding({
packageName: '@sentry/aws-serverless',
diff --git a/static/app/gettingStartedDocs/node/awslambda/logs.tsx b/static/app/gettingStartedDocs/node/awslambda/logs.tsx
index f69a03db66997b..ba467ba7652203 100644
--- a/static/app/gettingStartedDocs/node/awslambda/logs.tsx
+++ b/static/app/gettingStartedDocs/node/awslambda/logs.tsx
@@ -1,4 +1,4 @@
-import {getNodeLogsOnboarding} from 'sentry/utils/gettingStartedDocs/node';
+import {getNodeLogsOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
export const logs = getNodeLogsOnboarding({
docsPlatform: 'aws-lambda',
diff --git a/static/app/gettingStartedDocs/node/awslambda/mcp.tsx b/static/app/gettingStartedDocs/node/awslambda/mcp.tsx
index fe69604c56cae9..e74ffc0bdc8e6c 100644
--- a/static/app/gettingStartedDocs/node/awslambda/mcp.tsx
+++ b/static/app/gettingStartedDocs/node/awslambda/mcp.tsx
@@ -1,4 +1,4 @@
-import {getNodeMcpOnboarding} from 'sentry/utils/gettingStartedDocs/node';
+import {getNodeMcpOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
export const mcp = getNodeMcpOnboarding({
packageName: '@sentry/aws-serverless',
diff --git a/static/app/gettingStartedDocs/node/awslambda/onboarding.tsx b/static/app/gettingStartedDocs/node/awslambda/onboarding.tsx
index 9cc3c32e1b32b4..0a043fff092adc 100644
--- a/static/app/gettingStartedDocs/node/awslambda/onboarding.tsx
+++ b/static/app/gettingStartedDocs/node/awslambda/onboarding.tsx
@@ -4,8 +4,8 @@ import type {OnboardingConfig} from 'sentry/components/onboarding/gettingStarted
import {getUploadSourceMapsStep} from 'sentry/components/onboarding/gettingStartedDoc/utils';
import {AwsLambdaArn} from 'sentry/gettingStartedDocs/node/awslambda/awslambdaArnSelector';
import {InstallationMethod} from 'sentry/gettingStartedDocs/node/awslambda/utils';
+import {getInstallCodeBlock} from 'sentry/gettingStartedDocs/node/node/utils';
import {t, tct} from 'sentry/locale';
-import {getInstallCodeBlock} from 'sentry/utils/gettingStartedDocs/node';
import type {Params, PlatformOptions} from './utils';
diff --git a/static/app/gettingStartedDocs/node/awslambda/profiling.tsx b/static/app/gettingStartedDocs/node/awslambda/profiling.tsx
index efb58d0806f566..7efff18ef0d52c 100644
--- a/static/app/gettingStartedDocs/node/awslambda/profiling.tsx
+++ b/static/app/gettingStartedDocs/node/awslambda/profiling.tsx
@@ -1,4 +1,4 @@
-import {getNodeProfilingOnboarding} from 'sentry/utils/gettingStartedDocs/node';
+import {getNodeProfilingOnboarding} from 'sentry/gettingStartedDocs/node/node/utils';
export const profiling = getNodeProfilingOnboarding({
packageName: '@sentry/aws-serverless',
diff --git a/static/app/utils/gettingStartedDocs/node.tsx b/static/app/utils/gettingStartedDocs/node.tsx
deleted file mode 100644
index ed6beca536a39f..00000000000000
--- a/static/app/utils/gettingStartedDocs/node.tsx
+++ /dev/null
@@ -1,917 +0,0 @@
-import {ExternalLink} from 'sentry/components/core/link';
-import type {
- BasePlatformOptions,
- ContentBlock,
- DocsParams,
- OnboardingConfig,
-} from 'sentry/components/onboarding/gettingStartedDoc/types';
-import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types';
-import {t, tct} from 'sentry/locale';
-
-function getInstallSnippet({
- params,
- packageManager,
- additionalPackages = [],
- packageName = '@sentry/node',
-}: {
- packageManager: 'npm' | 'yarn' | 'pnpm';
- params: DocsParams;
- additionalPackages?: Array<`@sentry/${string}`>;
- packageName?: `@sentry/${string}`;
-}) {
- let packages = [packageName];
- if (params.isProfilingSelected) {
- packages.push('@sentry/profiling-node');
- }
- packages = packages.concat(additionalPackages);
-
- if (packageManager === 'yarn') {
- return `yarn add ${packages.join(' ')}`;
- }
-
- if (packageManager === 'pnpm') {
- return `pnpm add ${packages.join(' ')}`;
- }
-
- return `npm install ${packages.join(' ')} --save`;
-}
-
-export function getInstallCodeBlock(
- params: DocsParams,
- {
- packageName = '@sentry/node',
- additionalPackages,
- }: {
- additionalPackages?: Array<`@sentry/${string}`>;
- packageName?: `@sentry/${string}`;
- } = {}
-): ContentBlock {
- return {
- type: 'code',
- tabs: [
- {
- label: 'npm',
- language: 'bash',
- code: getInstallSnippet({
- params,
- additionalPackages,
- packageManager: 'npm',
- packageName,
- }),
- },
- {
- label: 'yarn',
- language: 'bash',
- code: getInstallSnippet({
- params,
- additionalPackages,
- packageManager: 'yarn',
- packageName,
- }),
- },
- {
- label: 'pnpm',
- language: 'bash',
- code: getInstallSnippet({
- params,
- additionalPackages,
- packageManager: 'pnpm',
- packageName,
- }),
- },
- ],
- };
-}
-
-function getImport(
- packageName: `@sentry/${string}`,
- defaultMode?: 'esm' | 'cjs'
-): string[] {
- return defaultMode === 'esm'
- ? [
- `// Import with \`const Sentry = require("${packageName}");\` if you are using CJS`,
- `import * as Sentry from "${packageName}"`,
- ]
- : [
- `// Import with \`import * as Sentry from "${packageName}"\` if you are using ESM`,
- `const Sentry = require("${packageName}");`,
- ];
-}
-
-function getProfilingImport(defaultMode?: 'esm' | 'cjs'): string {
- return defaultMode === 'esm'
- ? `import { nodeProfilingIntegration } from "@sentry/profiling-node";`
- : `const { nodeProfilingIntegration } = require("@sentry/profiling-node");`;
-}
-
-/**
- * Import Snippet for the Node and Serverless SDKs without other packages (like profiling).
- */
-export function getSentryImportSnippet(
- packageName: `@sentry/${string}`,
- defaultMode?: 'esm' | 'cjs'
-): string {
- return getImport(packageName, defaultMode).join('\n');
-}
-
-export function getImportInstrumentSnippet(
- defaultMode?: 'esm' | 'cjs',
- fileExtension = 'js'
-): string {
- const filename = `instrument.${fileExtension}`;
-
- return defaultMode === 'esm'
- ? `// IMPORTANT: Make sure to import \`${filename}\` at the top of your file.
-// If you're using CommonJS (CJS) syntax, use \`require("./${filename}");\`
-import "./${filename}";`
- : `// IMPORTANT: Make sure to import \`${filename}\` at the top of your file.
-// If you're using ECMAScript Modules (ESM) syntax, use \`import "./${filename}";\`
-require("./${filename}");`;
-}
-
-const libraryMap = {
- node: '@sentry/node',
- aws: '@sentry/aws-serverless',
- gpc: '@sentry/google-cloud-serverless',
- nestjs: '@sentry/nestjs',
-} as const;
-
-function getDefaultNodeImports({
- params,
- sdkImport,
- defaultMode,
-}: {
- params: DocsParams;
- sdkImport: 'node' | 'aws' | 'gpc' | 'nestjs' | null;
- defaultMode?: 'esm' | 'cjs';
-}) {
- if (sdkImport === null || !libraryMap[sdkImport]) {
- return '';
- }
- const imports: string[] = getImport(libraryMap[sdkImport], defaultMode);
-
- if (params.isProfilingSelected) {
- imports.push(getProfilingImport(defaultMode));
- }
- return imports.join('\n');
-}
-
-/**
- * Returns the init() with the necessary imports. It is possible to omit the imports.
- */
-export const getSdkInitSnippet = (
- params: DocsParams,
- sdkImport: 'node' | 'aws' | 'gpc' | 'nestjs' | null,
- defaultMode?: 'esm' | 'cjs'
-) => `${getDefaultNodeImports({params, sdkImport, defaultMode})}
-
-Sentry.init({
- dsn: "${params.dsn.public}",${
- params.isProfilingSelected
- ? `integrations: [
- nodeProfilingIntegration(),
- ],`
- : ''
- }${
- params.isLogsSelected
- ? `
-
- // Send structured logs to Sentry
- enableLogs: true,`
- : ''
- }${
- params.isPerformanceSelected
- ? `
- // Tracing
- tracesSampleRate: 1.0, // Capture 100% of the transactions`
- : ''
- }${
- params.isProfilingSelected &&
- params.profilingOptions?.defaultProfilingMode !== 'continuous'
- ? `
- // Set sampling rate for profiling - this is evaluated only once per SDK.init call
- profilesSampleRate: 1.0,`
- : ''
- }${
- params.isProfilingSelected &&
- params.profilingOptions?.defaultProfilingMode === 'continuous'
- ? `
- // Set sampling rate for profiling - this is evaluated only once per SDK.init call
- profileSessionSampleRate: 1.0,
- // Trace lifecycle automatically enables profiling during active traces
- profileLifecycle: 'trace',`
- : ''
- }
- // Setting this option to true will send default PII data to Sentry.
- // For example, automatic IP address collection on events
- sendDefaultPii: true,
- });${
- params.isProfilingSelected &&
- params.profilingOptions?.defaultProfilingMode === 'continuous'
- ? `
-
-// Profiling happens automatically after setting it up with \`Sentry.init()\`.
-// All spans (unless those discarded by sampling) will have profiling data attached to them.
-Sentry.startSpan({
- name: "My Span",
-}, () => {
- // The code executed here will be profiled
-});`
- : ''
- }`;
-
-export const getNodeProfilingOnboarding = ({
- packageName = '@sentry/node',
- profilingLifecycle = 'trace',
-}: {
- packageName?: `@sentry/${string}`;
- profilingLifecycle?: 'trace' | 'manual';
-} = {}): OnboardingConfig => ({
- install: params => [
- {
- type: StepType.INSTALL,
- content: [
- {
- type: 'text',
- text: tct(
- 'To enable profiling, add [code:@sentry/profiling-node] to your imports.',
- {
- code: ,
- }
- ),
- },
- getInstallCodeBlock(params, {
- packageName,
- }),
- ],
- },
- ],
- configure: params => [
- {
- type: StepType.CONFIGURE,
- content: [
- {
- type: 'text',
- text: tct(
- 'Set up the [code:nodeProfilingIntegration] in your [code:Sentry.init()] call.',
- {
- code: ,
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'Javascript',
- value: 'javascript',
- language: 'javascript',
- code: `
-const { nodeProfilingIntegration } = require("@sentry/profiling-node");
-
-Sentry.init({
- dsn: "${params.dsn.public}",
- integrations: [
- nodeProfilingIntegration(),
- ],${
- params.profilingOptions?.defaultProfilingMode === 'continuous'
- ? profilingLifecycle === 'trace'
- ? `
- // Tracing must be enabled for profiling to work
- tracesSampleRate: 1.0,
- // Set sampling rate for profiling - this is evaluated only once per SDK.init call
- profileSessionSampleRate: 1.0,
- // Trace lifecycle automatically enables profiling during active traces
- profileLifecycle: 'trace',`
- : `
- // Tracing is not required for profiling to work
- // but for the best experience we recommend enabling it
- tracesSampleRate: 1.0,
- // Set sampling rate for profiling - this is evaluated only once per SDK.init call
- profileSessionSampleRate: 1.0,`
- : `
- // Tracing must be enabled for profiling to work
- tracesSampleRate: 1.0,
- // Set sampling rate for profiling - this is evaluated only once per SDK.init call
- profilesSampleRate: 1.0,`
- }
-
- // Setting this option to true will send default PII data to Sentry.
- // For example, automatic IP address collection on events
- sendDefaultPii: true,
-});${
- params.profilingOptions?.defaultProfilingMode === 'continuous' &&
- profilingLifecycle === 'trace'
- ? `
-
-// Profiling happens automatically after setting it up with \`Sentry.init()\`.
-// All spans (unless those discarded by sampling) will have profiling data attached to them.
-Sentry.startSpan({
- name: "My Span",
-}, () => {
- // The code executed here will be profiled
-});`
- : ''
- }${
- params.profilingOptions?.defaultProfilingMode === 'continuous' &&
- profilingLifecycle === 'manual'
- ? `
-
-Sentry.profiler.startProfiler();
-// Code executed between these two calls will be profiled
-Sentry.profiler.stopProfiler();
- `
- : ''
- }`,
- },
- ],
- },
- {
- type: 'conditional',
- condition: profilingLifecycle === 'trace',
- content: [
- {
- type: 'text',
- text: tct(
- 'If you need more fine grained control over which spans are profiled, you can do so by [link:enabling manual lifecycle profiling].',
- {
- link: (
-
- ),
- }
- ),
- },
- ],
- },
- {
- type: 'text',
- text: tct(
- 'For more detailed information on profiling, see the [link:profiling documentation].',
- {
- link: (
-
- ),
- }
- ),
- },
- ],
- },
- ],
- verify: () => [
- {
- type: StepType.VERIFY,
- content: [
- {
- type: 'text',
- text: t(
- 'Verify that profiling is working correctly by simply using your application.'
- ),
- },
- ],
- },
- ],
-});
-
-export const getNodeAgentMonitoringOnboarding = ({
- packageName = '@sentry/node',
- configFileName,
-}: {
- configFileName?: string;
- packageName?: `@sentry/${string}`;
-} = {}): OnboardingConfig => ({
- install: params => [
- {
- type: StepType.INSTALL,
- content: [
- {
- type: 'text',
- text: tct(
- 'To enable agent monitoring, you need to install the Sentry SDK with a minimum version of [code:10.14.0].',
- {
- code: ,
- }
- ),
- },
- getInstallCodeBlock(params, {
- packageName,
- }),
- ],
- },
- ],
- configure: params => {
- const vercelContent: ContentBlock[] = [
- {
- type: 'text',
- text: tct(
- 'Add the [code:vercelAIIntegration] to your [code:Sentry.init()] call. This integration automatically instruments the [link:Vercel AI SDK] to capture spans for AI operations.',
- {
- code: ,
- link: (
-
- ),
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: configFileName ? configFileName : 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName).join('\n')}
-
-Sentry.init({
- dsn: "${params.dsn.public}",
- integrations: [
- // Add the Vercel AI SDK integration ${configFileName ? `to ${configFileName}` : ''}
- Sentry.vercelAIIntegration({
- recordInputs: true,
- recordOutputs: true,
- }),
- ],
- // Tracing must be enabled for agent monitoring to work
- tracesSampleRate: 1.0,
- sendDefaultPii: true,
-});`,
- },
- ],
- },
- {
- type: 'text',
- text: tct(
- 'To correctly capture spans, pass the [code:experimental_telemetry] object to every [code:generateText], [code:generateObject], and [code:streamText] function call. For more details, see the [link:AI SDK Telemetry Metadata docs].',
- {
- code: ,
- link: (
-
- ),
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `const { generateText } = require('ai');
-const { openai } = require('@ai-sdk/openai');
-
-const result = await generateText({
- model: openai("gpt-4o"),
- prompt: "Tell me a joke",
- experimental_telemetry: {
- isEnabled: true,
- recordInputs: true,
- recordOutputs: true,
- },
-});`,
- },
- ],
- },
- ];
-
- const anthropicContent: ContentBlock[] = [
- {
- type: 'text',
- text: tct(
- 'Add the [code:anthropicAIIntegration] to your [code:Sentry.init()] call. This integration automatically instruments the Anthropic SDK to capture spans for AI operations.',
- {code: }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName).join('\n')}
-
-Sentry.init({
- dsn: "${params.dsn.public}",
- integrations: [
- // Add the AnthropicAI integration
- Sentry.anthropicAIIntegration({
- recordInputs: true,
- recordOutputs: true,
- }),
- ],
- // Tracing must be enabled for agent monitoring to work
- tracesSampleRate: 1.0,
- sendDefaultPii: true,
-});`,
- },
- ],
- },
- ];
-
- const googleGenAIContent: ContentBlock[] = [
- {
- type: 'text',
- text: tct(
- 'Add the [code:googleGenAIIntegration] to your [code:Sentry.init()] call. This integration automatically instruments the Google Gen AI SDK to capture spans for AI operations.',
- {code: }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName).join('\n')}
-
-Sentry.init({
- dsn: "${params.dsn.public}",
- integrations: [
- // Add the Google Gen AI integration
- Sentry.googleGenAIIntegration({
- recordInputs: true,
- recordOutputs: true,
- }),
- ],
- // Tracing must be enabled for agent monitoring to work
- tracesSampleRate: 1.0,
- sendDefaultPii: true,
-});`,
- },
- ],
- },
- ];
-
- const openaiContent: ContentBlock[] = [
- {
- type: 'text',
- text: tct(
- 'Add the [code:openAIIntegration] to your [code:Sentry.init()] call. This integration automatically instruments the OpenAI SDK to capture spans for AI operations.',
- {code: }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName).join('\n')}
-
-Sentry.init({
- dsn: "${params.dsn.public}",
- integrations: [
- // Add the OpenAI integration
- Sentry.openAIIntegration({
- recordInputs: true,
- recordOutputs: true,
- }),
- ],
- // Tracing must be enabled for agent monitoring to work
- tracesSampleRate: 1.0,
- sendDefaultPii: true,
-});`,
- },
- ],
- },
- ];
-
- const manualContent: ContentBlock[] = [
- {
- type: 'text',
- text: tct(
- 'If you are not using a supported SDK integration, you can instrument your AI calls manually. See [link:manual instrumentation docs] for details.',
- {
- link: (
-
- ),
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `${getImport(packageName).join('\n')}
-
-// Create a span around your AI call
-await Sentry.startSpan({
- op: "gen_ai.chat",
- name: "chat gpt-4o",
- attributes: {
- "gen_ai.operation.name": "chat",
- "gen_ai.request.model": "gpt-4o",
- }
-}, async (span) => {
- // Call your AI function here
- // e.g., await generateText(...)
-
- // Set further span attributes after the AI call
- span.setAttribute("gen_ai.response.text", "");
-});`,
- },
- ],
- },
- ];
-
- const selected = (params.platformOptions as any)?.integration ?? 'vercel_ai';
- let content: ContentBlock[] = manualContent;
- if (selected === 'vercel_ai') {
- content = vercelContent;
- }
- if (selected === 'anthropic') {
- content = anthropicContent;
- }
- if (selected === 'openai') {
- content = openaiContent;
- }
- if (selected === 'google_genai') {
- content = googleGenAIContent;
- }
- return [
- {
- title: t('Configure'),
- content,
- },
- ];
- },
- verify: params => {
- const selected = (params.platformOptions as any)?.integration ?? 'vercel_ai';
- const content: ContentBlock[] = [
- {
- type: 'text',
- text: t('Verify that your instrumentation works by simply calling your LLM.'),
- },
- ];
-
- if (selected === 'anthropic') {
- content.push({
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `
-const Anthropic = require("anthropic");
-const anthropic = new Anthropic();
-
-const msg = await anthropic.messages.create({
-model: "claude-3-5-sonnet",
-messages: [{role: "user", content: "Tell me a joke"}],
-});`,
- },
- ],
- });
- }
- if (selected === 'openai') {
- content.push({
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `
-const OpenAI = require("openai");
-const client = new OpenAI();
-
-const response = await client.responses.create({
-model: "gpt-4o-mini",
-input: "Tell me a joke",
-});`,
- },
- ],
- });
- }
- if (selected === 'google_genai') {
- content.push({
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- language: 'javascript',
- code: `
-const GoogleGenAI = require("@google/genai").GoogleGenAI;
-const GEMINI_API_KEY = process.env.GEMINI_API_KEY;
-
-const ai = new GoogleGenAI({apiKey: GEMINI_API_KEY});
-
-const response = await ai.models.generateContent({
- model: 'gemini-2.0-flash-001',
- contents: 'Why is the sky blue?',
-});`,
- },
- ],
- });
- }
- return [
- {
- type: StepType.VERIFY,
- content,
- },
- ];
- },
-});
-
-export const getNodeMcpOnboarding = ({
- packageName = '@sentry/node',
-}: {
- packageName?: `@sentry/${string}`;
-} = {}): OnboardingConfig => ({
- install: params => [
- {
- type: StepType.INSTALL,
- content: [
- {
- type: 'text',
- text: tct(
- 'To enable MCP monitoring, you need to install the Sentry SDK with a minimum version of [code:9.44.0].',
- {
- code: ,
- }
- ),
- },
- getInstallCodeBlock(params, {
- packageName,
- }),
- ],
- },
- ],
- configure: params => [
- {
- type: StepType.CONFIGURE,
- content: [
- {
- type: 'text',
- text: tct('Initialize the Sentry SDK with [code:Sentry.init()] call.', {
- code: ,
- }),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- value: 'javascript',
- language: 'javascript',
- code: `${getImport(packageName).join('\n')}
-
-Sentry.init({
- dsn: "${params.dsn.public}",
- // Tracing must be enabled for MCP monitoring to work
- tracesSampleRate: 1.0,
- sendDefaultPii: true,
-});`,
- },
- ],
- },
- {
- type: 'text',
- text: tct(
- 'Wrap your MCP server in a [code:Sentry.wrapMcpServerWithSentry()] call. This will automatically capture spans for all MCP server interactions.',
- {
- code: ,
- }
- ),
- },
- {
- type: 'code',
- tabs: [
- {
- label: 'JavaScript',
- value: 'javascript',
- language: 'javascript',
- code: `
-const { McpServer } = require("@modelcontextprotocol/sdk");
-
-const server = Sentry.wrapMcpServerWithSentry(new McpServer({
- name: "my-mcp-server",
- version: "1.0.0",
-}));`,
- },
- ],
- },
- ],
- },
- ],
- verify: () => [
- {
- type: StepType.VERIFY,
- content: [
- {
- type: 'text',
- text: t(
- 'Verify that MCP monitoring is working correctly by triggering some MCP server interactions in your application.'
- ),
- },
- ],
- },
- ],
-});
-
-function getNodeLogsConfigureSnippet(
- params: DocsParams,
- packageName: `@sentry/${string}`
-): ContentBlock {
- return {
- type: 'code',
- language: 'javascript',
- code: `
-import * as Sentry from "${packageName}";
-
-Sentry.init({
- dsn: "${params.dsn.public}",
- integrations: [
- // send console.log, console.warn, and console.error calls as logs to Sentry
- Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] }),
- ],
- // Enable logs to be sent to Sentry
- enableLogs: true,
-});`,
- };
-}
-
-export const getNodeLogsOnboarding = <
- PlatformOptions extends BasePlatformOptions = BasePlatformOptions,
->({
- docsPlatform,
- packageName,
- generateConfigureSnippet = getNodeLogsConfigureSnippet,
-}: {
- docsPlatform: string;
- packageName: `@sentry/${string}`;
- generateConfigureSnippet?: typeof getNodeLogsConfigureSnippet;
-}): OnboardingConfig => ({
- install: (params: DocsParams) => [
- {
- type: StepType.INSTALL,
- content: [
- {
- type: 'text',
- text: tct(
- 'Add the Sentry SDK as a dependency. The minimum version of [packageName] that supports logs is [code:9.41.0].',
- {
- code: ,
- packageName: {packageName},
- }
- ),
- },
- getInstallCodeBlock(params, {packageName}),
- {
- type: 'text',
- text: tct(
- 'If you are on an older version of the SDK, follow our [link:migration guide] to upgrade.',
- {
- link: (
-
- ),
- }
- ),
- },
- ],
- },
- ],
- configure: (params: DocsParams) => [
- {
- type: StepType.CONFIGURE,
- content: [
- {
- type: 'text',
- text: tct(
- 'Enable Sentry logs by adding [code:enableLogs: true] to your [code:Sentry.init()] configuration.',
- {code: }
- ),
- },
- generateConfigureSnippet(params, packageName),
- {
- type: 'text',
- text: tct('For more detailed information, see the [link:logs documentation].', {
- link: (
-
- ),
- }),
- },
- ],
- },
- ],
- verify: () => [
- {
- type: StepType.VERIFY,
- content: [
- {
- type: 'text',
- text: t('Send a test log from your app to verify logs are arriving in Sentry.'),
- },
- {
- type: 'code',
- language: 'javascript',
- code: `import * as Sentry from "${packageName}";
-
-Sentry.logger.info('User triggered test log', { action: 'test_log' })`,
- },
- ],
- },
- ],
-});