Skip to content

Commit 2c51838

Browse files
authored
feat: Option to disable all breadcrumbs and stack. (#770)
When using browser-telemetry for just metrics it is probably best to disable all breadcrumbs and stack information. This PR makes it simple to do so. ``` initTelemetry({breadcrumbs: false, stack: false}); ```
1 parent 24d3bba commit 2c51838

File tree

7 files changed

+276
-158
lines changed

7 files changed

+276
-158
lines changed

packages/telemetry/browser-telemetry/__tests__/BrowserTelemetryImpl.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ const defaultOptions: ParsedOptions = {
2626
filters: [],
2727
},
2828
stack: {
29+
enabled: true,
2930
source: {
3031
beforeLines: 5,
3132
afterLines: 5,

packages/telemetry/browser-telemetry/__tests__/options.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,27 @@ it('handles an empty configuration', () => {
1616
expect(outOptions).toEqual(defaultOptions());
1717
});
1818

19+
it('disables all breadcrumb options when breadcrumbs is false', () => {
20+
const outOptions = parse({
21+
breadcrumbs: false,
22+
});
23+
24+
expect(outOptions.breadcrumbs).toEqual({
25+
maxBreadcrumbs: 0,
26+
click: false,
27+
evaluations: false,
28+
flagChange: false,
29+
keyboardInput: false,
30+
http: {
31+
instrumentFetch: false,
32+
instrumentXhr: false,
33+
customUrlFilter: undefined,
34+
},
35+
filters: [],
36+
});
37+
expect(mockLogger.warn).not.toHaveBeenCalled();
38+
});
39+
1940
it('can set all options at once', () => {
2041
const breadcrumbFilter = (breadcrumb: Breadcrumb) => breadcrumb;
2142
const errorFilter = (error: ErrorData) => error;
@@ -47,6 +68,7 @@ it('can set all options at once', () => {
4768
filters: expect.arrayContaining([breadcrumbFilter]),
4869
},
4970
stack: {
71+
enabled: true,
5072
source: {
5173
beforeLines: 3,
5274
afterLines: 3,
@@ -473,3 +495,19 @@ it('accepts valid error filters array', () => {
473495
expect(outOptions.errorFilters).toEqual(errorFilters);
474496
expect(mockLogger.warn).not.toHaveBeenCalled();
475497
});
498+
499+
it('disables all stack options when stack is false', () => {
500+
const outOptions = parse({
501+
stack: false,
502+
});
503+
504+
expect(outOptions.stack).toEqual({
505+
enabled: false,
506+
source: {
507+
beforeLines: 0,
508+
afterLines: 0,
509+
maxLineLength: 0,
510+
},
511+
});
512+
expect(mockLogger.warn).not.toHaveBeenCalled();
513+
});

packages/telemetry/browser-telemetry/__tests__/stack/StackParser.test.ts

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {
1+
import parse, {
22
getLines,
33
getSrcLines,
44
processUrlToFileName,
@@ -58,6 +58,7 @@ describe('given an input stack frame', () => {
5858
it('can produce a full stack source in the output frame', () => {
5959
expect(
6060
getSrcLines(inputFrame, {
61+
enabled: true,
6162
source: {
6263
beforeLines: 2,
6364
afterLines: 2,
@@ -74,6 +75,7 @@ describe('given an input stack frame', () => {
7475
it('can trim all the lines', () => {
7576
expect(
7677
getSrcLines(inputFrame, {
78+
enabled: true,
7779
source: {
7880
beforeLines: 2,
7981
afterLines: 2,
@@ -90,6 +92,7 @@ describe('given an input stack frame', () => {
9092
it('can handle fewer input lines than the expected context', () => {
9193
expect(
9294
getSrcLines(inputFrame, {
95+
enabled: true,
9396
source: {
9497
beforeLines: 3,
9598
afterLines: 3,
@@ -106,6 +109,7 @@ describe('given an input stack frame', () => {
106109
it('can handle more input lines than the expected context', () => {
107110
expect(
108111
getSrcLines(inputFrame, {
112+
enabled: true,
109113
source: {
110114
beforeLines: 1,
111115
afterLines: 1,
@@ -119,3 +123,16 @@ describe('given an input stack frame', () => {
119123
});
120124
});
121125
});
126+
127+
it('returns an empty stack when stack parsing is disabled', () => {
128+
expect(
129+
parse(new Error('test'), {
130+
enabled: false,
131+
source: {
132+
beforeLines: 1,
133+
afterLines: 1,
134+
maxLineLength: 280,
135+
},
136+
}),
137+
).toEqual({ frames: [] });
138+
});

packages/telemetry/browser-telemetry/src/BrowserTelemetryImpl.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ function applyFilter<T>(item: T | undefined, filter: (item: T) => T | undefined)
6565
}
6666

6767
function configureTraceKit(options: ParsedStackOptions) {
68+
if (!options.enabled) {
69+
return;
70+
}
71+
6872
const TraceKit = getTraceKit();
6973
// Include before + after + source line.
7074
// TraceKit only takes a total context size, so we have to over capture and then reduce the lines.

packages/telemetry/browser-telemetry/src/api/Options.ts

Lines changed: 85 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,86 @@ export interface StackOptions {
9393
};
9494
}
9595

96+
export interface BreadcrumbsOptions {
97+
/**
98+
* Set the maximum number of breadcrumbs. Defaults to 50.
99+
*/
100+
maxBreadcrumbs?: number;
101+
102+
/**
103+
* True to enable automatic evaluation breadcrumbs. Defaults to true.
104+
*/
105+
evaluations?: boolean;
106+
107+
/**
108+
* True to enable flag change breadcrumbs. Defaults to true.
109+
*/
110+
flagChange?: boolean;
111+
112+
/**
113+
* True to enable click breadcrumbs. Defaults to true.
114+
*/
115+
click?: boolean;
116+
117+
/**
118+
* True to enable input breadcrumbs for keypresses. Defaults to true.
119+
*
120+
* Input breadcrumbs do not include entered text, just that text was entered.
121+
*/
122+
keyboardInput?: boolean;
123+
124+
/**
125+
* Controls instrumentation and breadcrumbs for HTTP requests.
126+
* The default is to instrument XMLHttpRequests and fetch requests.
127+
*
128+
* `false` to disable all HTTP breadcrumbs and instrumentation.
129+
*
130+
* Example:
131+
* ```
132+
* // This would instrument only XmlHttpRequests
133+
* http: {
134+
* instrumentFetch: false
135+
* instrumentXhr: true
136+
* }
137+
*
138+
* // Disable all HTTP instrumentation:
139+
* http: false
140+
* ```
141+
*/
142+
http?: HttpBreadcrumbOptions | false;
143+
144+
/**
145+
* Custom breadcrumb filters.
146+
*
147+
* Can be used to redact or modify breadcrumbs.
148+
*
149+
* Example:
150+
* ```
151+
* // We want to redact any click events that include the message 'sneaky-button'
152+
* filters: [
153+
* (breadcrumb) => {
154+
* if(
155+
* breadcrumb.class === 'ui' &&
156+
* breadcrumb.type === 'click' &&
157+
* breadcrumb.message?.includes('sneaky-button')
158+
* ) {
159+
* return;
160+
* }
161+
* return breadcrumb;
162+
* }
163+
* ]
164+
* ```
165+
*
166+
* If you want to redact or modify URLs in breadcrumbs, then a urlFilter should be used.
167+
*
168+
* If any breadcrumb filters throw an exception while processing a breadcrumb, then that breadcrumb will be excluded.
169+
*
170+
* If any breadcrumbFilter cannot be executed, for example because it is not a function, then all breadcrumbs will
171+
* be excluded.
172+
*/
173+
filters?: BreadcrumbFilter[];
174+
}
175+
96176
/**
97177
* Options for configuring browser telemetry.
98178
*/
@@ -103,98 +183,21 @@ export interface Options {
103183
* events captured during initialization.
104184
*/
105185
maxPendingEvents?: number;
186+
106187
/**
107-
* Properties related to automatic breadcrumb collection.
188+
* Properties related to automatic breadcrumb collection, or `false` to disable automatic breadcrumbs.
108189
*/
109-
breadcrumbs?: {
110-
/**
111-
* Set the maximum number of breadcrumbs. Defaults to 50.
112-
*/
113-
maxBreadcrumbs?: number;
114-
115-
/**
116-
* True to enable automatic evaluation breadcrumbs. Defaults to true.
117-
*/
118-
evaluations?: boolean;
119-
120-
/**
121-
* True to enable flag change breadcrumbs. Defaults to true.
122-
*/
123-
flagChange?: boolean;
124-
125-
/**
126-
* True to enable click breadcrumbs. Defaults to true.
127-
*/
128-
click?: boolean;
129-
130-
/**
131-
* True to enable input breadcrumbs for keypresses. Defaults to true.
132-
*
133-
* Input breadcrumbs do not include entered text, just that text was entered.
134-
*/
135-
keyboardInput?: boolean;
136-
137-
/**
138-
* Controls instrumentation and breadcrumbs for HTTP requests.
139-
* The default is to instrument XMLHttpRequests and fetch requests.
140-
*
141-
* `false` to disable all HTTP breadcrumbs and instrumentation.
142-
*
143-
* Example:
144-
* ```
145-
* // This would instrument only XmlHttpRequests
146-
* http: {
147-
* instrumentFetch: false
148-
* instrumentXhr: true
149-
* }
150-
*
151-
* // Disable all HTTP instrumentation:
152-
* http: false
153-
* ```
154-
*/
155-
http?: HttpBreadcrumbOptions | false;
156-
157-
/**
158-
* Custom breadcrumb filters.
159-
*
160-
* Can be used to redact or modify breadcrumbs.
161-
*
162-
* Example:
163-
* ```
164-
* // We want to redact any click events that include the message 'sneaky-button'
165-
* filters: [
166-
* (breadcrumb) => {
167-
* if(
168-
* breadcrumb.class === 'ui' &&
169-
* breadcrumb.type === 'click' &&
170-
* breadcrumb.message?.includes('sneaky-button')
171-
* ) {
172-
* return;
173-
* }
174-
* return breadcrumb;
175-
* }
176-
* ]
177-
* ```
178-
*
179-
* If you want to redact or modify URLs in breadcrumbs, then a urlFilter should be used.
180-
*
181-
* If any breadcrumb filters throw an exception while processing a breadcrumb, then that breadcrumb will be excluded.
182-
*
183-
* If any breadcrumbFilter cannot be executed, for example because it is not a function, then all breadcrumbs will
184-
* be excluded.
185-
*/
186-
filters?: BreadcrumbFilter[];
187-
};
190+
breadcrumbs?: BreadcrumbsOptions | false;
188191

189192
/**
190193
* Additional, or custom, collectors.
191194
*/
192195
collectors?: Collector[];
193196

194197
/**
195-
* Configuration that controls the capture of the stack trace.
198+
* Configuration that controls the capture of the stack trace, or `false` to exclude stack frames from error events.
196199
*/
197-
stack?: StackOptions;
200+
stack?: StackOptions | false;
198201

199202
/**
200203
* Logger to use for warnings.

0 commit comments

Comments
 (0)