diff --git a/static/app/utils/ansiEscapeCodes.spec.tsx b/static/app/utils/ansiEscapeCodes.spec.tsx new file mode 100644 index 00000000000000..a0755d56a6b66c --- /dev/null +++ b/static/app/utils/ansiEscapeCodes.spec.tsx @@ -0,0 +1,27 @@ +import {stripAnsi} from 'sentry/utils/ansiEscapeCodes'; + +describe('ansiEscapeCodes', () => { + it('removes ANSI color codes', () => { + const colored = '\x1b[31mThis is red text\x1b[0m'; + expect(stripAnsi(colored)).toBe('This is red text'); + }); + + it('removes multiple ANSI codes', () => { + const input = '\x1b[32mGreen\x1b[0m and \x1b[34mBlue\x1b[0m'; + expect(stripAnsi(input)).toBe('Green and Blue'); + }); + + it('returns the original string if there are no ANSI codes', () => { + const plain = 'Just a normal string.'; + expect(stripAnsi(plain)).toBe(plain); + }); + + it('handles empty strings', () => { + expect(stripAnsi('')).toBe(''); + }); + + it('handles strings with mixed characters and ANSI codes', () => { + const input = 'Hello \x1b[1mWorld\x1b[0m!'; + expect(stripAnsi(input)).toBe('Hello World!'); + }); +}); diff --git a/static/app/utils/ansiEscapeCodes.tsx b/static/app/utils/ansiEscapeCodes.tsx new file mode 100644 index 00000000000000..35ec4802b7097f --- /dev/null +++ b/static/app/utils/ansiEscapeCodes.tsx @@ -0,0 +1,10 @@ +/** + * Strips ANSI escape codes from a string + * @param input - The string potentially containing ANSI codes + * @returns The cleaned string without ANSI codes + */ +export function stripAnsi(input: string): string { + // eslint-disable-next-line no-control-regex + const ansiRegex = /\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])/g; + return input.replace(ansiRegex, ''); +} diff --git a/static/app/views/explore/logs/fieldRenderers.tsx b/static/app/views/explore/logs/fieldRenderers.tsx index 18ffb31e009d0d..1bfc8e4274deec 100644 --- a/static/app/views/explore/logs/fieldRenderers.tsx +++ b/static/app/views/explore/logs/fieldRenderers.tsx @@ -7,6 +7,7 @@ import Link from 'sentry/components/links/link'; import {Tooltip} from 'sentry/components/tooltip'; import type {Organization} from 'sentry/types/organization'; import {defined} from 'sentry/utils'; +import {stripAnsi} from 'sentry/utils/ansiEscapeCodes'; import type {EventsMetaType} from 'sentry/utils/discover/eventView'; import {getFieldRenderer} from 'sentry/utils/discover/fieldRenderers'; import {stripLogParamsFromLocation} from 'sentry/views/explore/contexts/logs/logsPageParams'; @@ -140,7 +141,7 @@ export function LogBodyRenderer(props: LogFieldRendererProps) { // TODO: Allow more than one highlight term to be highlighted at once. return ( - {attribute_value} + {stripAnsi(attribute_value)} ); }