Skip to content

Commit

Permalink
Logs Strip color according to severity_text (SigNoz#4643)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
Rajat Dabade and nityanandagohain authored Mar 7, 2024
1 parent 62af836 commit 54c6931
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 18 deletions.
7 changes: 3 additions & 4 deletions frontend/src/components/Logs/ListLogView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@ import { ILog } from 'types/api/logs/log';
// components
import AddToQueryHOC, { AddToQueryHOCProps } from '../AddToQueryHOC';
import LogLinesActionButtons from '../LogLinesActionButtons/LogLinesActionButtons';
import LogStateIndicator, {
LogType,
} from '../LogStateIndicator/LogStateIndicator';
import LogStateIndicator from '../LogStateIndicator/LogStateIndicator';
import { getLogIndicatorType } from '../LogStateIndicator/utils';
// styles
import {
Container,
Expand Down Expand Up @@ -152,7 +151,7 @@ function ListLogView({
[flattenLogData.timestamp],
);

const logType = logData?.attributes_string?.log_level || LogType.INFO;
const logType = getLogIndicatorType(logData);

const handleMouseEnter = (): void => {
setHasActionButtons(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,27 @@
background-color: transparent;

&.INFO {
background-color: #1d212d;
background-color: var(--bg-slate-400);
}

&.WARNING {
background-color: #ffcd56;
&.WARNING, &.WARN {
background-color: var(--bg-amber-500);
}

&.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);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,40 @@ import './LogStateIndicator.styles.scss';

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 = {
INFO: 'INFO',
WARNING: 'WARNING',
ERROR: 'ERROR',
};
} as const;

function LogStateIndicator({
type,
isActive,
Expand Down
89 changes: 89 additions & 0 deletions frontend/src/components/Logs/LogStateIndicator/utils.test.ts
Original file line number Diff line number Diff line change
@@ -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 changes: 57 additions & 0 deletions frontend/src/components/Logs/LogStateIndicator/utils.ts
Original file line number Diff line number Diff line change
@@ -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;
};
7 changes: 3 additions & 4 deletions frontend/src/components/Logs/RawLogView/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,8 @@ import {
} from 'react';

import LogLinesActionButtons from '../LogLinesActionButtons/LogLinesActionButtons';
import LogStateIndicator, {
LogType,
} from '../LogStateIndicator/LogStateIndicator';
import LogStateIndicator from '../LogStateIndicator/LogStateIndicator';
import { getLogIndicatorType } from '../LogStateIndicator/utils';
// styles
import { RawLogContent, RawLogViewContainer } from './styles';
import { RawLogViewProps } from './types';
Expand Down Expand Up @@ -64,7 +63,7 @@ function RawLogView({

const severityText = data.severity_text ? `${data.severity_text} |` : '';

const logType = data?.attributes_string?.log_level || LogType.INFO;
const logType = getLogIndicatorType(data);

const updatedSelecedFields = useMemo(
() => selectedFields.filter((e) => e.name !== 'id'),
Expand Down
8 changes: 3 additions & 5 deletions frontend/src/components/Logs/TableView/useTableView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ import dayjs from 'dayjs';
import dompurify from 'dompurify';
import { useIsDarkMode } from 'hooks/useDarkMode';
import { FlatLogData } from 'lib/logs/flatLogData';
import { defaultTo } from 'lodash-es';
import { useMemo } from 'react';

import LogStateIndicator, {
LogType,
} from '../LogStateIndicator/LogStateIndicator';
import LogStateIndicator from '../LogStateIndicator/LogStateIndicator';
import { getLogIndicatorTypeForTable } from '../LogStateIndicator/utils';
import {
defaultListViewPanelStyle,
defaultTableStyle,
Expand Down Expand Up @@ -84,7 +82,7 @@ export const useTableView = (props: UseTableViewProps): UseTableViewResult => {
children: (
<div className="table-timestamp">
<LogStateIndicator
type={defaultTo(item.log_level, LogType.INFO) as string}
type={getLogIndicatorTypeForTable(item)}
isActive={
activeLog?.id === item.id || activeContextLog?.id === item.id
}
Expand Down

0 comments on commit 54c6931

Please sign in to comment.