Tests for label stats calculation

This commit is contained in:
David Kaltschmidt 2018-12-03 17:00:50 +01:00
parent 5916cb3e7c
commit 9f0b1e533f
3 changed files with 82 additions and 29 deletions

View File

@ -45,6 +45,13 @@ export interface LogRow {
uniqueLabels?: LogsStreamLabels;
}
export interface LogsLabelStat {
active?: boolean;
count: number;
proportion: number;
value: string;
}
export enum LogsMetaKind {
Number,
String,
@ -88,6 +95,22 @@ export enum LogsDedupStrategy {
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;
function isDuplicateRow(row: LogRow, other: LogRow, strategy: LogsDedupStrategy): boolean {
switch (strategy) {

View File

@ -1,4 +1,4 @@
import { dedupLogRows, LogsDedupStrategy, LogsModel } from '../logs_model';
import { calculateLogsLabelStats, dedupLogRows, LogsDedupStrategy, LogsModel } from '../logs_model';
describe('dedupLogRows()', () => {
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,
},
]);
});
});

View File

@ -2,32 +2,9 @@ import _ from 'lodash';
import React, { PureComponent } from 'react';
import classnames from 'classnames';
import { LogsStreamLabels, LogRow } from 'app/core/logs_model';
import { calculateLogsLabelStats, LogsLabelStat, LogsStreamLabels, LogRow } from 'app/core/logs_model';
interface FieldStat {
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) {
function StatsRow({ active, count, proportion, value }: LogsLabelStat) {
const percent = `${Math.round(proportion * 100)}%`;
const barStyle = { width: percent };
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;
class Stats extends PureComponent<{
stats: FieldStat[];
stats: LogsLabelStat[];
label: string;
value: string;
rowCount: number;
@ -92,7 +69,7 @@ class Label extends PureComponent<
value: string;
onClickLabel?: (label: string, value: string) => void;
},
{ showStats: boolean; stats: FieldStat[] }
{ showStats: boolean; stats: LogsLabelStat[] }
> {
state = {
stats: null,
@ -115,7 +92,7 @@ class Label extends PureComponent<
if (state.showStats) {
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 };
});
};