diff --git a/packages/node/src/integrations/console.ts b/packages/node/src/integrations/console.ts index 5cd2eb2ce98a..4a7cea53ec90 100644 --- a/packages/node/src/integrations/console.ts +++ b/packages/node/src/integrations/console.ts @@ -1,11 +1,13 @@ import * as util from 'node:util'; import { addBreadcrumb, defineIntegration, getClient } from '@sentry/core'; -import type { IntegrationFn } from '@sentry/types'; -import { addConsoleInstrumentationHandler, severityLevelFromString } from '@sentry/utils'; +import { addConsoleInstrumentationHandler, severityLevelFromString, truncate } from '@sentry/utils'; const INTEGRATION_NAME = 'Console'; -const _consoleIntegration = (() => { +/** + * Capture console logs as breadcrumbs. + */ +export const consoleIntegration = defineIntegration(() => { return { name: INTEGRATION_NAME, setup(client) { @@ -18,7 +20,7 @@ const _consoleIntegration = (() => { { category: 'console', level: severityLevelFromString(level), - message: util.format.apply(undefined, args), + message: truncate(util.format.apply(undefined, args), 2048), // 2KB }, { input: [...args], @@ -28,9 +30,4 @@ const _consoleIntegration = (() => { }); }, }; -}) satisfies IntegrationFn; - -/** - * Capture console logs as breadcrumbs. - */ -export const consoleIntegration = defineIntegration(_consoleIntegration); +}); diff --git a/packages/node/test/integration/console.test.ts b/packages/node/test/integration/console.test.ts new file mode 100644 index 000000000000..d869959ebdfc --- /dev/null +++ b/packages/node/test/integration/console.test.ts @@ -0,0 +1,60 @@ +import * as SentryCore from '@sentry/core'; +import { resetInstrumentationHandlers } from '@sentry/utils'; +import { getClient } from '../../src'; +import type { NodeClient } from '../../src'; +import { consoleIntegration } from '../../src/integrations/console'; + +const addBreadcrumbSpy = jest.spyOn(SentryCore, 'addBreadcrumb'); + +jest.spyOn(console, 'log').mockImplementation(() => { + // noop so that we don't spam the logs +}); + +afterEach(() => { + jest.clearAllMocks(); + resetInstrumentationHandlers(); +}); + +describe('Console integration', () => { + it('should add a breadcrumb on console.log', () => { + consoleIntegration().setup?.(getClient() as NodeClient); + + // eslint-disable-next-line no-console + console.log('test'); + + expect(addBreadcrumbSpy).toHaveBeenCalledTimes(1); + expect(addBreadcrumbSpy).toHaveBeenCalledWith( + { + category: 'console', + level: 'log', + message: 'test', + }, + { + input: ['test'], + level: 'log', + }, + ); + }); + + it('should truncate breadcrumbs with more than 2 KB message size', () => { + consoleIntegration().setup?.(getClient() as NodeClient); + + const longMsg = 'A'.repeat(10_000); + + // eslint-disable-next-line no-console + console.log(longMsg); + + expect(addBreadcrumbSpy).toHaveBeenCalledTimes(1); + expect(addBreadcrumbSpy).toHaveBeenCalledWith( + { + category: 'console', + level: 'log', + message: `${'A'.repeat(2048)}...`, + }, + { + input: [longMsg], + level: 'log', + }, + ); + }); +});