Skip to content

Commit d9b479c

Browse files
authored
feat(ourlogs): Strip ANSI escape codes (#89619)
ANSI codes make logs look like `[32mthis text is green` instead of just `this text is green` - strip them for a better user experience. Solves LOGS-40
1 parent 66cd5ca commit d9b479c

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {stripAnsi} from 'sentry/utils/ansiEscapeCodes';
2+
3+
describe('ansiEscapeCodes', () => {
4+
it('removes ANSI color codes', () => {
5+
const colored = '\x1b[31mThis is red text\x1b[0m';
6+
expect(stripAnsi(colored)).toBe('This is red text');
7+
});
8+
9+
it('removes multiple ANSI codes', () => {
10+
const input = '\x1b[32mGreen\x1b[0m and \x1b[34mBlue\x1b[0m';
11+
expect(stripAnsi(input)).toBe('Green and Blue');
12+
});
13+
14+
it('returns the original string if there are no ANSI codes', () => {
15+
const plain = 'Just a normal string.';
16+
expect(stripAnsi(plain)).toBe(plain);
17+
});
18+
19+
it('handles empty strings', () => {
20+
expect(stripAnsi('')).toBe('');
21+
});
22+
23+
it('handles strings with mixed characters and ANSI codes', () => {
24+
const input = 'Hello \x1b[1mWorld\x1b[0m!';
25+
expect(stripAnsi(input)).toBe('Hello World!');
26+
});
27+
});
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* Strips ANSI escape codes from a string
3+
* @param input - The string potentially containing ANSI codes
4+
* @returns The cleaned string without ANSI codes
5+
*/
6+
export function stripAnsi(input: string): string {
7+
// eslint-disable-next-line no-control-regex
8+
const ansiRegex = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g;
9+
return input.replace(ansiRegex, '');
10+
}

static/app/views/explore/logs/fieldRenderers.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import Link from 'sentry/components/links/link';
77
import {Tooltip} from 'sentry/components/tooltip';
88
import type {Organization} from 'sentry/types/organization';
99
import {defined} from 'sentry/utils';
10+
import {stripAnsi} from 'sentry/utils/ansiEscapeCodes';
1011
import type {EventsMetaType} from 'sentry/utils/discover/eventView';
1112
import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers';
1213
import {stripLogParamsFromLocation} from 'sentry/views/explore/contexts/logs/logsPageParams';
@@ -140,7 +141,7 @@ export function LogBodyRenderer(props: LogFieldRendererProps) {
140141
// TODO: Allow more than one highlight term to be highlighted at once.
141142
return (
142143
<WrappingText wrap={props.extra.wrapBody}>
143-
<LogsHighlight text={highlightTerm}>{attribute_value}</LogsHighlight>
144+
<LogsHighlight text={highlightTerm}>{stripAnsi(attribute_value)}</LogsHighlight>
144145
</WrappingText>
145146
);
146147
}

0 commit comments

Comments
 (0)