mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Logs: Added support for numeric log levels (#87366)
* logs: add support for numeric loglevels * Log types: add a numeric level map to LogLevel * getLogLevelFromKey: adapt to support numeric levels * Formatting * getLogLevelFromKey: accept strings or numbers --------- Co-authored-by: Matias Chomicki <matyax@gmail.com>
This commit is contained in:
@@ -92,15 +92,15 @@ For the logs where a `level` label is specified, we use the value of this label
|
||||
|
||||
**Supported log levels and mapping of log level abbreviation and expressions:**
|
||||
|
||||
| Log level | Color | Supported expressions |
|
||||
| :-------- | :--------- | ---------------------------------------- |
|
||||
| critical | purple | emerg, fatal, alert, crit, critical |
|
||||
| error | red | err, eror, error |
|
||||
| warning | yellow | warn, warning |
|
||||
| info | green | info, information, informational, notice |
|
||||
| debug | blue | dbug, debug |
|
||||
| trace | light blue | trace |
|
||||
| unknown | grey | \* |
|
||||
| Log level | Color | Supported expressions |
|
||||
| :-------- | :--------- | ---------------------------------------------- |
|
||||
| critical | purple | emerg, fatal, alert, crit, critical, 0, 1, 2 |
|
||||
| error | red | err, eror, error, 3 |
|
||||
| warning | yellow | warn, warning, 4 |
|
||||
| info | green | info, information, informational, notice, 5, 6 |
|
||||
| debug | blue | dbug, debug, 7 |
|
||||
| trace | light blue | trace |
|
||||
| unknown | grey | \* |
|
||||
|
||||
### Highlight searched words
|
||||
|
||||
|
||||
@@ -33,6 +33,21 @@ export enum LogLevel {
|
||||
unknown = 'unknown',
|
||||
}
|
||||
|
||||
/**
|
||||
* Mapping of log level abbreviation to canonical log level.
|
||||
* Supported levels are reduce to limit color variation.
|
||||
*/
|
||||
export const NumericLogLevel: Record<string, LogLevel> = {
|
||||
'0': LogLevel.critical,
|
||||
'1': LogLevel.critical,
|
||||
'2': LogLevel.critical,
|
||||
'3': LogLevel.error,
|
||||
'4': LogLevel.warning,
|
||||
'5': LogLevel.info,
|
||||
'6': LogLevel.info,
|
||||
'7': LogLevel.debug,
|
||||
};
|
||||
|
||||
// Used for meta information such as common labels or returned log rows in logs view in Explore
|
||||
export enum LogsMetaKind {
|
||||
Number,
|
||||
|
||||
@@ -425,7 +425,7 @@ export function logSeriesToLogsModel(
|
||||
|
||||
let logLevel = LogLevel.unknown;
|
||||
const logLevelKey = (logLevelField && logLevelField.values[j]) || (labels && labels['level']);
|
||||
if (logLevelKey) {
|
||||
if (typeof logLevelKey === 'number' || typeof logLevelKey === 'string') {
|
||||
logLevel = getLogLevelFromKey(logLevelKey);
|
||||
} else {
|
||||
logLevel = getLogLevel(entry);
|
||||
|
||||
@@ -63,8 +63,30 @@ describe('getLogLevelFromKey()', () => {
|
||||
it('returns correct log level when level is capitalized', () => {
|
||||
expect(getLogLevelFromKey('INFO')).toBe(LogLevel.info);
|
||||
});
|
||||
it('returns unknown log level when level is integer', () => {
|
||||
expect(getLogLevelFromKey(1)).toBe(LogLevel.unknown);
|
||||
describe('Numeric log levels', () => {
|
||||
it('returns critical', () => {
|
||||
expect(getLogLevelFromKey(0)).toBe(LogLevel.critical);
|
||||
expect(getLogLevelFromKey('0')).toBe(LogLevel.critical);
|
||||
expect(getLogLevelFromKey('1')).toBe(LogLevel.critical);
|
||||
expect(getLogLevelFromKey('2')).toBe(LogLevel.critical);
|
||||
});
|
||||
it('returns error', () => {
|
||||
expect(getLogLevelFromKey('3')).toBe(LogLevel.error);
|
||||
});
|
||||
it('returns warning', () => {
|
||||
expect(getLogLevelFromKey('4')).toBe(LogLevel.warning);
|
||||
});
|
||||
it('returns info', () => {
|
||||
expect(getLogLevelFromKey('5')).toBe(LogLevel.info);
|
||||
expect(getLogLevelFromKey('6')).toBe(LogLevel.info);
|
||||
});
|
||||
it('returns debug', () => {
|
||||
expect(getLogLevelFromKey('7')).toBe(LogLevel.debug);
|
||||
});
|
||||
it('returns unknown log level when level is an unexpected integer', () => {
|
||||
expect(getLogLevelFromKey('8')).toBe(LogLevel.unknown);
|
||||
expect(getLogLevelFromKey(8)).toBe(LogLevel.unknown);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
MutableDataFrame,
|
||||
QueryResultMeta,
|
||||
LogsVolumeType,
|
||||
NumericLogLevel,
|
||||
} from '@grafana/data';
|
||||
|
||||
import { getDataframeFields } from './components/logParser';
|
||||
@@ -49,6 +50,17 @@ export function getLogLevelFromKey(key: string | number): LogLevel {
|
||||
if (level) {
|
||||
return level;
|
||||
}
|
||||
if (typeof key === 'string') {
|
||||
// The level did not match any entry of LogLevel. It might be unknown or a numeric level.
|
||||
const numericLevel = parseInt(key, 10);
|
||||
// Safety check to confirm that we're parsing a number and not a number with a string.
|
||||
// For example `parseInt('1abcd', 10)` outputs 1
|
||||
if (key.length === numericLevel.toString().length) {
|
||||
return NumericLogLevel[key] || LogLevel.unknown;
|
||||
}
|
||||
} else if (typeof key === 'number') {
|
||||
return NumericLogLevel[key] || LogLevel.unknown;
|
||||
}
|
||||
|
||||
return LogLevel.unknown;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user