Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions static/app/components/onboarding/productSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ export const platformProductAvailability = {
],
node: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
'node-connect': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
'node-express': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
'node-koa': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
python: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
'python-aiohttp': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
'python-awslambda': [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.PROFILING],
Expand Down
7 changes: 6 additions & 1 deletion static/app/gettingStartedDocs/node/express.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ describe('GettingStartedWithExpress', function () {
const {container} = render(<GettingStartedWithExpress dsn="test-dsn" />);

// Steps
for (const step of steps()) {
for (const step of steps({
installSnippet: 'test-install-snippet',
importContent: 'test-import-content',
initContent: 'test-init-content',
hasPerformanceMonitoring: true,
})) {
expect(
screen.getByRole('heading', {name: step.title ?? StepTitle[step.type]})
).toBeInTheDocument();
Expand Down
150 changes: 84 additions & 66 deletions static/app/gettingStartedDocs/node/express.tsx
Original file line number Diff line number Diff line change
@@ -1,44 +1,44 @@
import {Layout, LayoutProps} from 'sentry/components/onboarding/gettingStartedDoc/layout';
import {ModuleProps} from 'sentry/components/onboarding/gettingStartedDoc/sdkDocumentation';
import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
import {PlatformKey} from 'sentry/data/platformCategories';
import {t, tct} from 'sentry/locale';
import type {Organization} from 'sentry/types';

type StepProps = {
newOrg: boolean;
organization: Organization;
platformKey: PlatformKey;
projectId: string;
sentryInitContent: string;
};
import {
getDefaultInitParams,
getDefaultNodeImports,
getInstallSnippet,
getProductInitParams,
getProductIntegrations,
getProductSelectionMap,
joinWithIndentation,
} from 'sentry/utils/gettingStartedDocs/node';

interface StepProps {
hasPerformanceMonitoring: boolean;
importContent: string;
initContent: string;
installSnippet: string;
}

const performanceIntegrations: string[] = [
`// enable HTTP calls tracing
new Sentry.Integrations.Http({ tracing: true }),`,
`// enable Express.js middleware tracing
new Sentry.Integrations.Express({ app }),`,
'// enable HTTP calls tracing',
'new Sentry.Integrations.Http({ tracing: true }),',
'// enable Express.js middleware tracing',
'new Sentry.Integrations.Express({ app }),',
];

const performanceOtherConfig = `// Performance Monitoring
tracesSampleRate: 1.0, // Capture 100% of the transactions, reduce in production!`;

export const steps = ({
sentryInitContent,
}: Partial<StepProps> = {}): LayoutProps['steps'] => [
installSnippet,
importContent,
initContent,
hasPerformanceMonitoring,
}: StepProps): LayoutProps['steps'] => [
{
type: StepType.INSTALL,
description: t('Add the Sentry Node SDK as a dependency:'),
configurations: [
{
language: 'bash',
code: `
# Using yarn
yarn add @sentry/node

# Using npm
npm install --save @sentry/node
`,
code: installSnippet,
},
],
},
Expand All @@ -56,40 +56,41 @@ npm install --save @sentry/node
{
language: 'javascript',
code: `
import * as Sentry from "@sentry/node";
import express from "express";
${importContent}

// or using CommonJS
// const Sentry = require('@sentry/node');
// const express = require('express');
const app = express();

const app = express();
Sentry.init({
${initContent}
});

Sentry.init({
${sentryInitContent},
});
// The request handler must be the first middleware on the app
app.use(Sentry.Handlers.requestHandler());${
hasPerformanceMonitoring
? `

// Trace incoming requests
app.use(Sentry.Handlers.requestHandler());
app.use(Sentry.Handlers.tracingHandler());
// TracingHandler creates a trace for every incoming request
app.use(Sentry.Handlers.tracingHandler());`
: ''
}

// All your controllers should live here
app.get("/", function rootHandler(req, res) {
res.end("Hello world!");
});
// All your controllers should live here
app.get("/", function rootHandler(req, res) {
res.end("Hello world!");
});

// The error handler must be registered before any other error middleware and after all controllers
app.use(Sentry.Handlers.errorHandler());
// The error handler must be registered before any other error middleware and after all controllers
app.use(Sentry.Handlers.errorHandler());

// Optional fallthrough error handler
app.use(function onError(err, req, res, next) {
// The error id is attached to \`res.sentry\` to be returned
// and optionally displayed to the user for support.
res.statusCode = 500;
res.end(res.sentry + "\\n");
});
// Optional fallthrough error handler
app.use(function onError(err, req, res, next) {
// The error id is attached to \`res.sentry\` to be returned
// and optionally displayed to the user for support.
res.statusCode = 500;
res.end(res.sentry + "\\n");
});

app.listen(3000);
app.listen(3000);
`,
},
],
Expand All @@ -112,24 +113,41 @@ npm install --save @sentry/node
},
];

export function GettingStartedWithExpress({dsn, newOrg, platformKey}: ModuleProps) {
let sentryInitContent: string[] = [`dsn: "${dsn}",`];

const integrations = [...performanceIntegrations];
const otherConfigs = [performanceOtherConfig];

if (integrations.length > 0) {
sentryInitContent = sentryInitContent.concat('integrations: [', integrations, '],');
}

if (otherConfigs.length > 0) {
sentryInitContent = sentryInitContent.concat(otherConfigs);
}
export function GettingStartedWithExpress({
dsn,
newOrg,
platformKey,
activeProductSelection = [],
}: ModuleProps) {
const productSelection = getProductSelectionMap(activeProductSelection);

const installSnippet = getInstallSnippet({productSelection});
const imports = getDefaultNodeImports({productSelection});
imports.push('import express from "express";');

const integrations = [
...(productSelection['performance-monitoring'] ? performanceIntegrations : []),
...getProductIntegrations({productSelection}),
];

const integrationParam =
integrations.length > 0
? `integrations: [\n${joinWithIndentation(integrations)}\n],`
: null;

const initContent = joinWithIndentation([
...getDefaultInitParams({dsn}),
...(integrationParam ? [integrationParam] : []),
...getProductInitParams({productSelection}),
]);

return (
<Layout
steps={steps({
sentryInitContent: sentryInitContent.join('\n'),
installSnippet,
importContent: imports.join('\n'),
initContent,
hasPerformanceMonitoring: productSelection['performance-monitoring'],
})}
newOrg={newOrg}
platformKey={platformKey}
Expand Down
7 changes: 6 additions & 1 deletion static/app/gettingStartedDocs/node/koa.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@ describe('GettingStartedWithKoa', function () {
const {container} = render(<GettingStartedWithKoa dsn="test-dsn" />);

// Steps
for (const step of steps()) {
for (const step of steps({
installSnippet: 'test-install-snippet',
importContent: 'test-import-content',
initContent: 'test-init-content',
hasPerformanceMonitoring: true,
})) {
expect(
screen.getByRole('heading', {name: step.title ?? StepTitle[step.type]})
).toBeInTheDocument();
Expand Down
Loading