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
5 changes: 5 additions & 0 deletions e2e-tests/tests/cloudflare-worker.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ describe('cloudflare-worker', () => {
whenAsked('Do you want to enable Tracing', {
timeout: 90_000, // package installation can take a while in CI
}).respondWith(KEYS.ENTER);
whenAsked('Do you want to enable Logs', {
timeout: 90_000, // package installation can take a while in CI
}).respondWith(KEYS.ENTER);
})
.whenAsked(
'Optionally add a project-scoped MCP server configuration for the Sentry MCP?',
Expand Down Expand Up @@ -82,6 +85,8 @@ describe('cloudflare-worker', () => {
'import * as Sentry from "@sentry/cloudflare";',
'export default Sentry.withSentry(env => ({',
'dsn: "https://public@dsn.ingest.sentry.io/1337",',
'tracesSampleRate: 1',
'enableLogs: true',
]);
});
});
7 changes: 7 additions & 0 deletions src/cloudflare/cloudflare-wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ async function runCloudflareWizardWithTelemetry(
)} to track the performance of your application?`,
enabledHint: 'recommended',
},
{
id: 'logs',
prompt: `Do you want to enable ${chalk.bold(
'Logs',
)} to send your application logs to Sentry?`,
enabledHint: 'recommended',
},
] as const);

await traceStep('Create Sentry initialization', async () => {
Expand Down
1 change: 1 addition & 0 deletions src/cloudflare/sdk-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export async function createSentryInitFile(
dsn: string,
selectedFeatures: {
performance: boolean;
logs: boolean;
},
): Promise<void> {
const entryPointFromConfig = getEntryPointFromWranglerConfig();
Expand Down
10 changes: 9 additions & 1 deletion src/cloudflare/templates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export function getCloudflareWorkerTemplate(
dsn: string,
selectedFeatures: {
performance: boolean;
logs: boolean;
},
): string {
let performanceOptions = '';
Expand All @@ -11,11 +12,18 @@ export function getCloudflareWorkerTemplate(
tracesSampleRate: 1,`;
}

let logsOptions = '';
if (selectedFeatures.logs) {
logsOptions = `
// Enable logs to be sent to Sentry
enableLogs: true,`;
}

return `import * as Sentry from '@sentry/cloudflare';

export default Sentry.withSentry(
(env) => ({
dsn: '${dsn}',${performanceOptions}
dsn: '${dsn}',${performanceOptions}${logsOptions}
}),
{
async fetch(request, env, ctx): Promise<Response> {
Expand Down
15 changes: 15 additions & 0 deletions src/cloudflare/wrap-worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export async function wrapWorkerWithSentry(
dsn: string,
selectedFeatures: {
performance: boolean;
logs: boolean;
},
): Promise<void> {
const workerAst = await loadFile(workerFilePath);
Expand Down Expand Up @@ -90,6 +91,7 @@ function createSentryConfigFunction(
dsn: string,
selectedFeatures: {
performance: boolean;
logs: boolean;
},
): t.ArrowFunctionExpression {
const configProperties: t.ObjectProperty[] = [
Expand All @@ -113,6 +115,19 @@ function createSentryConfigFunction(
configProperties.push(tracesSampleRateProperty);
}

if (selectedFeatures.logs) {
const enableLogsProperty = b.objectProperty(
b.identifier('enableLogs'),
b.booleanLiteral(true),
);

enableLogsProperty.comments = [
b.commentLine(' Enable logs to be sent to Sentry', true, false),
];

configProperties.push(enableLogsProperty);
}

const configObject = b.objectExpression(configProperties);

return b.arrowFunctionExpression([b.identifier('env')], configObject);
Expand Down
47 changes: 31 additions & 16 deletions test/cloudflare/__snapshots__/wrap-worker.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,6 @@ export default Sentry.withSentry(env => ({
});"
`;

exports[`wrapWorkerWithSentry > idempotency > does not wrap again if Sentry is already present 1`] = `
"import * as Sentry from '@sentry/cloudflare';

export default Sentry.withSentry(
(env) => ({
dsn: 'existing-dsn',
}),
{
async fetch(request, env, ctx): Promise<Response> {
return new Response('Already wrapped');
},
},
);
"
`;

exports[`wrapWorkerWithSentry > import handling > adds Sentry import at the beginning of the file 1`] = `
"import * as Sentry from "@sentry/cloudflare";
// Worker comment
Expand Down Expand Up @@ -108,6 +92,37 @@ export default Sentry.withSentry(env => ({
});"
`;

exports[`wrapWorkerWithSentry > logs > includes both tracesSampleRate and enableLogs when both are enabled 1`] = `
"import * as Sentry from "@sentry/cloudflare";
export default Sentry.withSentry(env => ({
dsn: "my-dsn",

// Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
tracesSampleRate: 1,

// Enable logs to be sent to Sentry
enableLogs: true
}), {
async fetch(request, env, ctx): Promise<Response> {
return new Response('Hello');
}
});"
`;

exports[`wrapWorkerWithSentry > logs > includes enableLogs when logs is enabled 1`] = `
"import * as Sentry from "@sentry/cloudflare";
export default Sentry.withSentry(env => ({
dsn: "my-dsn",

// Enable logs to be sent to Sentry
enableLogs: true
}), {
async fetch(request, env, ctx): Promise<Response> {
return new Response('Hello');
}
});"
`;

exports[`wrapWorkerWithSentry > performance monitoring > includes tracesSampleRate when performance is enabled 1`] = `
"import * as Sentry from "@sentry/cloudflare";
export default Sentry.withSentry(env => ({
Expand Down
36 changes: 34 additions & 2 deletions test/cloudflare/sdk-setup.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ describe('createSentryInitFile', () => {
const testDsn = 'https://example@sentry.io/123';
const testFeatures = {
performance: true,
logs: false,
};

beforeEach(() => {
Expand Down Expand Up @@ -155,12 +156,43 @@ describe('createSentryInitFile', () => {
.spyOn(wrapWorker, 'wrapWorkerWithSentry')
.mockResolvedValue(undefined);

await createSentryInitFile(testDsn, { performance: false });
await createSentryInitFile(testDsn, {
performance: false,
logs: false,
});

expect(wrapWorkerWithSentrySpy).toHaveBeenCalledWith(
path.join(tmpDir, defaultEntryPoint),
testDsn,
{ performance: false },
{ performance: false, logs: false },
);
});

it('passes logs feature flag correctly', async () => {
const wrapWorkerWithSentrySpy = vi
.spyOn(wrapWorker, 'wrapWorkerWithSentry')
.mockResolvedValue(undefined);

await createSentryInitFile(testDsn, { performance: false, logs: true });

expect(wrapWorkerWithSentrySpy).toHaveBeenCalledWith(
path.join(tmpDir, defaultEntryPoint),
testDsn,
{ performance: false, logs: true },
);
});

it('passes both feature flags correctly', async () => {
const wrapWorkerWithSentrySpy = vi
.spyOn(wrapWorker, 'wrapWorkerWithSentry')
.mockResolvedValue(undefined);

await createSentryInitFile(testDsn, { performance: true, logs: true });

expect(wrapWorkerWithSentrySpy).toHaveBeenCalledWith(
path.join(tmpDir, defaultEntryPoint),
testDsn,
{ performance: true, logs: true },
);
});
});
Expand Down
58 changes: 58 additions & 0 deletions test/cloudflare/templates.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ describe('Cloudflare code templates', () => {
it('generates worker template with performance monitoring enabled', () => {
const template = getCloudflareWorkerTemplate('my-dsn', {
performance: true,
logs: false,
});

expect(template).toMatchInlineSnapshot(`
Expand All @@ -31,6 +32,7 @@ describe('Cloudflare code templates', () => {
it('generates worker template with performance monitoring disabled', () => {
const template = getCloudflareWorkerTemplate('my-dsn', {
performance: false,
logs: false,
});

expect(template).toMatchInlineSnapshot(`
Expand All @@ -51,10 +53,65 @@ describe('Cloudflare code templates', () => {
`);
});

it('generates worker template with logs enabled', () => {
const template = getCloudflareWorkerTemplate('my-dsn', {
performance: false,
logs: true,
});

expect(template).toMatchInlineSnapshot(`
"import * as Sentry from '@sentry/cloudflare';

export default Sentry.withSentry(
(env) => ({
dsn: 'my-dsn',
// Enable logs to be sent to Sentry
enableLogs: true,
}),
{
async fetch(request, env, ctx): Promise<Response> {
// Your worker logic here
return new Response('Hello World!');
},
} satisfies ExportedHandler<Env>,
);
"
`);
});

it('generates worker template with both performance and logs enabled', () => {
const template = getCloudflareWorkerTemplate('my-dsn', {
performance: true,
logs: true,
});

expect(template).toMatchInlineSnapshot(`
"import * as Sentry from '@sentry/cloudflare';

export default Sentry.withSentry(
(env) => ({
dsn: 'my-dsn',
// Define how likely traces are sampled. Adjust this value in production, or use tracesSampler for greater control.
tracesSampleRate: 1,
// Enable logs to be sent to Sentry
enableLogs: true,
}),
{
async fetch(request, env, ctx): Promise<Response> {
// Your worker logic here
return new Response('Hello World!');
},
} satisfies ExportedHandler<Env>,
);
"
`);
});

it('includes the correct DSN', () => {
const dsn = 'https://example@sentry.io/123';
const template = getCloudflareWorkerTemplate(dsn, {
performance: true,
logs: false,
});

expect(template).toContain(`dsn: '${dsn}'`);
Expand All @@ -63,6 +120,7 @@ describe('Cloudflare code templates', () => {
it('wraps handler with Sentry.withSentry', () => {
const template = getCloudflareWorkerTemplate('my-dsn', {
performance: false,
logs: false,
});

expect(template).toContain('Sentry.withSentry');
Expand Down
Loading
Loading