Skip to content

Commit

Permalink
[Logs UI] Add category anomalies to anomalies page (#70982) (#71490)
Browse files Browse the repository at this point in the history
* Add category anomalies to anomalies page

Co-authored-by: Felix Stürmer <weltenwort@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>

Co-authored-by: Felix Stürmer <weltenwort@users.noreply.github.com>
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
3 people authored Jul 13, 2020
1 parent 31c2595 commit 5b9c7ad
Show file tree
Hide file tree
Showing 34 changed files with 1,764 additions and 892 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ export * from './log_entry_categories';
export * from './log_entry_category_datasets';
export * from './log_entry_category_examples';
export * from './log_entry_rate';
export * from './log_entry_rate_examples';
export * from './log_entry_examples';
export * from './log_entry_anomalies';
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* 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 { timeRangeRT, routeTimingMetadataRT } from '../../shared';

export const LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH =
'/api/infra/log_analysis/results/log_entry_anomalies';

// [Sort field value, tiebreaker value]
const paginationCursorRT = rt.tuple([
rt.union([rt.string, rt.number]),
rt.union([rt.string, rt.number]),
]);

export type PaginationCursor = rt.TypeOf<typeof paginationCursorRT>;

export const anomalyTypeRT = rt.keyof({
logRate: null,
logCategory: null,
});

export type AnomalyType = rt.TypeOf<typeof anomalyTypeRT>;

const logEntryAnomalyCommonFieldsRT = rt.type({
id: rt.string,
anomalyScore: rt.number,
dataset: rt.string,
typical: rt.number,
actual: rt.number,
type: anomalyTypeRT,
duration: rt.number,
startTime: rt.number,
jobId: rt.string,
});
const logEntrylogRateAnomalyRT = logEntryAnomalyCommonFieldsRT;
const logEntrylogCategoryAnomalyRT = rt.partial({
categoryId: rt.string,
});
const logEntryAnomalyRT = rt.intersection([
logEntryAnomalyCommonFieldsRT,
logEntrylogRateAnomalyRT,
logEntrylogCategoryAnomalyRT,
]);

export type LogEntryAnomaly = rt.TypeOf<typeof logEntryAnomalyRT>;

export const getLogEntryAnomaliesSuccessReponsePayloadRT = rt.intersection([
rt.type({
data: rt.intersection([
rt.type({
anomalies: rt.array(logEntryAnomalyRT),
// Signifies there are more entries backwards or forwards. If this was a request
// for a previous page, there are more previous pages, if this was a request for a next page,
// there are more next pages.
hasMoreEntries: rt.boolean,
}),
rt.partial({
paginationCursors: rt.type({
// The cursor to use to fetch the previous page
previousPageCursor: paginationCursorRT,
// The cursor to use to fetch the next page
nextPageCursor: paginationCursorRT,
}),
}),
]),
}),
rt.partial({
timing: routeTimingMetadataRT,
}),
]);

export type GetLogEntryAnomaliesSuccessResponsePayload = rt.TypeOf<
typeof getLogEntryAnomaliesSuccessReponsePayloadRT
>;

const sortOptionsRT = rt.keyof({
anomalyScore: null,
dataset: null,
startTime: null,
});

const sortDirectionsRT = rt.keyof({
asc: null,
desc: null,
});

const paginationPreviousPageCursorRT = rt.type({
searchBefore: paginationCursorRT,
});

const paginationNextPageCursorRT = rt.type({
searchAfter: paginationCursorRT,
});

const paginationRT = rt.intersection([
rt.type({
pageSize: rt.number,
}),
rt.partial({
cursor: rt.union([paginationPreviousPageCursorRT, paginationNextPageCursorRT]),
}),
]);

export type Pagination = rt.TypeOf<typeof paginationRT>;

const sortRT = rt.type({
field: sortOptionsRT,
direction: sortDirectionsRT,
});

export type Sort = rt.TypeOf<typeof sortRT>;

export const getLogEntryAnomaliesRequestPayloadRT = rt.type({
data: rt.intersection([
rt.type({
// the ID of the source configuration
sourceId: rt.string,
// the time range to fetch the log entry anomalies from
timeRange: timeRangeRT,
}),
rt.partial({
// Pagination properties
pagination: paginationRT,
// Sort properties
sort: sortRT,
}),
]),
});

export type GetLogEntryAnomaliesRequestPayload = rt.TypeOf<
typeof getLogEntryAnomaliesRequestPayloadRT
>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* 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_RATE_EXAMPLES_PATH =
'/api/infra/log_analysis/results/log_entry_examples';

/**
* request
*/

export const getLogEntryExamplesRequestPayloadRT = rt.type({
data: rt.intersection([
rt.type({
// the dataset to fetch the log rate examples from
dataset: rt.string,
// the number of examples to fetch
exampleCount: rt.number,
// the id of the source configuration
sourceId: rt.string,
// the time range to fetch the log rate examples from
timeRange: timeRangeRT,
}),
rt.partial({
categoryId: rt.string,
}),
]),
});

export type GetLogEntryExamplesRequestPayload = rt.TypeOf<
typeof getLogEntryExamplesRequestPayloadRT
>;

/**
* response
*/

const logEntryExampleRT = rt.type({
id: rt.string,
dataset: rt.string,
message: rt.string,
timestamp: rt.number,
tiebreaker: rt.number,
});

export type LogEntryExample = rt.TypeOf<typeof logEntryExampleRT>;

export const getLogEntryExamplesSuccessReponsePayloadRT = rt.intersection([
rt.type({
data: rt.type({
examples: rt.array(logEntryExampleRT),
}),
}),
rt.partial({
timing: routeTimingMetadataRT,
}),
]);

export type GetLogEntryExamplesSuccessReponsePayload = rt.TypeOf<
typeof getLogEntryExamplesSuccessReponsePayloadRT
>;

export const getLogEntryExamplesResponsePayloadRT = rt.union([
getLogEntryExamplesSuccessReponsePayloadRT,
badRequestErrorRT,
forbiddenErrorRT,
]);

export type GetLogEntryExamplesResponsePayload = rt.TypeOf<
typeof getLogEntryExamplesResponsePayloadRT
>;

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ export const formatAnomalyScore = (score: number) => {
return Math.round(score);
};

export const formatOneDecimalPlace = (number: number) => {
return Math.round(number * 10) / 10;
};

export const getFriendlyNameForPartitionId = (partitionId: string) => {
return partitionId !== '' ? partitionId : 'unknown';
};
Expand Down
Loading

0 comments on commit 5b9c7ad

Please sign in to comment.