From 120195731fb898184141ee4a2852eee2d39c6cbf Mon Sep 17 00:00:00 2001 From: Luca Forstner <luca.forstner@sentry.io> Date: Tue, 25 Mar 2025 11:17:35 +0100 Subject: [PATCH 1/2] feat: Always truncate stored breadcrumb messages to 2kb --- packages/core/src/scope.ts | 5 ++++- packages/core/test/lib/scope.test.ts | 6 +++++ packages/node/src/integrations/console.ts | 3 +-- .../node/test/integration/console.test.ts | 22 ------------------- 4 files changed, 11 insertions(+), 25 deletions(-) diff --git a/packages/core/src/scope.ts b/packages/core/src/scope.ts index a302e5a14c34..1b432bf94148 100644 --- a/packages/core/src/scope.ts +++ b/packages/core/src/scope.ts @@ -24,6 +24,7 @@ import { isPlainObject } from './utils-hoist/is'; import { logger } from './utils-hoist/logger'; import { uuid4 } from './utils-hoist/misc'; import { generateTraceId } from './utils-hoist/propagationContext'; +import { truncate } from './utils-hoist/string'; import { dateTimestampInSeconds } from './utils-hoist/time'; import { merge } from './utils/merge'; import { _getSpanForScope, _setSpanForScope } from './utils/spanOnScope'; @@ -474,8 +475,10 @@ export class Scope { return this; } - const mergedBreadcrumb = { + const mergedBreadcrumb: Breadcrumb = { timestamp: dateTimestampInSeconds(), + // Breadcrumb messages can theoretically be infinitely large and they're held in memory so we truncate them not to leak (too much) memory + message: breadcrumb.message ? truncate(breadcrumb.message, 2048) : breadcrumb.message, ...breadcrumb, }; diff --git a/packages/core/test/lib/scope.test.ts b/packages/core/test/lib/scope.test.ts index 4b27eff42824..87dcf9315ba9 100644 --- a/packages/core/test/lib/scope.test.ts +++ b/packages/core/test/lib/scope.test.ts @@ -186,6 +186,12 @@ describe('Scope', () => { expect(scope['_breadcrumbs']).toHaveLength(111); }); + test('addBreadcrumb will truncate the stored messages', () => { + const scope = new Scope(); + scope.addBreadcrumb({ message: 'A'.repeat(10_000) }); + expect(scope['_breadcrumbs'][0]?.message).toBe(`${'A'.repeat(2048)}...`); + }); + test('setLevel', () => { const scope = new Scope(); scope.setLevel('fatal'); diff --git a/packages/node/src/integrations/console.ts b/packages/node/src/integrations/console.ts index 5e5e6ac414d9..d1bb0463551e 100644 --- a/packages/node/src/integrations/console.ts +++ b/packages/node/src/integrations/console.ts @@ -5,7 +5,6 @@ import { defineIntegration, getClient, severityLevelFromString, - truncate, } from '@sentry/core'; const INTEGRATION_NAME = 'Console'; @@ -26,7 +25,7 @@ export const consoleIntegration = defineIntegration(() => { { category: 'console', level: severityLevelFromString(level), - message: truncate(util.format.apply(undefined, args), 2048), // 2KB + message: util.format.apply(undefined, args), }, { input: [...args], diff --git a/packages/node/test/integration/console.test.ts b/packages/node/test/integration/console.test.ts index 401dffd34819..691ccd4397ee 100644 --- a/packages/node/test/integration/console.test.ts +++ b/packages/node/test/integration/console.test.ts @@ -36,26 +36,4 @@ describe('Console integration', () => { }, ); }); - - 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', - }, - ); - }); }); From f529da06d71b95052d179da5ece57f1d100a9564 Mon Sep 17 00:00:00 2001 From: Luca Forstner <luca.forstner@sentry.io> Date: Tue, 25 Mar 2025 12:45:57 +0100 Subject: [PATCH 2/2] actually override --- packages/core/src/scope.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/scope.ts b/packages/core/src/scope.ts index 1b432bf94148..d10b9dea08d6 100644 --- a/packages/core/src/scope.ts +++ b/packages/core/src/scope.ts @@ -477,9 +477,9 @@ export class Scope { const mergedBreadcrumb: Breadcrumb = { timestamp: dateTimestampInSeconds(), + ...breadcrumb, // Breadcrumb messages can theoretically be infinitely large and they're held in memory so we truncate them not to leak (too much) memory message: breadcrumb.message ? truncate(breadcrumb.message, 2048) : breadcrumb.message, - ...breadcrumb, }; this._breadcrumbs.push(mergedBreadcrumb);