mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-08-15 21:15:56 +08:00
Logs Strip color according to severity_text
(#4643)
* refactor: initial setup * refactor: done with setup * refactor: done with severity text split color * refactor: initial setup * refactor: done with setup * refactor: done with severity text split color * chore: added unit test case * refactor : pointed to the correct variable --------- Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>
This commit is contained in:
parent
62af836554
commit
54c69311ed
@ -20,9 +20,8 @@ import { ILog } from 'types/api/logs/log';
|
|||||||
// components
|
// components
|
||||||
import AddToQueryHOC, { AddToQueryHOCProps } from '../AddToQueryHOC';
|
import AddToQueryHOC, { AddToQueryHOCProps } from '../AddToQueryHOC';
|
||||||
import LogLinesActionButtons from '../LogLinesActionButtons/LogLinesActionButtons';
|
import LogLinesActionButtons from '../LogLinesActionButtons/LogLinesActionButtons';
|
||||||
import LogStateIndicator, {
|
import LogStateIndicator from '../LogStateIndicator/LogStateIndicator';
|
||||||
LogType,
|
import { getLogIndicatorType } from '../LogStateIndicator/utils';
|
||||||
} from '../LogStateIndicator/LogStateIndicator';
|
|
||||||
// styles
|
// styles
|
||||||
import {
|
import {
|
||||||
Container,
|
Container,
|
||||||
@ -152,7 +151,7 @@ function ListLogView({
|
|||||||
[flattenLogData.timestamp],
|
[flattenLogData.timestamp],
|
||||||
);
|
);
|
||||||
|
|
||||||
const logType = logData?.attributes_string?.log_level || LogType.INFO;
|
const logType = getLogIndicatorType(logData);
|
||||||
|
|
||||||
const handleMouseEnter = (): void => {
|
const handleMouseEnter = (): void => {
|
||||||
setHasActionButtons(true);
|
setHasActionButtons(true);
|
||||||
|
@ -10,15 +10,27 @@
|
|||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
|
||||||
&.INFO {
|
&.INFO {
|
||||||
background-color: #1d212d;
|
background-color: var(--bg-slate-400);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.WARNING {
|
&.WARNING, &.WARN {
|
||||||
background-color: #ffcd56;
|
background-color: var(--bg-amber-500);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.ERROR {
|
&.ERROR {
|
||||||
background-color: #e5484d;
|
background-color: var(--bg-cherry-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.TRACE {
|
||||||
|
background-color: var(--bg-robin-300);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.DEBUG {
|
||||||
|
background-color: var(--bg-forest-500);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.FATAL {
|
||||||
|
background-color: var(--bg-sakura-500);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
import { render } from '@testing-library/react';
|
||||||
|
|
||||||
|
import LogStateIndicator from './LogStateIndicator';
|
||||||
|
|
||||||
|
describe('LogStateIndicator', () => {
|
||||||
|
it('renders correctly with default props', () => {
|
||||||
|
const { container } = render(<LogStateIndicator type="INFO" />);
|
||||||
|
const indicator = container.firstChild as HTMLElement;
|
||||||
|
expect(indicator.classList.contains('log-state-indicator')).toBe(true);
|
||||||
|
expect(indicator.classList.contains('isActive')).toBe(false);
|
||||||
|
expect(container.querySelector('.line')).toBeTruthy();
|
||||||
|
expect(container.querySelector('.line')?.classList.contains('INFO')).toBe(
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders correctly when isActive is true', () => {
|
||||||
|
const { container } = render(<LogStateIndicator type="INFO" isActive />);
|
||||||
|
const indicator = container.firstChild as HTMLElement;
|
||||||
|
expect(indicator.classList.contains('isActive')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders correctly with different types', () => {
|
||||||
|
const { container: containerInfo } = render(
|
||||||
|
<LogStateIndicator type="INFO" />,
|
||||||
|
);
|
||||||
|
expect(containerInfo.querySelector('.line')?.classList.contains('INFO')).toBe(
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
const { container: containerWarning } = render(
|
||||||
|
<LogStateIndicator type="WARNING" />,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
containerWarning.querySelector('.line')?.classList.contains('WARNING'),
|
||||||
|
).toBe(true);
|
||||||
|
|
||||||
|
const { container: containerError } = render(
|
||||||
|
<LogStateIndicator type="ERROR" />,
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
containerError.querySelector('.line')?.classList.contains('ERROR'),
|
||||||
|
).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
@ -2,11 +2,40 @@ import './LogStateIndicator.styles.scss';
|
|||||||
|
|
||||||
import cx from 'classnames';
|
import cx from 'classnames';
|
||||||
|
|
||||||
|
export const SEVERITY_TEXT_TYPE = {
|
||||||
|
TRACE: 'TRACE',
|
||||||
|
TRACE2: 'TRACE2',
|
||||||
|
TRACE3: 'TRACE3',
|
||||||
|
TRACE4: 'TRACE4',
|
||||||
|
DEBUG: 'DEBUG',
|
||||||
|
DEBUG2: 'DEBUG2',
|
||||||
|
DEBUG3: 'DEBUG3',
|
||||||
|
DEBUG4: 'DEBUG4',
|
||||||
|
INFO: 'INFO',
|
||||||
|
INFO2: 'INFO2',
|
||||||
|
INFO3: 'INFO3',
|
||||||
|
INFO4: 'INFO4',
|
||||||
|
WARN: 'WARN',
|
||||||
|
WARN2: 'WARN2',
|
||||||
|
WARN3: 'WARN3',
|
||||||
|
WARN4: 'WARN4',
|
||||||
|
WARNING: 'WARNING',
|
||||||
|
ERROR: 'ERROR',
|
||||||
|
ERROR2: 'ERROR2',
|
||||||
|
ERROR3: 'ERROR3',
|
||||||
|
ERROR4: 'ERROR4',
|
||||||
|
FATAL: 'FATAL',
|
||||||
|
FATAL2: 'FATAL2',
|
||||||
|
FATAL3: 'FATAL3',
|
||||||
|
FATAL4: 'FATAL4',
|
||||||
|
} as const;
|
||||||
|
|
||||||
export const LogType = {
|
export const LogType = {
|
||||||
INFO: 'INFO',
|
INFO: 'INFO',
|
||||||
WARNING: 'WARNING',
|
WARNING: 'WARNING',
|
||||||
ERROR: 'ERROR',
|
ERROR: 'ERROR',
|
||||||
};
|
} as const;
|
||||||
|
|
||||||
function LogStateIndicator({
|
function LogStateIndicator({
|
||||||
type,
|
type,
|
||||||
isActive,
|
isActive,
|
||||||
|
89
frontend/src/components/Logs/LogStateIndicator/utils.test.ts
Normal file
89
frontend/src/components/Logs/LogStateIndicator/utils.test.ts
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import { ILog } from 'types/api/logs/log';
|
||||||
|
|
||||||
|
import { getLogIndicatorType, getLogIndicatorTypeForTable } from './utils';
|
||||||
|
|
||||||
|
describe('getLogIndicatorType', () => {
|
||||||
|
it('should return severity type for valid log with severityText', () => {
|
||||||
|
const log = {
|
||||||
|
date: '2024-02-29T12:34:46Z',
|
||||||
|
timestamp: 1646115296,
|
||||||
|
id: '123456',
|
||||||
|
traceId: '987654',
|
||||||
|
spanId: '54321',
|
||||||
|
traceFlags: 0,
|
||||||
|
severityText: 'INFO',
|
||||||
|
severityNumber: 2,
|
||||||
|
body: 'Sample log Message',
|
||||||
|
resources_string: {},
|
||||||
|
attributesString: {},
|
||||||
|
attributes_string: {},
|
||||||
|
attributesInt: {},
|
||||||
|
attributesFloat: {},
|
||||||
|
severity_text: 'INFO',
|
||||||
|
};
|
||||||
|
expect(getLogIndicatorType(log)).toBe('INFO');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return log level if severityText is missing', () => {
|
||||||
|
const log: ILog = {
|
||||||
|
date: '2024-02-29T12:34:58Z',
|
||||||
|
timestamp: 1646115296,
|
||||||
|
id: '123456',
|
||||||
|
traceId: '987654',
|
||||||
|
spanId: '54321',
|
||||||
|
traceFlags: 0,
|
||||||
|
severityNumber: 2,
|
||||||
|
body: 'Sample log',
|
||||||
|
resources_string: {},
|
||||||
|
attributesString: {},
|
||||||
|
attributes_string: {},
|
||||||
|
attributesInt: {},
|
||||||
|
attributesFloat: {},
|
||||||
|
severity_text: 'FATAL',
|
||||||
|
severityText: '',
|
||||||
|
};
|
||||||
|
expect(getLogIndicatorType(log)).toBe('FATAL');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getLogIndicatorTypeForTable', () => {
|
||||||
|
it('should return severity type for valid log with severityText', () => {
|
||||||
|
const log = {
|
||||||
|
date: '2024-02-29T12:34:56Z',
|
||||||
|
timestamp: 1646115296,
|
||||||
|
id: '123456',
|
||||||
|
traceId: '987654',
|
||||||
|
spanId: '54321',
|
||||||
|
traceFlags: 0,
|
||||||
|
severity_number: 2,
|
||||||
|
body: 'Sample log message',
|
||||||
|
resources_string: {},
|
||||||
|
attributesString: {},
|
||||||
|
attributes_string: {},
|
||||||
|
attributesInt: {},
|
||||||
|
attributesFloat: {},
|
||||||
|
severity_text: 'WARN',
|
||||||
|
};
|
||||||
|
expect(getLogIndicatorTypeForTable(log)).toBe('WARN');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return log level if severityText is missing', () => {
|
||||||
|
const log = {
|
||||||
|
date: '2024-02-29T12:34:56Z',
|
||||||
|
timestamp: 1646115296,
|
||||||
|
id: '123456',
|
||||||
|
traceId: '987654',
|
||||||
|
spanId: '54321',
|
||||||
|
traceFlags: 0,
|
||||||
|
severityNumber: 2,
|
||||||
|
body: 'Sample log message',
|
||||||
|
resources_string: {},
|
||||||
|
attributesString: {},
|
||||||
|
attributes_string: {},
|
||||||
|
attributesInt: {},
|
||||||
|
attributesFloat: {},
|
||||||
|
log_level: 'INFO',
|
||||||
|
};
|
||||||
|
expect(getLogIndicatorTypeForTable(log)).toBe('INFO');
|
||||||
|
});
|
||||||
|
});
|
57
frontend/src/components/Logs/LogStateIndicator/utils.ts
Normal file
57
frontend/src/components/Logs/LogStateIndicator/utils.ts
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
import { ILog } from 'types/api/logs/log';
|
||||||
|
|
||||||
|
import { LogType, SEVERITY_TEXT_TYPE } from './LogStateIndicator';
|
||||||
|
|
||||||
|
const getSeverityType = (severityText: string): string => {
|
||||||
|
switch (severityText) {
|
||||||
|
case SEVERITY_TEXT_TYPE.TRACE:
|
||||||
|
case SEVERITY_TEXT_TYPE.TRACE2:
|
||||||
|
case SEVERITY_TEXT_TYPE.TRACE3:
|
||||||
|
case SEVERITY_TEXT_TYPE.TRACE4:
|
||||||
|
return SEVERITY_TEXT_TYPE.TRACE;
|
||||||
|
case SEVERITY_TEXT_TYPE.DEBUG:
|
||||||
|
case SEVERITY_TEXT_TYPE.DEBUG2:
|
||||||
|
case SEVERITY_TEXT_TYPE.DEBUG3:
|
||||||
|
case SEVERITY_TEXT_TYPE.DEBUG4:
|
||||||
|
return SEVERITY_TEXT_TYPE.DEBUG;
|
||||||
|
case SEVERITY_TEXT_TYPE.INFO:
|
||||||
|
case SEVERITY_TEXT_TYPE.INFO2:
|
||||||
|
case SEVERITY_TEXT_TYPE.INFO3:
|
||||||
|
case SEVERITY_TEXT_TYPE.INFO4:
|
||||||
|
return SEVERITY_TEXT_TYPE.INFO;
|
||||||
|
case SEVERITY_TEXT_TYPE.WARN:
|
||||||
|
case SEVERITY_TEXT_TYPE.WARN2:
|
||||||
|
case SEVERITY_TEXT_TYPE.WARN3:
|
||||||
|
case SEVERITY_TEXT_TYPE.WARN4:
|
||||||
|
case SEVERITY_TEXT_TYPE.WARNING:
|
||||||
|
return SEVERITY_TEXT_TYPE.WARN;
|
||||||
|
case SEVERITY_TEXT_TYPE.ERROR:
|
||||||
|
case SEVERITY_TEXT_TYPE.ERROR2:
|
||||||
|
case SEVERITY_TEXT_TYPE.ERROR3:
|
||||||
|
case SEVERITY_TEXT_TYPE.ERROR4:
|
||||||
|
return SEVERITY_TEXT_TYPE.ERROR;
|
||||||
|
case SEVERITY_TEXT_TYPE.FATAL:
|
||||||
|
case SEVERITY_TEXT_TYPE.FATAL2:
|
||||||
|
case SEVERITY_TEXT_TYPE.FATAL3:
|
||||||
|
case SEVERITY_TEXT_TYPE.FATAL4:
|
||||||
|
return SEVERITY_TEXT_TYPE.FATAL;
|
||||||
|
default:
|
||||||
|
return SEVERITY_TEXT_TYPE.INFO;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getLogIndicatorType = (logData: ILog): string => {
|
||||||
|
if (logData.severity_text) {
|
||||||
|
return getSeverityType(logData.severity_text);
|
||||||
|
}
|
||||||
|
return logData.attributes_string?.log_level || LogType.INFO;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getLogIndicatorTypeForTable = (
|
||||||
|
log: Record<string, unknown>,
|
||||||
|
): string => {
|
||||||
|
if (log.severity_text) {
|
||||||
|
return getSeverityType(log.severity_text as string);
|
||||||
|
}
|
||||||
|
return (log.log_level as string) || LogType.INFO;
|
||||||
|
};
|
@ -23,9 +23,8 @@ import {
|
|||||||
} from 'react';
|
} from 'react';
|
||||||
|
|
||||||
import LogLinesActionButtons from '../LogLinesActionButtons/LogLinesActionButtons';
|
import LogLinesActionButtons from '../LogLinesActionButtons/LogLinesActionButtons';
|
||||||
import LogStateIndicator, {
|
import LogStateIndicator from '../LogStateIndicator/LogStateIndicator';
|
||||||
LogType,
|
import { getLogIndicatorType } from '../LogStateIndicator/utils';
|
||||||
} from '../LogStateIndicator/LogStateIndicator';
|
|
||||||
// styles
|
// styles
|
||||||
import { RawLogContent, RawLogViewContainer } from './styles';
|
import { RawLogContent, RawLogViewContainer } from './styles';
|
||||||
import { RawLogViewProps } from './types';
|
import { RawLogViewProps } from './types';
|
||||||
@ -64,7 +63,7 @@ function RawLogView({
|
|||||||
|
|
||||||
const severityText = data.severity_text ? `${data.severity_text} |` : '';
|
const severityText = data.severity_text ? `${data.severity_text} |` : '';
|
||||||
|
|
||||||
const logType = data?.attributes_string?.log_level || LogType.INFO;
|
const logType = getLogIndicatorType(data);
|
||||||
|
|
||||||
const updatedSelecedFields = useMemo(
|
const updatedSelecedFields = useMemo(
|
||||||
() => selectedFields.filter((e) => e.name !== 'id'),
|
() => selectedFields.filter((e) => e.name !== 'id'),
|
||||||
|
@ -7,12 +7,10 @@ import dayjs from 'dayjs';
|
|||||||
import dompurify from 'dompurify';
|
import dompurify from 'dompurify';
|
||||||
import { useIsDarkMode } from 'hooks/useDarkMode';
|
import { useIsDarkMode } from 'hooks/useDarkMode';
|
||||||
import { FlatLogData } from 'lib/logs/flatLogData';
|
import { FlatLogData } from 'lib/logs/flatLogData';
|
||||||
import { defaultTo } from 'lodash-es';
|
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
|
|
||||||
import LogStateIndicator, {
|
import LogStateIndicator from '../LogStateIndicator/LogStateIndicator';
|
||||||
LogType,
|
import { getLogIndicatorTypeForTable } from '../LogStateIndicator/utils';
|
||||||
} from '../LogStateIndicator/LogStateIndicator';
|
|
||||||
import {
|
import {
|
||||||
defaultListViewPanelStyle,
|
defaultListViewPanelStyle,
|
||||||
defaultTableStyle,
|
defaultTableStyle,
|
||||||
@ -84,7 +82,7 @@ export const useTableView = (props: UseTableViewProps): UseTableViewResult => {
|
|||||||
children: (
|
children: (
|
||||||
<div className="table-timestamp">
|
<div className="table-timestamp">
|
||||||
<LogStateIndicator
|
<LogStateIndicator
|
||||||
type={defaultTo(item.log_level, LogType.INFO) as string}
|
type={getLogIndicatorTypeForTable(item)}
|
||||||
isActive={
|
isActive={
|
||||||
activeLog?.id === item.id || activeContextLog?.id === item.id
|
activeLog?.id === item.id || activeContextLog?.id === item.id
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user