Skip to content

Commit 7191ebd

Browse files
authored
feat: Always truncate stored breadcrumb messages to 2kb (#15819)
We had this logic in the console instrumentation before but it probably makes sense to truncate all breadcrumbs to some degree for memory consumption reasons. Acts as prework for #15818 because if we don't truncate error messages they will end up as very big strings in breadcrumbs.
1 parent 05391d0 commit 7191ebd

File tree

4 files changed

+11
-25
lines changed

4 files changed

+11
-25
lines changed

packages/core/src/scope.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { isPlainObject } from './utils-hoist/is';
2424
import { logger } from './utils-hoist/logger';
2525
import { uuid4 } from './utils-hoist/misc';
2626
import { generateTraceId } from './utils-hoist/propagationContext';
27+
import { truncate } from './utils-hoist/string';
2728
import { dateTimestampInSeconds } from './utils-hoist/time';
2829
import { merge } from './utils/merge';
2930
import { _getSpanForScope, _setSpanForScope } from './utils/spanOnScope';
@@ -474,9 +475,11 @@ export class Scope {
474475
return this;
475476
}
476477

477-
const mergedBreadcrumb = {
478+
const mergedBreadcrumb: Breadcrumb = {
478479
timestamp: dateTimestampInSeconds(),
479480
...breadcrumb,
481+
// Breadcrumb messages can theoretically be infinitely large and they're held in memory so we truncate them not to leak (too much) memory
482+
message: breadcrumb.message ? truncate(breadcrumb.message, 2048) : breadcrumb.message,
480483
};
481484

482485
this._breadcrumbs.push(mergedBreadcrumb);

packages/core/test/lib/scope.test.ts

+6
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,12 @@ describe('Scope', () => {
186186
expect(scope['_breadcrumbs']).toHaveLength(111);
187187
});
188188

189+
test('addBreadcrumb will truncate the stored messages', () => {
190+
const scope = new Scope();
191+
scope.addBreadcrumb({ message: 'A'.repeat(10_000) });
192+
expect(scope['_breadcrumbs'][0]?.message).toBe(`${'A'.repeat(2048)}...`);
193+
});
194+
189195
test('setLevel', () => {
190196
const scope = new Scope();
191197
scope.setLevel('fatal');

packages/node/src/integrations/console.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import {
55
defineIntegration,
66
getClient,
77
severityLevelFromString,
8-
truncate,
98
} from '@sentry/core';
109

1110
const INTEGRATION_NAME = 'Console';
@@ -26,7 +25,7 @@ export const consoleIntegration = defineIntegration(() => {
2625
{
2726
category: 'console',
2827
level: severityLevelFromString(level),
29-
message: truncate(util.format.apply(undefined, args), 2048), // 2KB
28+
message: util.format.apply(undefined, args),
3029
},
3130
{
3231
input: [...args],

packages/node/test/integration/console.test.ts

-22
Original file line numberDiff line numberDiff line change
@@ -36,26 +36,4 @@ describe('Console integration', () => {
3636
},
3737
);
3838
});
39-
40-
it('should truncate breadcrumbs with more than 2 KB message size', () => {
41-
consoleIntegration().setup?.(getClient() as NodeClient);
42-
43-
const longMsg = 'A'.repeat(10_000);
44-
45-
// eslint-disable-next-line no-console
46-
console.log(longMsg);
47-
48-
expect(addBreadcrumbSpy).toHaveBeenCalledTimes(1);
49-
expect(addBreadcrumbSpy).toHaveBeenCalledWith(
50-
{
51-
category: 'console',
52-
level: 'log',
53-
message: `${'A'.repeat(2048)}...`,
54-
},
55-
{
56-
input: [longMsg],
57-
level: 'log',
58-
},
59-
);
60-
});
6139
});

0 commit comments

Comments
 (0)