Commit 2c724e0a by Valentin Agachi Committed by GitHub

Explore: support ANSI colors in live logs (#28895)

Closes #28893

Co-authored-by: Ivana <ivana.huckova@gmail.com>
parent e834ad00
......@@ -96,6 +96,7 @@ export { GraphSeriesToggler, GraphSeriesTogglerAPI } from './Graph/GraphSeriesTo
export { Collapse, ControlledCollapse } from './Collapse/Collapse';
export { CollapsableSection } from './Collapse/CollapsableSection';
export { LogLabels } from './Logs/LogLabels';
export { LogMessageAnsi } from './Logs/LogMessageAnsi';
export { LogRows } from './Logs/LogRows';
export { getLogRowStyles } from './Logs/getLogRowStyles';
export { ToggleButtonGroup, ToggleButton } from './ToggleButtonGroup/ToggleButtonGroup';
......
......@@ -55,10 +55,45 @@ describe('LiveLogs', () => {
expect(wrapper.contains('log message 5')).toBeTruthy();
expect(wrapper.contains('log message 6')).toBeTruthy();
});
it('renders ansi logs', () => {
const rows: LogRowModel[] = [
makeLog({ uid: '1' }),
makeLog({ hasAnsi: true, raw: 'log message \u001B[31m2\u001B[0m', uid: '2' }),
makeLog({ hasAnsi: true, raw: 'log message \u001B[31m3\u001B[0m', uid: '3' }),
];
const wrapper = mount(
<LiveLogsWithTheme
logRows={rows}
timeZone={'utc'}
stopLive={() => {}}
onPause={() => {}}
onResume={() => {}}
isPaused={true}
/>
);
expect(wrapper.contains('log message 1')).toBeTruthy();
expect(wrapper.contains('log message 2')).not.toBeTruthy();
expect(wrapper.contains('log message 3')).not.toBeTruthy();
expect(wrapper.find('LogMessageAnsi')).toHaveLength(2);
expect(
wrapper
.find('LogMessageAnsi')
.first()
.prop('value')
).toBe('log message \u001B[31m2\u001B[0m');
expect(
wrapper
.find('LogMessageAnsi')
.last()
.prop('value')
).toBe('log message \u001B[31m3\u001B[0m');
});
});
const makeLog = (overides: Partial<LogRowModel>): LogRowModel => {
const uid = overides.uid || '1';
const makeLog = (overrides: Partial<LogRowModel>): LogRowModel => {
const uid = overrides.uid || '1';
const entry = `log message ${uid}`;
return {
uid,
......@@ -75,6 +110,6 @@ const makeLog = (overides: Partial<LogRowModel>): LogRowModel => {
timeEpochNs: '1000000',
timeLocal: '',
timeUtc: '',
...overides,
...overrides,
};
};
......@@ -2,7 +2,7 @@ import React, { PureComponent } from 'react';
import { css, cx } from 'emotion';
import tinycolor from 'tinycolor2';
import { Themeable, withTheme, getLogRowStyles, Icon } from '@grafana/ui';
import { LogMessageAnsi, Themeable, withTheme, getLogRowStyles, Icon } from '@grafana/ui';
import { GrafanaTheme, LogRowModel, TimeZone, dateTimeFormat } from '@grafana/data';
import { ElapsedTime } from './ElapsedTime';
......@@ -151,7 +151,7 @@ class LiveLogs extends PureComponent<Props, State> {
return (
<tr className={cx(logsRow, styles.logsRowFade)} key={row.uid}>
<td className={cx(logsRowLocalTime)}>{dateTimeFormat(row.timeEpochMs, { timeZone })}</td>
<td className={cx(logsRowMessage)}>{row.entry}</td>
<td className={cx(logsRowMessage)}>{row.hasAnsi ? <LogMessageAnsi value={row.raw} /> : row.entry}</td>
</tr>
);
})}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment