mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Tests for label stats calculation
This commit is contained in:
parent
5916cb3e7c
commit
9f0b1e533f
@ -45,6 +45,13 @@ export interface LogRow {
|
|||||||
uniqueLabels?: LogsStreamLabels;
|
uniqueLabels?: LogsStreamLabels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface LogsLabelStat {
|
||||||
|
active?: boolean;
|
||||||
|
count: number;
|
||||||
|
proportion: number;
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
export enum LogsMetaKind {
|
export enum LogsMetaKind {
|
||||||
Number,
|
Number,
|
||||||
String,
|
String,
|
||||||
@ -88,6 +95,22 @@ export enum LogsDedupStrategy {
|
|||||||
signature = 'signature',
|
signature = 'signature',
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function calculateLogsLabelStats(rows: LogRow[], label: string): LogsLabelStat[] {
|
||||||
|
// Consider only rows that have the given label
|
||||||
|
const rowsWithLabel = rows.filter(row => row.labels[label] !== undefined);
|
||||||
|
const rowCount = rowsWithLabel.length;
|
||||||
|
|
||||||
|
// Get label value counts for eligible rows
|
||||||
|
const countsByValue = _.countBy(rowsWithLabel, row => (row as LogRow).labels[label]);
|
||||||
|
const sortedCounts = _.chain(countsByValue)
|
||||||
|
.map((count, value) => ({ count, value, proportion: count / rowCount }))
|
||||||
|
.sortBy('count')
|
||||||
|
.reverse()
|
||||||
|
.value();
|
||||||
|
|
||||||
|
return sortedCounts;
|
||||||
|
}
|
||||||
|
|
||||||
const isoDateRegexp = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-6]\d[,\.]\d+([+-][0-2]\d:[0-5]\d|Z)/g;
|
const isoDateRegexp = /\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-6]\d[,\.]\d+([+-][0-2]\d:[0-5]\d|Z)/g;
|
||||||
function isDuplicateRow(row: LogRow, other: LogRow, strategy: LogsDedupStrategy): boolean {
|
function isDuplicateRow(row: LogRow, other: LogRow, strategy: LogsDedupStrategy): boolean {
|
||||||
switch (strategy) {
|
switch (strategy) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { dedupLogRows, LogsDedupStrategy, LogsModel } from '../logs_model';
|
import { calculateLogsLabelStats, dedupLogRows, LogsDedupStrategy, LogsModel } from '../logs_model';
|
||||||
|
|
||||||
describe('dedupLogRows()', () => {
|
describe('dedupLogRows()', () => {
|
||||||
test('should return rows as is when dedup is set to none', () => {
|
test('should return rows as is when dedup is set to none', () => {
|
||||||
@ -106,3 +106,56 @@ describe('dedupLogRows()', () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('calculateLogsLabelStats()', () => {
|
||||||
|
test('should return no stats for empty rows', () => {
|
||||||
|
expect(calculateLogsLabelStats([], '')).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return no stats of label is not found', () => {
|
||||||
|
const rows = [
|
||||||
|
{
|
||||||
|
entry: 'foo 1',
|
||||||
|
labels: {
|
||||||
|
foo: 'bar',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(calculateLogsLabelStats(rows as any, 'baz')).toEqual([]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should return stats for found labels', () => {
|
||||||
|
const rows = [
|
||||||
|
{
|
||||||
|
entry: 'foo 1',
|
||||||
|
labels: {
|
||||||
|
foo: 'bar',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
entry: 'foo 0',
|
||||||
|
labels: {
|
||||||
|
foo: 'xxx',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
entry: 'foo 2',
|
||||||
|
labels: {
|
||||||
|
foo: 'bar',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
expect(calculateLogsLabelStats(rows as any, 'foo')).toMatchObject([
|
||||||
|
{
|
||||||
|
value: 'bar',
|
||||||
|
count: 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'xxx',
|
||||||
|
count: 1,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
@ -2,32 +2,9 @@ import _ from 'lodash';
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
|
|
||||||
import { LogsStreamLabels, LogRow } from 'app/core/logs_model';
|
import { calculateLogsLabelStats, LogsLabelStat, LogsStreamLabels, LogRow } from 'app/core/logs_model';
|
||||||
|
|
||||||
interface FieldStat {
|
function StatsRow({ active, count, proportion, value }: LogsLabelStat) {
|
||||||
active?: boolean;
|
|
||||||
value: string;
|
|
||||||
count: number;
|
|
||||||
proportion: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
function calculateStats(rows: LogRow[], label: string): FieldStat[] {
|
|
||||||
// Consider only rows that have the given label
|
|
||||||
const rowsWithLabel = rows.filter(row => row.labels[label] !== undefined);
|
|
||||||
const rowCount = rowsWithLabel.length;
|
|
||||||
|
|
||||||
// Get label value counts for eligible rows
|
|
||||||
const countsByValue = _.countBy(rowsWithLabel, row => (row as LogRow).labels[label]);
|
|
||||||
const sortedCounts = _.chain(countsByValue)
|
|
||||||
.map((count, value) => ({ count, value, proportion: count / rowCount }))
|
|
||||||
.sortBy('count')
|
|
||||||
.reverse()
|
|
||||||
.value();
|
|
||||||
|
|
||||||
return sortedCounts;
|
|
||||||
}
|
|
||||||
|
|
||||||
function StatsRow({ active, count, proportion, value }: FieldStat) {
|
|
||||||
const percent = `${Math.round(proportion * 100)}%`;
|
const percent = `${Math.round(proportion * 100)}%`;
|
||||||
const barStyle = { width: percent };
|
const barStyle = { width: percent };
|
||||||
const className = classnames('logs-stats-row', { 'logs-stats-row--active': active });
|
const className = classnames('logs-stats-row', { 'logs-stats-row--active': active });
|
||||||
@ -48,7 +25,7 @@ function StatsRow({ active, count, proportion, value }: FieldStat) {
|
|||||||
|
|
||||||
const STATS_ROW_LIMIT = 5;
|
const STATS_ROW_LIMIT = 5;
|
||||||
class Stats extends PureComponent<{
|
class Stats extends PureComponent<{
|
||||||
stats: FieldStat[];
|
stats: LogsLabelStat[];
|
||||||
label: string;
|
label: string;
|
||||||
value: string;
|
value: string;
|
||||||
rowCount: number;
|
rowCount: number;
|
||||||
@ -92,7 +69,7 @@ class Label extends PureComponent<
|
|||||||
value: string;
|
value: string;
|
||||||
onClickLabel?: (label: string, value: string) => void;
|
onClickLabel?: (label: string, value: string) => void;
|
||||||
},
|
},
|
||||||
{ showStats: boolean; stats: FieldStat[] }
|
{ showStats: boolean; stats: LogsLabelStat[] }
|
||||||
> {
|
> {
|
||||||
state = {
|
state = {
|
||||||
stats: null,
|
stats: null,
|
||||||
@ -115,7 +92,7 @@ class Label extends PureComponent<
|
|||||||
if (state.showStats) {
|
if (state.showStats) {
|
||||||
return { showStats: false, stats: null };
|
return { showStats: false, stats: null };
|
||||||
}
|
}
|
||||||
const stats = calculateStats(this.props.allRows, this.props.label);
|
const stats = calculateLogsLabelStats(this.props.allRows, this.props.label);
|
||||||
return { showStats: true, stats };
|
return { showStats: true, stats };
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user