Skip to content

Commit

Permalink
[Logs UI] Add categories table to the categorization tab (elastic#53004)
Browse files Browse the repository at this point in the history
This renders the log entry categories after the ML jobs have been set up previously.

closes elastic#42776
closes elastic#42065
  • Loading branch information
weltenwort authored and jkelastic committed Jan 17, 2020
1 parent c30059c commit 2ef4b35
Show file tree
Hide file tree
Showing 68 changed files with 2,581 additions and 160 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/

export * from './log_entry_categories';
export * from './log_entry_category_datasets';
export * from './log_entry_rate';
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import * as rt from 'io-ts';

import {
badRequestErrorRT,
forbiddenErrorRT,
timeRangeRT,
routeTimingMetadataRT,
} from '../../shared';

export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORIES_PATH =
'/api/infra/log_analysis/results/log_entry_categories';

/**
* request
*/

const logEntryCategoriesHistogramParametersRT = rt.type({
id: rt.string,
timeRange: timeRangeRT,
bucketCount: rt.number,
});

export type LogEntryCategoriesHistogramParameters = rt.TypeOf<
typeof logEntryCategoriesHistogramParametersRT
>;

export const getLogEntryCategoriesRequestPayloadRT = rt.type({
data: rt.intersection([
rt.type({
// the number of categories to fetch
categoryCount: rt.number,
// the id of the source configuration
sourceId: rt.string,
// the time range to fetch the categories from
timeRange: timeRangeRT,
// a list of histograms to create
histograms: rt.array(logEntryCategoriesHistogramParametersRT),
}),
rt.partial({
// the datasets to filter for (optional, unfiltered if not present)
datasets: rt.array(rt.string),
}),
]),
});

export type GetLogEntryCategoriesRequestPayload = rt.TypeOf<
typeof getLogEntryCategoriesRequestPayloadRT
>;

/**
* response
*/

export const logEntryCategoryHistogramBucketRT = rt.type({
startTime: rt.number,
bucketDuration: rt.number,
logEntryCount: rt.number,
});

export type LogEntryCategoryHistogramBucket = rt.TypeOf<typeof logEntryCategoryHistogramBucketRT>;

export const logEntryCategoryHistogramRT = rt.type({
histogramId: rt.string,
buckets: rt.array(logEntryCategoryHistogramBucketRT),
});

export type LogEntryCategoryHistogram = rt.TypeOf<typeof logEntryCategoryHistogramRT>;

export const logEntryCategoryRT = rt.type({
categoryId: rt.number,
datasets: rt.array(rt.string),
histograms: rt.array(logEntryCategoryHistogramRT),
logEntryCount: rt.number,
maximumAnomalyScore: rt.number,
regularExpression: rt.string,
});

export type LogEntryCategory = rt.TypeOf<typeof logEntryCategoryRT>;

export const getLogEntryCategoriesSuccessReponsePayloadRT = rt.intersection([
rt.type({
data: rt.type({
categories: rt.array(logEntryCategoryRT),
}),
}),
rt.partial({
timing: routeTimingMetadataRT,
}),
]);

export type GetLogEntryCategoriesSuccessResponsePayload = rt.TypeOf<
typeof getLogEntryCategoriesSuccessReponsePayloadRT
>;

export const getLogEntryCategoriesResponsePayloadRT = rt.union([
getLogEntryCategoriesSuccessReponsePayloadRT,
badRequestErrorRT,
forbiddenErrorRT,
]);

export type GetLogEntryCategoriesReponsePayload = rt.TypeOf<
typeof getLogEntryCategoriesResponsePayloadRT
>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import * as rt from 'io-ts';

import {
badRequestErrorRT,
forbiddenErrorRT,
timeRangeRT,
routeTimingMetadataRT,
} from '../../shared';

export const LOG_ANALYSIS_GET_LOG_ENTRY_CATEGORY_DATASETS_PATH =
'/api/infra/log_analysis/results/log_entry_category_datasets';

/**
* request
*/

export const getLogEntryCategoryDatasetsRequestPayloadRT = rt.type({
data: rt.type({
// the id of the source configuration
sourceId: rt.string,
// the time range to fetch the category datasets from
timeRange: timeRangeRT,
}),
});

export type GetLogEntryCategoryDatasetsRequestPayload = rt.TypeOf<
typeof getLogEntryCategoryDatasetsRequestPayloadRT
>;

/**
* response
*/

export const getLogEntryCategoryDatasetsSuccessReponsePayloadRT = rt.intersection([
rt.type({
data: rt.type({
datasets: rt.array(rt.string),
}),
}),
rt.partial({
timing: routeTimingMetadataRT,
}),
]);

export type GetLogEntryCategoryDatasetsSuccessResponsePayload = rt.TypeOf<
typeof getLogEntryCategoryDatasetsSuccessReponsePayloadRT
>;

export const getLogEntryCategoryDatasetsResponsePayloadRT = rt.union([
getLogEntryCategoryDatasetsSuccessReponsePayloadRT,
badRequestErrorRT,
forbiddenErrorRT,
]);

export type GetLogEntryCategoryDatasetsReponsePayload = rt.TypeOf<
typeof getLogEntryCategoryDatasetsResponsePayloadRT
>;
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@
export * from './errors';
export * from './metric_statistics';
export * from './time_range';
export * from './timing';
13 changes: 13 additions & 0 deletions x-pack/legacy/plugins/infra/common/http_api/shared/timing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import * as rt from 'io-ts';

import { tracingSpanRT } from '../../performance_tracing';

export const routeTimingMetadataRT = rt.type({
spans: rt.array(tracingSpanRT),
});
3 changes: 3 additions & 0 deletions x-pack/legacy/plugins/infra/common/log_analysis/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@
*/

export * from './log_analysis';
export * from './log_analysis_results';
export * from './log_entry_rate_analysis';
export * from './log_entry_categories_analysis';
export * from './job_parameters';
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,6 @@
* you may not use this file except in compliance with the Elastic License.
*/

import * as rt from 'io-ts';

export const jobTypeRT = rt.keyof({
'log-entry-rate': null,
});

export type JobType = rt.TypeOf<typeof jobTypeRT>;

// combines and abstracts job and datafeed status
export type JobStatus =
| 'unknown'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

export const ML_SEVERITY_SCORES = {
warning: 3,
minor: 25,
major: 50,
critical: 75,
};

export type MLSeverityScoreCategories = keyof typeof ML_SEVERITY_SCORES;

export const ML_SEVERITY_COLORS = {
critical: 'rgb(228, 72, 72)',
major: 'rgb(229, 113, 0)',
minor: 'rgb(255, 221, 0)',
warning: 'rgb(125, 180, 226)',
};

export const getSeverityCategoryForScore = (
score: number
): MLSeverityScoreCategories | undefined => {
if (score >= ML_SEVERITY_SCORES.critical) {
return 'critical';
} else if (score >= ML_SEVERITY_SCORES.major) {
return 'major';
} else if (score >= ML_SEVERITY_SCORES.minor) {
return 'minor';
} else if (score >= ML_SEVERITY_SCORES.warning) {
return 'warning';
} else {
// Category is too low to include
return undefined;
}
};

export const formatAnomalyScore = (score: number) => {
return Math.round(score);
};

export const getFriendlyNameForPartitionId = (partitionId: string) => {
return partitionId !== '' ? partitionId : 'unknown';
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import * as rt from 'io-ts';

export const logEntryCategoriesJobTypeRT = rt.keyof({
'log-entry-categories-count': null,
});

export type LogEntryCategoriesJobType = rt.TypeOf<typeof logEntryCategoriesJobTypeRT>;

export const logEntryCategoriesJobTypes: LogEntryCategoriesJobType[] = [
'log-entry-categories-count',
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import * as rt from 'io-ts';

export const logEntryRateJobTypeRT = rt.keyof({
'log-entry-rate': null,
});

export type LogEntryRateJobType = rt.TypeOf<typeof logEntryRateJobTypeRT>;

export const logEntryRateJobTypes: LogEntryRateJobType[] = ['log-entry-rate'];
33 changes: 33 additions & 0 deletions x-pack/legacy/plugins/infra/common/performance_tracing.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import * as rt from 'io-ts';
import uuid from 'uuid';

export const tracingSpanRT = rt.type({
duration: rt.number,
id: rt.string,
name: rt.string,
start: rt.number,
});

export type TracingSpan = rt.TypeOf<typeof tracingSpanRT>;

export type ActiveTrace = (endTime?: number) => TracingSpan;

export const startTracingSpan = (name: string): ActiveTrace => {
const initialState: TracingSpan = {
duration: Number.POSITIVE_INFINITY,
id: uuid.v4(),
name,
start: Date.now(),
};

return (endTime: number = Date.now()) => ({
...initialState,
duration: endTime - initialState.start,
});
};
15 changes: 13 additions & 2 deletions x-pack/legacy/plugins/infra/common/runtime_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,22 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { Errors } from 'io-ts';
import { fold } from 'fp-ts/lib/Either';
import { identity } from 'fp-ts/lib/function';
import { pipe } from 'fp-ts/lib/pipeable';
import { Errors, Type } from 'io-ts';
import { failure } from 'io-ts/lib/PathReporter';

type ErrorFactory = (message: string) => Error;

export const createPlainError = (message: string) => new Error(message);

export const throwErrors = (createError: (message: string) => Error) => (errors: Errors) => {
export const throwErrors = (createError: ErrorFactory) => (errors: Errors) => {
throw createError(failure(errors).join('\n'));
};

export const decodeOrThrow = <A, O, I>(
runtimeType: Type<A, O, I>,
createError: ErrorFactory = createPlainError
) => (inputValue: I) =>
pipe(runtimeType.decode(inputValue), fold(throwErrors(createError), identity));
1 change: 1 addition & 0 deletions x-pack/legacy/plugins/infra/public/apps/start_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
KibanaContextProvider,
} from '../../../../../../src/plugins/kibana_react/public';
import { ROOT_ELEMENT_ID } from '../app';

// NP_TODO: Type plugins
export async function startApp(libs: InfraFrontendLibs, core: CoreStart, plugins: any) {
const history = createHashHistory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
*/

export * from './log_analysis_job_problem_indicator';
export * from './recreate_job_button';
Loading

0 comments on commit 2ef4b35

Please sign in to comment.