diff --git a/frontend/src/components/Logs/ListLogView/index.tsx b/frontend/src/components/Logs/ListLogView/index.tsx index 10790255cf..5452db0f16 100644 --- a/frontend/src/components/Logs/ListLogView/index.tsx +++ b/frontend/src/components/Logs/ListLogView/index.tsx @@ -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, @@ -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); diff --git a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.styles.scss b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.styles.scss index 6d2429b592..a00c7f6761 100644 --- a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.styles.scss +++ b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.styles.scss @@ -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); } } diff --git a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.test.tsx b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.test.tsx new file mode 100644 index 0000000000..d924c27426 --- /dev/null +++ b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.test.tsx @@ -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(); + 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(); + const indicator = container.firstChild as HTMLElement; + expect(indicator.classList.contains('isActive')).toBe(true); + }); + + it('renders correctly with different types', () => { + const { container: containerInfo } = render( + , + ); + expect(containerInfo.querySelector('.line')?.classList.contains('INFO')).toBe( + true, + ); + + const { container: containerWarning } = render( + , + ); + expect( + containerWarning.querySelector('.line')?.classList.contains('WARNING'), + ).toBe(true); + + const { container: containerError } = render( + , + ); + expect( + containerError.querySelector('.line')?.classList.contains('ERROR'), + ).toBe(true); + }); +}); diff --git a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.tsx b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.tsx index 4c9b7de903..5355e38017 100644 --- a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.tsx +++ b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.tsx @@ -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, diff --git a/frontend/src/components/Logs/LogStateIndicator/utils.test.ts b/frontend/src/components/Logs/LogStateIndicator/utils.test.ts new file mode 100644 index 0000000000..65f6b9664d --- /dev/null +++ b/frontend/src/components/Logs/LogStateIndicator/utils.test.ts @@ -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'); + }); +}); diff --git a/frontend/src/components/Logs/LogStateIndicator/utils.ts b/frontend/src/components/Logs/LogStateIndicator/utils.ts new file mode 100644 index 0000000000..7bfe7a430a --- /dev/null +++ b/frontend/src/components/Logs/LogStateIndicator/utils.ts @@ -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 => { + if (log.severity_text) { + return getSeverityType(log.severity_text as string); + } + return (log.log_level as string) || LogType.INFO; +}; diff --git a/frontend/src/components/Logs/RawLogView/index.tsx b/frontend/src/components/Logs/RawLogView/index.tsx index 94c9dbe1bb..419bb33a76 100644 --- a/frontend/src/components/Logs/RawLogView/index.tsx +++ b/frontend/src/components/Logs/RawLogView/index.tsx @@ -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'; @@ -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'), diff --git a/frontend/src/components/Logs/TableView/useTableView.tsx b/frontend/src/components/Logs/TableView/useTableView.tsx index 9db2332635..259e046370 100644 --- a/frontend/src/components/Logs/TableView/useTableView.tsx +++ b/frontend/src/components/Logs/TableView/useTableView.tsx @@ -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, @@ -84,7 +82,7 @@ export const useTableView = (props: UseTableViewProps): UseTableViewResult => { children: (