mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Graph log entries by log level
This commit is contained in:
parent
e39e82949d
commit
a5ed86edba
@ -1,5 +1,6 @@
|
||||
import _ from 'lodash';
|
||||
import { TimeSeries } from 'app/core/core';
|
||||
import colors from 'app/core/utils/colors';
|
||||
|
||||
export enum LogLevel {
|
||||
crit = 'crit',
|
||||
@ -9,8 +10,20 @@ export enum LogLevel {
|
||||
info = 'info',
|
||||
debug = 'debug',
|
||||
trace = 'trace',
|
||||
none = 'none',
|
||||
}
|
||||
|
||||
export const LogLevelColor = {
|
||||
[LogLevel.crit]: colors[7],
|
||||
[LogLevel.warn]: colors[1],
|
||||
[LogLevel.err]: colors[4],
|
||||
[LogLevel.error]: colors[4],
|
||||
[LogLevel.info]: colors[0],
|
||||
[LogLevel.debug]: colors[3],
|
||||
[LogLevel.trace]: colors[3],
|
||||
[LogLevel.none]: '#eee',
|
||||
};
|
||||
|
||||
export interface LogSearchMatch {
|
||||
start: number;
|
||||
length: number;
|
||||
@ -44,7 +57,7 @@ export interface LogsStream {
|
||||
labels: string;
|
||||
entries: LogsStreamEntry[];
|
||||
parsedLabels: { [key: string]: string };
|
||||
graphSeries: TimeSeries;
|
||||
intervalMs?: number;
|
||||
}
|
||||
|
||||
export interface LogsStreamEntry {
|
||||
|
@ -10,16 +10,16 @@ export const NO_DATA_COLOR = 'rgba(150, 150, 150, 1)';
|
||||
export const REGION_FILL_ALPHA = 0.09;
|
||||
|
||||
const colors = [
|
||||
'#7EB26D',
|
||||
'#EAB839',
|
||||
'#6ED0E0',
|
||||
'#EF843C',
|
||||
'#E24D42',
|
||||
'#1F78C1',
|
||||
'#BA43A9',
|
||||
'#705DA0',
|
||||
'#508642',
|
||||
'#CCA300',
|
||||
'#7EB26D', // 0: pale green
|
||||
'#EAB839', // 1: mustard
|
||||
'#6ED0E0', // 2: light blue
|
||||
'#EF843C', // 3: orange
|
||||
'#E24D42', // 4: red
|
||||
'#1F78C1', // 5: ocean
|
||||
'#BA43A9', // 6: purple
|
||||
'#705DA0', // 7: violet
|
||||
'#508642', // 8: dark green
|
||||
'#CCA300', // 9: dark sand
|
||||
'#447EBC',
|
||||
'#C15C17',
|
||||
'#890F02',
|
||||
|
@ -1,13 +1,12 @@
|
||||
import _ from 'lodash';
|
||||
import moment from 'moment';
|
||||
|
||||
import { LogLevel, LogsMetaItem, LogsModel, LogRow, LogsStream } from 'app/core/logs_model';
|
||||
import { LogLevel, LogLevelColor, LogsMetaItem, LogsModel, LogRow, LogsStream } from 'app/core/logs_model';
|
||||
import { TimeSeries } from 'app/core/core';
|
||||
import colors from 'app/core/utils/colors';
|
||||
|
||||
export function getLogLevel(line: string): LogLevel {
|
||||
if (!line) {
|
||||
return undefined;
|
||||
return LogLevel.none;
|
||||
}
|
||||
let level: LogLevel;
|
||||
Object.keys(LogLevel).forEach(key => {
|
||||
@ -18,6 +17,9 @@ export function getLogLevel(line: string): LogLevel {
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!level) {
|
||||
level = LogLevel.none;
|
||||
}
|
||||
return level;
|
||||
}
|
||||
|
||||
@ -107,8 +109,13 @@ export function mergeStreams(streams: LogsStream[], limit?: number): LogsModel {
|
||||
},
|
||||
];
|
||||
|
||||
let intervalMs;
|
||||
|
||||
// Flatten entries of streams
|
||||
const combinedEntries = streams.reduce((acc, stream) => {
|
||||
const combinedEntries: LogRow[] = streams.reduce((acc, stream) => {
|
||||
// Set interval for graphs
|
||||
intervalMs = stream.intervalMs;
|
||||
|
||||
// Overwrite labels to be only the non-common ones
|
||||
const labels = formatLabels(findUncommonLabels(stream.parsedLabels, commonLabels));
|
||||
return [
|
||||
@ -120,15 +127,34 @@ export function mergeStreams(streams: LogsStream[], limit?: number): LogsModel {
|
||||
];
|
||||
}, []);
|
||||
|
||||
const commonLabelsAlias =
|
||||
streams.length === 1 ? formatLabels(commonLabels) : `Stream with common labels ${formatLabels(commonLabels)}`;
|
||||
const series = streams.map((stream, index) => {
|
||||
const colorIndex = index % colors.length;
|
||||
stream.graphSeries.setColor(colors[colorIndex]);
|
||||
stream.graphSeries.alias = formatLabels(findUncommonLabels(stream.parsedLabels, commonLabels), commonLabelsAlias);
|
||||
return stream.graphSeries;
|
||||
// Graph time series by log level
|
||||
const seriesByLevel = {};
|
||||
combinedEntries.forEach(entry => {
|
||||
if (!seriesByLevel[entry.logLevel]) {
|
||||
seriesByLevel[entry.logLevel] = { lastTs: null, datapoints: [], alias: entry.logLevel };
|
||||
}
|
||||
const levelSeries = seriesByLevel[entry.logLevel];
|
||||
|
||||
// Bucket to nearest minute
|
||||
const time = Math.round(entry.timeJs / intervalMs / 10) * intervalMs * 10;
|
||||
// Entry for time
|
||||
if (time === levelSeries.lastTs) {
|
||||
levelSeries.datapoints[levelSeries.datapoints.length - 1][0]++;
|
||||
} else {
|
||||
levelSeries.datapoints.push([1, time]);
|
||||
levelSeries.lastTs = time;
|
||||
}
|
||||
});
|
||||
|
||||
const series = Object.keys(seriesByLevel).reduce((acc, level, index) => {
|
||||
if (seriesByLevel[level]) {
|
||||
const gs = new TimeSeries(seriesByLevel[level]);
|
||||
gs.setColor(LogLevelColor[level]);
|
||||
acc.push(gs);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
const sortedEntries = _.chain(combinedEntries)
|
||||
.sortBy('timestamp')
|
||||
.reverse()
|
||||
@ -151,25 +177,9 @@ export function processStream(stream: LogsStream, limit?: number, intervalMs?: n
|
||||
.slice(0, limit || stream.entries.length)
|
||||
.value();
|
||||
|
||||
// Build graph data
|
||||
let previousTime;
|
||||
const datapoints = sortedEntries.reduce((acc, entry, index) => {
|
||||
// Bucket to nearest minute
|
||||
const time = Math.round(entry.timeJs / intervalMs / 10) * intervalMs * 10;
|
||||
// Entry for time
|
||||
if (time === previousTime) {
|
||||
acc[acc.length - 1][0]++;
|
||||
} else {
|
||||
acc.push([1, time]);
|
||||
previousTime = time;
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
const graphSeries = new TimeSeries({ datapoints, alias: stream.labels });
|
||||
|
||||
return {
|
||||
...stream,
|
||||
graphSeries,
|
||||
intervalMs,
|
||||
entries: sortedEntries,
|
||||
parsedLabels: parseLabels(stream.labels),
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user