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
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const defaultOptions: ParsedOptions = {
filters: [],
},
stack: {
enabled: true,
source: {
beforeLines: 5,
afterLines: 5,
Expand Down
38 changes: 38 additions & 0 deletions packages/telemetry/browser-telemetry/__tests__/options.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@ it('handles an empty configuration', () => {
expect(outOptions).toEqual(defaultOptions());
});

it('disables all breadcrumb options when breadcrumbs is false', () => {
const outOptions = parse({
breadcrumbs: false,
});

expect(outOptions.breadcrumbs).toEqual({
maxBreadcrumbs: 0,
click: false,
evaluations: false,
flagChange: false,
keyboardInput: false,
http: {
instrumentFetch: false,
instrumentXhr: false,
customUrlFilter: undefined,
},
filters: [],
});
expect(mockLogger.warn).not.toHaveBeenCalled();
});

it('can set all options at once', () => {
const breadcrumbFilter = (breadcrumb: Breadcrumb) => breadcrumb;
const errorFilter = (error: ErrorData) => error;
Expand Down Expand Up @@ -47,6 +68,7 @@ it('can set all options at once', () => {
filters: expect.arrayContaining([breadcrumbFilter]),
},
stack: {
enabled: true,
source: {
beforeLines: 3,
afterLines: 3,
Expand Down Expand Up @@ -473,3 +495,19 @@ it('accepts valid error filters array', () => {
expect(outOptions.errorFilters).toEqual(errorFilters);
expect(mockLogger.warn).not.toHaveBeenCalled();
});

it('disables all stack options when stack is false', () => {
const outOptions = parse({
stack: false,
});

expect(outOptions.stack).toEqual({
enabled: false,
source: {
beforeLines: 0,
afterLines: 0,
maxLineLength: 0,
},
});
expect(mockLogger.warn).not.toHaveBeenCalled();
});
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {
import parse, {
getLines,
getSrcLines,
processUrlToFileName,
Expand Down Expand Up @@ -58,6 +58,7 @@ describe('given an input stack frame', () => {
it('can produce a full stack source in the output frame', () => {
expect(
getSrcLines(inputFrame, {
enabled: true,
source: {
beforeLines: 2,
afterLines: 2,
Expand All @@ -74,6 +75,7 @@ describe('given an input stack frame', () => {
it('can trim all the lines', () => {
expect(
getSrcLines(inputFrame, {
enabled: true,
source: {
beforeLines: 2,
afterLines: 2,
Expand All @@ -90,6 +92,7 @@ describe('given an input stack frame', () => {
it('can handle fewer input lines than the expected context', () => {
expect(
getSrcLines(inputFrame, {
enabled: true,
source: {
beforeLines: 3,
afterLines: 3,
Expand All @@ -106,6 +109,7 @@ describe('given an input stack frame', () => {
it('can handle more input lines than the expected context', () => {
expect(
getSrcLines(inputFrame, {
enabled: true,
source: {
beforeLines: 1,
afterLines: 1,
Expand All @@ -119,3 +123,16 @@ describe('given an input stack frame', () => {
});
});
});

it('returns an empty stack when stack parsing is disabled', () => {
expect(
parse(new Error('test'), {
enabled: false,
source: {
beforeLines: 1,
afterLines: 1,
maxLineLength: 280,
},
}),
).toEqual({ frames: [] });
});
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ function applyFilter<T>(item: T | undefined, filter: (item: T) => T | undefined)
}

function configureTraceKit(options: ParsedStackOptions) {
if (!options.enabled) {
return;
}

const TraceKit = getTraceKit();
// Include before + after + source line.
// TraceKit only takes a total context size, so we have to over capture and then reduce the lines.
Expand Down
167 changes: 85 additions & 82 deletions packages/telemetry/browser-telemetry/src/api/Options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,86 @@ export interface StackOptions {
};
}

export interface BreadcrumbsOptions {
/**
* Set the maximum number of breadcrumbs. Defaults to 50.
*/
maxBreadcrumbs?: number;

/**
* True to enable automatic evaluation breadcrumbs. Defaults to true.
*/
evaluations?: boolean;

/**
* True to enable flag change breadcrumbs. Defaults to true.
*/
flagChange?: boolean;

/**
* True to enable click breadcrumbs. Defaults to true.
*/
click?: boolean;

/**
* True to enable input breadcrumbs for keypresses. Defaults to true.
*
* Input breadcrumbs do not include entered text, just that text was entered.
*/
keyboardInput?: boolean;

/**
* Controls instrumentation and breadcrumbs for HTTP requests.
* The default is to instrument XMLHttpRequests and fetch requests.
*
* `false` to disable all HTTP breadcrumbs and instrumentation.
*
* Example:
* ```
* // This would instrument only XmlHttpRequests
* http: {
* instrumentFetch: false
* instrumentXhr: true
* }
*
* // Disable all HTTP instrumentation:
* http: false
* ```
*/
http?: HttpBreadcrumbOptions | false;

/**
* Custom breadcrumb filters.
*
* Can be used to redact or modify breadcrumbs.
*
* Example:
* ```
* // We want to redact any click events that include the message 'sneaky-button'
* filters: [
* (breadcrumb) => {
* if(
* breadcrumb.class === 'ui' &&
* breadcrumb.type === 'click' &&
* breadcrumb.message?.includes('sneaky-button')
* ) {
* return;
* }
* return breadcrumb;
* }
* ]
* ```
*
* If you want to redact or modify URLs in breadcrumbs, then a urlFilter should be used.
*
* If any breadcrumb filters throw an exception while processing a breadcrumb, then that breadcrumb will be excluded.
*
* If any breadcrumbFilter cannot be executed, for example because it is not a function, then all breadcrumbs will
* be excluded.
*/
filters?: BreadcrumbFilter[];
}

/**
* Options for configuring browser telemetry.
*/
Expand All @@ -103,98 +183,21 @@ export interface Options {
* events captured during initialization.
*/
maxPendingEvents?: number;

/**
* Properties related to automatic breadcrumb collection.
* Properties related to automatic breadcrumb collection, or `false` to disable automatic breadcrumbs.
*/
breadcrumbs?: {
/**
* Set the maximum number of breadcrumbs. Defaults to 50.
*/
maxBreadcrumbs?: number;

/**
* True to enable automatic evaluation breadcrumbs. Defaults to true.
*/
evaluations?: boolean;

/**
* True to enable flag change breadcrumbs. Defaults to true.
*/
flagChange?: boolean;

/**
* True to enable click breadcrumbs. Defaults to true.
*/
click?: boolean;

/**
* True to enable input breadcrumbs for keypresses. Defaults to true.
*
* Input breadcrumbs do not include entered text, just that text was entered.
*/
keyboardInput?: boolean;

/**
* Controls instrumentation and breadcrumbs for HTTP requests.
* The default is to instrument XMLHttpRequests and fetch requests.
*
* `false` to disable all HTTP breadcrumbs and instrumentation.
*
* Example:
* ```
* // This would instrument only XmlHttpRequests
* http: {
* instrumentFetch: false
* instrumentXhr: true
* }
*
* // Disable all HTTP instrumentation:
* http: false
* ```
*/
http?: HttpBreadcrumbOptions | false;

/**
* Custom breadcrumb filters.
*
* Can be used to redact or modify breadcrumbs.
*
* Example:
* ```
* // We want to redact any click events that include the message 'sneaky-button'
* filters: [
* (breadcrumb) => {
* if(
* breadcrumb.class === 'ui' &&
* breadcrumb.type === 'click' &&
* breadcrumb.message?.includes('sneaky-button')
* ) {
* return;
* }
* return breadcrumb;
* }
* ]
* ```
*
* If you want to redact or modify URLs in breadcrumbs, then a urlFilter should be used.
*
* If any breadcrumb filters throw an exception while processing a breadcrumb, then that breadcrumb will be excluded.
*
* If any breadcrumbFilter cannot be executed, for example because it is not a function, then all breadcrumbs will
* be excluded.
*/
filters?: BreadcrumbFilter[];
};
breadcrumbs?: BreadcrumbsOptions | false;

/**
* Additional, or custom, collectors.
*/
collectors?: Collector[];

/**
* Configuration that controls the capture of the stack trace.
* Configuration that controls the capture of the stack trace, or `false` to exclude stack frames from error events.
*/
stack?: StackOptions;
stack?: StackOptions | false;

/**
* Logger to use for warnings.
Expand Down
Loading