diff --git a/frontend/src/components/Logs/ListLogView/index.tsx b/frontend/src/components/Logs/ListLogView/index.tsx index bdc8b2e77f0c..c77d31ddc81f 100644 --- a/frontend/src/components/Logs/ListLogView/index.tsx +++ b/frontend/src/components/Logs/ListLogView/index.tsx @@ -208,7 +208,11 @@ function ListLogView({ fontSize={fontSize} >
- +
{updatedSelecedFields.some((field) => field.name === 'body') && ( diff --git a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.styles.scss b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.styles.scss index 5c2720e954c6..b3e51fe54f42 100644 --- a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.styles.scss +++ b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.styles.scss @@ -7,7 +7,6 @@ height: 100%; width: 3px; border-radius: 50px; - background-color: transparent; &.small { min-height: 16px; @@ -21,24 +20,107 @@ min-height: 24px; } - &.INFO { - background-color: var(--bg-robin-500); + // Severity variant CSS classes using design tokens + // Trace variants - + &.severity-trace-0 { + background-color: var(--bg-forest-600); } - &.WARNING, - &.WARN { - background-color: var(--bg-amber-500); + &.severity-trace-1 { + background-color: var(--bg-forest-500); } - &.ERROR { - background-color: var(--bg-cherry-500); - } - &.TRACE { + &.severity-trace-2 { background-color: var(--bg-forest-400); } - &.DEBUG { + &.severity-trace-3 { + background-color: var(--bg-forest-300); + } + &.severity-trace-4 { + background-color: var(--bg-forest-200); + } + + // Debug variants + &.severity-debug-0 { + background-color: var(--bg-aqua-600); + } + &.severity-debug-1 { background-color: var(--bg-aqua-500); } - &.FATAL { + &.severity-debug-2 { + background-color: var(--bg-aqua-400); + } + &.severity-debug-3 { + background-color: var(--bg-aqua-300); + } + &.severity-debug-4 { + background-color: var(--bg-aqua-200); + } + + // Info variants + &.severity-info-0 { + background-color: var(--bg-robin-600); + } + &.severity-info-1 { + background-color: var(--bg-robin-500); + } + &.severity-info-2 { + background-color: var(--bg-robin-400); + } + &.severity-info-3 { + background-color: var(--bg-robin-300); + } + &.severity-info-4 { + background-color: var(--bg-robin-200); + } + + // Warn variants + &.severity-warn-0 { + background-color: var(--bg-amber-600); + } + &.severity-warn-1 { + background-color: var(--bg-amber-500); + } + &.severity-warn-2 { + background-color: var(--bg-amber-400); + } + &.severity-warn-3 { + background-color: var(--bg-amber-300); + } + &.severity-warn-4 { + background-color: var(--bg-amber-200); + } + + // Error variants + &.severity-error-0 { + background-color: var(--bg-cherry-600); + } + &.severity-error-1 { + background-color: var(--bg-cherry-500); + } + &.severity-error-2 { + background-color: var(--bg-cherry-400); + } + &.severity-error-3 { + background-color: var(--bg-cherry-300); + } + &.severity-error-4 { + background-color: var(--bg-cherry-200); + } + + // Fatal variants + &.severity-fatal-0 { + background-color: var(--bg-sakura-600); + } + &.severity-fatal-1 { background-color: var(--bg-sakura-500); } + &.severity-fatal-2 { + background-color: var(--bg-sakura-400); + } + &.severity-fatal-3 { + background-color: var(--bg-sakura-300); + } + &.severity-fatal-4 { + background-color: var(--bg-sakura-200); + } } } diff --git a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.test.tsx b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.test.tsx index 5ecddd5959c5..086710d74bbe 100644 --- a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.test.tsx +++ b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.test.tsx @@ -6,37 +6,41 @@ 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, - ); + expect( + container.querySelector('.line')?.classList.contains('severity-info-0'), + ).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'), + containerInfo.querySelector('.line')?.classList.contains('severity-info-0'), + ).toBe(true); + + const { container: containerWarning } = render( + , + ); + expect( + containerWarning + .querySelector('.line') + ?.classList.contains('severity-warn-0'), ).toBe(true); const { container: containerError } = render( - , + , ); expect( - containerError.querySelector('.line')?.classList.contains('ERROR'), + containerError + .querySelector('.line') + ?.classList.contains('severity-error-0'), ).toBe(true); }); }); diff --git a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.tsx b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.tsx index f831c6252a88..7f2eeb4ecaf9 100644 --- a/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.tsx +++ b/frontend/src/components/Logs/LogStateIndicator/LogStateIndicator.tsx @@ -3,6 +3,8 @@ import './LogStateIndicator.styles.scss'; import cx from 'classnames'; import { FontSize } from 'container/OptionsMenu/types'; +import { getLogTypeBySeverityNumber } from './utils'; + export const SEVERITY_TEXT_TYPE = { TRACE: 'TRACE', TRACE2: 'TRACE2', @@ -42,18 +44,112 @@ export const LogType = { UNKNOWN: 'UNKNOWN', } as const; +// Severity variant mapping to CSS classes +const SEVERITY_VARIANT_CLASSES: Record = { + // Trace variants - forest-600 to forest-200 + TRACE: 'severity-trace-0', + Trace: 'severity-trace-1', + trace: 'severity-trace-2', + trc: 'severity-trace-3', + Trc: 'severity-trace-4', + + // Debug variants - aqua-600 to aqua-200 + DEBUG: 'severity-debug-0', + Debug: 'severity-debug-1', + debug: 'severity-debug-2', + dbg: 'severity-debug-3', + Dbg: 'severity-debug-4', + + // Info variants - robin-600 to robin-200 + INFO: 'severity-info-0', + Info: 'severity-info-1', + info: 'severity-info-2', + Information: 'severity-info-3', + information: 'severity-info-4', + + // Warn variants - amber-600 to amber-200 + WARN: 'severity-warn-0', + WARNING: 'severity-warn-0', + Warn: 'severity-warn-1', + warn: 'severity-warn-2', + warning: 'severity-warn-3', + Warning: 'severity-warn-4', + wrn: 'severity-warn-3', + Wrn: 'severity-warn-4', + + // Error variants - cherry-600 to cherry-200 + // eslint-disable-next-line sonarjs/no-duplicate-string + ERROR: 'severity-error-0', + Error: 'severity-error-1', + error: 'severity-error-2', + err: 'severity-error-3', + Err: 'severity-error-4', + ERR: 'severity-error-0', + fail: 'severity-error-2', + Fail: 'severity-error-3', + FAIL: 'severity-error-0', + + // Fatal variants - sakura-600 to sakura-200 + // eslint-disable-next-line sonarjs/no-duplicate-string + FATAL: 'severity-fatal-0', + Fatal: 'severity-fatal-1', + fatal: 'severity-fatal-2', + // eslint-disable-next-line sonarjs/no-duplicate-string + critical: 'severity-fatal-3', + Critical: 'severity-fatal-4', + CRITICAL: 'severity-fatal-0', + crit: 'severity-fatal-3', + Crit: 'severity-fatal-4', + CRIT: 'severity-fatal-0', + panic: 'severity-fatal-2', + Panic: 'severity-fatal-3', + PANIC: 'severity-fatal-0', +}; + +function getSeverityClass( + severityText?: string, + severityNumber?: number, +): string { + // Priority 1: Use severityText for exact variant mapping + if (severityText) { + const variantClass = SEVERITY_VARIANT_CLASSES[severityText.trim()]; + if (variantClass) { + return variantClass; + } + } + + // Priority 2: Use severityNumber for base color (use middle shade as default) + if (severityNumber) { + const logType = getLogTypeBySeverityNumber(severityNumber); + if (logType !== LogType.UNKNOWN) { + return `severity-${logType.toLowerCase()}-0`; // Use middle shade (index 2) + } + } + + return 'severity-info-0'; // Fallback to CSS classes based on type +} + function LogStateIndicator({ - type, fontSize, + severityText, + severityNumber, }: { - type: string; fontSize: FontSize; + severityText?: string; + severityNumber?: number; }): JSX.Element { + const severityClass = getSeverityClass(severityText, severityNumber); + return (
-
+
); } +LogStateIndicator.defaultProps = { + severityText: '', + severityNumber: 0, +}; + export default LogStateIndicator; diff --git a/frontend/src/components/Logs/LogStateIndicator/utils.ts b/frontend/src/components/Logs/LogStateIndicator/utils.ts index 03989a8dd602..963f319aceb0 100644 --- a/frontend/src/components/Logs/LogStateIndicator/utils.ts +++ b/frontend/src/components/Logs/LogStateIndicator/utils.ts @@ -41,7 +41,7 @@ const getLogTypeBySeverityText = (severityText: string): string => { }; // https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber -const getLogTypeBySeverityNumber = (severityNumber: number): string => { +export const getLogTypeBySeverityNumber = (severityNumber: number): string => { if (severityNumber < 1) { return LogType.UNKNOWN; } diff --git a/frontend/src/components/Logs/RawLogView/index.tsx b/frontend/src/components/Logs/RawLogView/index.tsx index 4ad7329f8353..c1f1cc346c69 100644 --- a/frontend/src/components/Logs/RawLogView/index.tsx +++ b/frontend/src/components/Logs/RawLogView/index.tsx @@ -192,7 +192,11 @@ function RawLogView({ onMouseLeave={handleMouseLeave} fontSize={fontSize} > - + { children: (
), diff --git a/frontend/src/container/LogsExplorerChart/utils.ts b/frontend/src/container/LogsExplorerChart/utils.ts index 40253750da26..dc51d005d2f1 100644 --- a/frontend/src/container/LogsExplorerChart/utils.ts +++ b/frontend/src/container/LogsExplorerChart/utils.ts @@ -2,12 +2,80 @@ import { Color } from '@signozhq/design-tokens'; import { themeColors } from 'constants/theme'; import { colors } from 'lib/getRandomColor'; +const SEVERITY_VARIANT_COLORS: Record = { + TRACE: Color.BG_FOREST_600, + Trace: Color.BG_FOREST_500, + trace: Color.BG_FOREST_400, + trc: Color.BG_FOREST_300, + Trc: Color.BG_FOREST_200, + + DEBUG: Color.BG_AQUA_600, + Debug: Color.BG_AQUA_500, + debug: Color.BG_AQUA_400, + dbg: Color.BG_AQUA_300, + Dbg: Color.BG_AQUA_200, + + INFO: Color.BG_ROBIN_600, + Info: Color.BG_ROBIN_500, + info: Color.BG_ROBIN_400, + Information: Color.BG_ROBIN_300, + information: Color.BG_ROBIN_200, + + WARN: Color.BG_AMBER_600, + Warn: Color.BG_AMBER_500, + warn: Color.BG_AMBER_400, + warning: Color.BG_AMBER_300, + Warning: Color.BG_AMBER_200, + wrn: Color.BG_AMBER_300, + Wrn: Color.BG_AMBER_200, + + ERROR: Color.BG_CHERRY_600, + Error: Color.BG_CHERRY_500, + error: Color.BG_CHERRY_400, + err: Color.BG_CHERRY_300, + Err: Color.BG_CHERRY_200, + ERR: Color.BG_CHERRY_600, + fail: Color.BG_CHERRY_400, + Fail: Color.BG_CHERRY_300, + FAIL: Color.BG_CHERRY_600, + + FATAL: Color.BG_SAKURA_600, + Fatal: Color.BG_SAKURA_500, + fatal: Color.BG_SAKURA_400, + critical: Color.BG_SAKURA_300, + Critical: Color.BG_SAKURA_200, + CRITICAL: Color.BG_SAKURA_600, + crit: Color.BG_SAKURA_300, + Crit: Color.BG_SAKURA_200, + CRIT: Color.BG_SAKURA_600, + panic: Color.BG_SAKURA_400, + Panic: Color.BG_SAKURA_300, + PANIC: Color.BG_SAKURA_600, +}; + +// Simple function to get severity color for any component +export function getSeverityColor(severityText: string): string { + const variantColor = SEVERITY_VARIANT_COLORS[severityText.trim()]; + if (variantColor) { + return variantColor; + } + + return Color.BG_ROBIN_500; // Default fallback +} + export function getColorsForSeverityLabels( label: string, index: number, ): string { + // Check if we have a direct mapping for this severity variant + const variantColor = SEVERITY_VARIANT_COLORS[label.trim()]; + if (variantColor) { + return variantColor; + } + const lowerCaseLabel = label.toLowerCase(); + // Fallback to old format for backward compatibility if (lowerCaseLabel.includes(`{severity_text="trace"}`)) { return Color.BG_FOREST_400; } diff --git a/frontend/src/container/LogsExplorerList/ColumnView/ColumnView.tsx b/frontend/src/container/LogsExplorerList/ColumnView/ColumnView.tsx index 052095277e26..9e65d648fa4c 100644 --- a/frontend/src/container/LogsExplorerList/ColumnView/ColumnView.tsx +++ b/frontend/src/container/LogsExplorerList/ColumnView/ColumnView.tsx @@ -4,7 +4,6 @@ import { ColumnDef, DataTable, Row } from '@signozhq/table'; import LogDetail from 'components/LogDetail'; import { VIEW_TYPES } from 'components/LogDetail/constants'; import LogStateIndicator from 'components/Logs/LogStateIndicator/LogStateIndicator'; -import { getLogIndicatorTypeForTable } from 'components/Logs/LogStateIndicator/utils'; import { useTableView } from 'components/Logs/TableView/useTableView'; import { DATE_TIME_FORMATS } from 'constants/dateTimeFormats'; import { LOCALSTORAGE } from 'constants/localStorage'; @@ -169,10 +168,14 @@ function ColumnView({ getValue: () => string | JSX.Element; }): string | JSX.Element => { if (field.key === 'state-indicator') { - const type = getLogIndicatorTypeForTable(row.original); const fontSize = options.fontSize as FontSize; - return ; + return ( + + ); } const isTimestamp = field.key === 'timestamp';