mirror of
https://github.com/SigNoz/signoz.git
synced 2025-12-17 15:36:48 +00:00
fix: logs explorer chart severity text bugfixes (#8731)
* fix: fixed severity color getting incorrectly assigned due to the response changed in v5 API * fix: implement consistent severity variant colors across logs chart and indicator component * chore: fix the failing tests * chore: fix the failing check --------- Co-authored-by: ahmadshaheer <ashaheerki@gmail.com> Co-authored-by: Nityananda Gohain <nityanandagohain@gmail.com>
This commit is contained in:
parent
f91115948a
commit
f82e9b55f8
@ -208,7 +208,11 @@ function ListLogView({
|
||||
fontSize={fontSize}
|
||||
>
|
||||
<div className="log-line">
|
||||
<LogStateIndicator type={logType} fontSize={fontSize} />
|
||||
<LogStateIndicator
|
||||
fontSize={fontSize}
|
||||
severityText={logData.severity_text}
|
||||
severityNumber={logData.severity_number}
|
||||
/>
|
||||
<div>
|
||||
<LogContainer fontSize={fontSize}>
|
||||
{updatedSelecedFields.some((field) => field.name === 'body') && (
|
||||
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,37 +6,41 @@ import LogStateIndicator from './LogStateIndicator';
|
||||
describe('LogStateIndicator', () => {
|
||||
it('renders correctly with default props', () => {
|
||||
const { container } = render(
|
||||
<LogStateIndicator type="INFO" fontSize={FontSize.MEDIUM} />,
|
||||
<LogStateIndicator severityText="INFO" fontSize={FontSize.MEDIUM} />,
|
||||
);
|
||||
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(
|
||||
<LogStateIndicator type="INFO" fontSize={FontSize.MEDIUM} />,
|
||||
);
|
||||
expect(containerInfo.querySelector('.line')?.classList.contains('INFO')).toBe(
|
||||
true,
|
||||
);
|
||||
|
||||
const { container: containerWarning } = render(
|
||||
<LogStateIndicator type="WARNING" fontSize={FontSize.MEDIUM} />,
|
||||
<LogStateIndicator severityText="INFO" fontSize={FontSize.MEDIUM} />,
|
||||
);
|
||||
expect(
|
||||
containerWarning.querySelector('.line')?.classList.contains('WARNING'),
|
||||
containerInfo.querySelector('.line')?.classList.contains('severity-info-0'),
|
||||
).toBe(true);
|
||||
|
||||
const { container: containerWarning } = render(
|
||||
<LogStateIndicator severityText="WARNING" fontSize={FontSize.MEDIUM} />,
|
||||
);
|
||||
expect(
|
||||
containerWarning
|
||||
.querySelector('.line')
|
||||
?.classList.contains('severity-warn-0'),
|
||||
).toBe(true);
|
||||
|
||||
const { container: containerError } = render(
|
||||
<LogStateIndicator type="ERROR" fontSize={FontSize.MEDIUM} />,
|
||||
<LogStateIndicator severityText="ERROR" fontSize={FontSize.MEDIUM} />,
|
||||
);
|
||||
expect(
|
||||
containerError.querySelector('.line')?.classList.contains('ERROR'),
|
||||
containerError
|
||||
.querySelector('.line')
|
||||
?.classList.contains('severity-error-0'),
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
@ -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<string, string> = {
|
||||
// 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 (
|
||||
<div className="log-state-indicator">
|
||||
<div className={cx('line', type, fontSize)}> </div>
|
||||
<div className={cx('line', fontSize, severityClass)} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
LogStateIndicator.defaultProps = {
|
||||
severityText: '',
|
||||
severityNumber: 0,
|
||||
};
|
||||
|
||||
export default LogStateIndicator;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -192,7 +192,11 @@ function RawLogView({
|
||||
onMouseLeave={handleMouseLeave}
|
||||
fontSize={fontSize}
|
||||
>
|
||||
<LogStateIndicator type={logType} fontSize={fontSize} />
|
||||
<LogStateIndicator
|
||||
fontSize={fontSize}
|
||||
severityText={data.severity_text}
|
||||
severityNumber={data.severity_number}
|
||||
/>
|
||||
|
||||
<RawLogContent
|
||||
className="raw-log-content"
|
||||
|
||||
@ -11,7 +11,6 @@ import { useTimezone } from 'providers/Timezone';
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import LogStateIndicator from '../LogStateIndicator/LogStateIndicator';
|
||||
import { getLogIndicatorTypeForTable } from '../LogStateIndicator/utils';
|
||||
import {
|
||||
defaultListViewPanelStyle,
|
||||
defaultTableStyle,
|
||||
@ -93,8 +92,9 @@ export const useTableView = (props: UseTableViewProps): UseTableViewResult => {
|
||||
children: (
|
||||
<div className={cx('state-indicator', fontSize)}>
|
||||
<LogStateIndicator
|
||||
type={getLogIndicatorTypeForTable(item)}
|
||||
fontSize={fontSize}
|
||||
severityText={item.severity_text as string}
|
||||
severityNumber={item.severity_number as number}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
|
||||
@ -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<string, string> = {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -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 <LogStateIndicator type={type} fontSize={fontSize} />;
|
||||
return (
|
||||
<LogStateIndicator
|
||||
severityText={row.original?.severity_text}
|
||||
fontSize={fontSize}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
const isTimestamp = field.key === 'timestamp';
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user