Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Filter ANSI escape codes for Sentry #1068

Merged
merged 2 commits into from
Oct 2, 2024
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
47 changes: 47 additions & 0 deletions node-src/errorMonitoring.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import * as Sentry from '@sentry/node';
import chalk from 'chalk';
import { describe, expect, it } from 'vitest';

import { filterBreadcrumb, filterErrorEvent } from './errorMonitoring';

const redError = chalk.red('error');
const blueMessage = chalk.blue('message');

describe('filterErrorEvent', () => {
it('removes ANSI from error.message', () => {
const actual = filterErrorEvent({ message: redError } as Sentry.ErrorEvent);
expect(actual.message).toBe('error');
});

it('remove ANSI from exceptions', () => {
const actual = filterErrorEvent({
exception: { values: [{ value: redError }, { value: redError }] },
} as Sentry.ErrorEvent);
expect(actual.exception.values[0].value).toBe('error');
expect(actual.exception.values[1].value).toBe('error');
});
});

describe('filterBreadcrumb', () => {
it('does nothing with non-console breadcrumbs', () => {
const breadcrumb = { category: 'http', message: blueMessage } as Sentry.Breadcrumb;
const actual = filterBreadcrumb(breadcrumb);
expect(actual).toBe(breadcrumb);
});

it('removes ANSI from console breadcrumb messages', () => {
const actual = filterBreadcrumb({
category: 'console',
message: blueMessage,
} as Sentry.Breadcrumb);
expect(actual.message).toBe('message');
});

it('returns null for empty console breadcrumbs', () => {
const actual = filterBreadcrumb({
category: 'console',
message: '',
} as Sentry.Breadcrumb);
expect(actual).toBeNull();
});
});
49 changes: 48 additions & 1 deletion node-src/errorMonitoring.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,62 @@
import * as Sentry from '@sentry/node';
import stripAnsi from 'strip-ansi';

/**
* Remove ANSI escape codes from Sentry ErrorEvents.
*
* @param event An event containing a captured exception.
jmhobbs marked this conversation as resolved.
Show resolved Hide resolved
*
* @returns The modified event.
jmhobbs marked this conversation as resolved.
Show resolved Hide resolved
*/
export function filterErrorEvent(event: Sentry.ErrorEvent) {
// Remove ANSI escape codes from error messages
if (event.message) {
event.message = stripAnsi(event.message);
}
// And from exception messages
if (event.exception?.values) {
for (const [index, exception] of event.exception.values.entries()) {
event.exception.values[index].value = stripAnsi(exception.value);
}
}
return event;
}

/**
* Remove ANSI escape codes from console breadcrumbs, and skip breadcrumbs for empty lines.
*
* @param breadcrumb A breadcrumb captured by Sentry.
*
* @returns The modified breadcrumb, or `null` when it is not desired.
*/
export function filterBreadcrumb(breadcrumb: Sentry.Breadcrumb) {
if (breadcrumb.category === 'console') {
// Do not send breadcrumbs for console newlines
if (breadcrumb.message === '') {
// eslint-disable-next-line unicorn/no-null
return null;
}
// Otherwise remove ANSI escape codes
if (breadcrumb.message) {
breadcrumb.message = stripAnsi(breadcrumb.message);
}
}
return breadcrumb;
}

Sentry.init({
dsn: 'https://4fa173db2ef3fb073b8ea153a5466d28@o4504181686599680.ingest.us.sentry.io/4507930289373184',
sampleRate: 1,
environment: process.env.CI && process.env.GITHUB_RUN_ID ? 'action' : 'cli',
environment: process.env.SENTRY_ENVIRONMENT,
enabled: process.env.DISABLE_ERROR_MONITORING !== 'true',
enableTracing: false,
integrations: [],
initialScope: {
tags: {
entrypoint: process.env.CI && process.env.GITHUB_RUN_ID ? 'action' : 'cli',
version: process.env.npm_package_version,
},
},
beforeSend: filterErrorEvent,
beforeBreadcrumb: filterBreadcrumb,
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@
"sort-package-json": "1.50.0",
"storybook": "^8.1.5",
"string-argv": "^0.3.1",
"strip-ansi": "6.0.0",
"strip-ansi": "^7.1.0",
"tmp-promise": "3.0.2",
"ts-dedent": "^1.0.0",
"ts-loader": "^9.2.5",
Expand Down
6 changes: 6 additions & 0 deletions tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ export default defineConfig((options) => [
clean: true,
platform: 'node',
target: 'node16', // Storybook still supports Node 16
env: {
SENTRY_ENVIRONMENT: process.env.CI ? 'production' : 'development',
},
},
{
entry: ['action-src/register.js'],
Expand All @@ -30,5 +33,8 @@ export default defineConfig((options) => [
clean: true,
platform: 'node',
target: 'node20', // Sync with `runs.using` in action.yml
env: {
SENTRY_ENVIRONMENT: process.env.CI ? 'production' : 'development',
},
},
]);
15 changes: 3 additions & 12 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6289,7 +6289,7 @@ __metadata:
languageName: node
linkType: hard

"ansi-regex@npm:^5.0.0, ansi-regex@npm:^5.0.1":
"ansi-regex@npm:^5.0.1":
version: 5.0.1
resolution: "ansi-regex@npm:5.0.1"
checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737
Expand Down Expand Up @@ -7516,7 +7516,7 @@ __metadata:
sort-package-json: "npm:1.50.0"
storybook: "npm:^8.1.5"
string-argv: "npm:^0.3.1"
strip-ansi: "npm:6.0.0"
strip-ansi: "npm:^7.1.0"
tmp-promise: "npm:3.0.2"
ts-dedent: "npm:^1.0.0"
ts-loader: "npm:^9.2.5"
Expand Down Expand Up @@ -17971,15 +17971,6 @@ __metadata:
languageName: node
linkType: hard

"strip-ansi@npm:6.0.0":
version: 6.0.0
resolution: "strip-ansi@npm:6.0.0"
dependencies:
ansi-regex: "npm:^5.0.0"
checksum: 10c0/85257c80250541cc0e65088c7dc768563bdbd1bf7120471d6d3a73cdc60e8149a50038c12a6fd4a30b674587f306ae42e2cc73ac3095daf193633daa0bd8f928
languageName: node
linkType: hard

"strip-ansi@npm:^3.0.0, strip-ansi@npm:^3.0.1":
version: 3.0.1
resolution: "strip-ansi@npm:3.0.1"
Expand All @@ -17998,7 +17989,7 @@ __metadata:
languageName: node
linkType: hard

"strip-ansi@npm:^7.0.0, strip-ansi@npm:^7.0.1":
"strip-ansi@npm:^7.0.0, strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0":
version: 7.1.0
resolution: "strip-ansi@npm:7.1.0"
dependencies:
Expand Down
Loading