Просмотр исходного кода

Graph log entries by log level

David Kaltschmidt 7 лет назад
Родитель
Сommit
a5ed86edba

+ 14 - 1
public/app/core/logs_model.ts

@@ -1,5 +1,6 @@
 import _ from 'lodash';
 import _ from 'lodash';
 import { TimeSeries } from 'app/core/core';
 import { TimeSeries } from 'app/core/core';
+import colors from 'app/core/utils/colors';
 
 
 export enum LogLevel {
 export enum LogLevel {
   crit = 'crit',
   crit = 'crit',
@@ -9,8 +10,20 @@ export enum LogLevel {
   info = 'info',
   info = 'info',
   debug = 'debug',
   debug = 'debug',
   trace = 'trace',
   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 {
 export interface LogSearchMatch {
   start: number;
   start: number;
   length: number;
   length: number;
@@ -44,7 +57,7 @@ export interface LogsStream {
   labels: string;
   labels: string;
   entries: LogsStreamEntry[];
   entries: LogsStreamEntry[];
   parsedLabels: { [key: string]: string };
   parsedLabels: { [key: string]: string };
-  graphSeries: TimeSeries;
+  intervalMs?: number;
 }
 }
 
 
 export interface LogsStreamEntry {
 export interface LogsStreamEntry {

+ 10 - 10
public/app/core/utils/colors.ts

@@ -10,16 +10,16 @@ export const NO_DATA_COLOR = 'rgba(150, 150, 150, 1)';
 export const REGION_FILL_ALPHA = 0.09;
 export const REGION_FILL_ALPHA = 0.09;
 
 
 const colors = [
 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',
   '#447EBC',
   '#C15C17',
   '#C15C17',
   '#890F02',
   '#890F02',

+ 38 - 28
public/app/plugins/datasource/logging/result_transformer.ts

@@ -1,13 +1,12 @@
 import _ from 'lodash';
 import _ from 'lodash';
 import moment from 'moment';
 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 { TimeSeries } from 'app/core/core';
-import colors from 'app/core/utils/colors';
 
 
 export function getLogLevel(line: string): LogLevel {
 export function getLogLevel(line: string): LogLevel {
   if (!line) {
   if (!line) {
-    return undefined;
+    return LogLevel.none;
   }
   }
   let level: LogLevel;
   let level: LogLevel;
   Object.keys(LogLevel).forEach(key => {
   Object.keys(LogLevel).forEach(key => {
@@ -18,6 +17,9 @@ export function getLogLevel(line: string): LogLevel {
       }
       }
     }
     }
   });
   });
+  if (!level) {
+    level = LogLevel.none;
+  }
   return level;
   return level;
 }
 }
 
 
@@ -107,8 +109,13 @@ export function mergeStreams(streams: LogsStream[], limit?: number): LogsModel {
     },
     },
   ];
   ];
 
 
+  let intervalMs;
+
   // Flatten entries of streams
   // 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
     // Overwrite labels to be only the non-common ones
     const labels = formatLabels(findUncommonLabels(stream.parsedLabels, commonLabels));
     const labels = formatLabels(findUncommonLabels(stream.parsedLabels, commonLabels));
     return [
     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)
   const sortedEntries = _.chain(combinedEntries)
     .sortBy('timestamp')
     .sortBy('timestamp')
     .reverse()
     .reverse()
@@ -151,25 +177,9 @@ export function processStream(stream: LogsStream, limit?: number, intervalMs?: n
     .slice(0, limit || stream.entries.length)
     .slice(0, limit || stream.entries.length)
     .value();
     .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 {
   return {
     ...stream,
     ...stream,
-    graphSeries,
+    intervalMs,
     entries: sortedEntries,
     entries: sortedEntries,
     parsedLabels: parseLabels(stream.labels),
     parsedLabels: parseLabels(stream.labels),
   };
   };