Skip to content

Commit

Permalink
[7.x] [Logs UI] Add ML job results APIs (elastic#42356) (elastic#42932)
Browse files Browse the repository at this point in the history
Backports the following commits to 7.x:
 - [Logs UI] Add ML job results APIs (elastic#42356)
  • Loading branch information
weltenwort authored Aug 8, 2019
1 parent 78abaf6 commit b03c1e1
Show file tree
Hide file tree
Showing 40 changed files with 1,246 additions and 801 deletions.
4 changes: 1 addition & 3 deletions x-pack/legacy/plugins/infra/common/http_api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@
* you may not use this file except in compliance with the Elastic License.
*/

export * from './search_results_api';
export * from './search_summary_api';
export * from './log_analysis';
export * from './metadata_api';
export * from './timed_api';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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 * from './results';
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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 * from './log_entry_rate';
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* 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,
conflictErrorRT,
forbiddenErrorRT,
metricStatisticsRT,
timeRangeRT,
} from '../../shared';

export const LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH =
'/api/infra/log_analysis/results/log_entry_rate';

/**
* request
*/

export const getLogEntryRateRequestPayloadRT = rt.type({
data: rt.type({
bucketDuration: rt.number,
sourceId: rt.string,
timeRange: timeRangeRT,
}),
});

export type GetLogEntryRateRequestPayload = rt.TypeOf<typeof getLogEntryRateRequestPayloadRT>;

/**
* response
*/

export const logEntryRateAnomaly = rt.type({
actualLogEntryRate: rt.number,
anomalyScore: rt.number,
duration: rt.number,
startTime: rt.number,
typicalLogEntryRate: rt.number,
});

export const logEntryRateHistogramBucket = rt.type({
anomalies: rt.array(logEntryRateAnomaly),
duration: rt.number,
logEntryRateStats: metricStatisticsRT,
modelLowerBoundStats: metricStatisticsRT,
modelUpperBoundStats: metricStatisticsRT,
startTime: rt.number,
});

export const getLogEntryRateSuccessReponsePayloadRT = rt.type({
data: rt.type({
bucketDuration: rt.number,
histogramBuckets: rt.array(logEntryRateHistogramBucket),
}),
});

export type GetLogEntryRateSuccessResponsePayload = rt.TypeOf<
typeof getLogEntryRateSuccessReponsePayloadRT
>;

export const getLogEntryRateResponsePayloadRT = rt.union([
getLogEntryRateSuccessReponsePayloadRT,
badRequestErrorRT,
conflictErrorRT,
forbiddenErrorRT,
]);

export type GetLogEntryRateReponsePayload = rt.TypeOf<typeof getLogEntryRateResponsePayloadRT>;
37 changes: 0 additions & 37 deletions x-pack/legacy/plugins/infra/common/http_api/search_results_api.ts

This file was deleted.

26 changes: 0 additions & 26 deletions x-pack/legacy/plugins/infra/common/http_api/search_summary_api.ts

This file was deleted.

23 changes: 23 additions & 0 deletions x-pack/legacy/plugins/infra/common/http_api/shared/errors.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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';

const createErrorRuntimeType = <Attributes extends rt.Mixed = rt.UndefinedType>(
statusCode: number,
errorCode: string,
attributes?: Attributes
) =>
rt.type({
statusCode: rt.literal(statusCode),
error: rt.literal(errorCode),
message: rt.string,
...(!!attributes ? { attributes } : {}),
});

export const badRequestErrorRT = createErrorRuntimeType(400, 'Bad Request');
export const forbiddenErrorRT = createErrorRuntimeType(403, 'Forbidden');
export const conflictErrorRT = createErrorRuntimeType(409, 'Conflict');
9 changes: 9 additions & 0 deletions x-pack/legacy/plugins/infra/common/http_api/shared/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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 * from './errors';
export * from './metric_statistics';
export * from './time_range';
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 metricStatisticsRT = rt.type({
avg: rt.union([rt.number, rt.null]),
count: rt.number,
max: rt.union([rt.number, rt.null]),
min: rt.union([rt.number, rt.null]),
sum: rt.number,
});
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/

export interface ApiResponseTimings {
[timing: string]: number;
}
import * as rt from 'io-ts';

export interface TimedApiResponse {
timings: ApiResponseTimings;
}
export const timeRangeRT = rt.type({
startTime: rt.number,
endTime: rt.number,
});
8 changes: 8 additions & 0 deletions x-pack/legacy/plugins/infra/common/log_analysis/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* 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 * from './log_analysis';
export * from './job_parameters';
10 changes: 10 additions & 0 deletions x-pack/legacy/plugins/infra/common/log_analysis/job_parameters.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/*
* 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 { JobType } from './log_analysis';

export const getJobId = (spaceId: string, sourceId: string, jobType: JobType) =>
`kibana-logs-ui-${spaceId}-${sourceId}-${jobType}`;
21 changes: 21 additions & 0 deletions x-pack/legacy/plugins/infra/common/log_analysis/log_analysis.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* 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 jobTypeRT = rt.keyof({
'log-entry-rate': null,
});

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

export const jobStatusRT = rt.keyof({
created: null,
missing: null,
running: null,
});

export type JobStatus = rt.TypeOf<typeof jobStatusRT>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* 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 * from './log_analysis_results';
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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 createContainer from 'constate-latest/dist/ts/src';
import { useMemo } from 'react';

import { useLogEntryRate } from './log_entry_rate';

export const useLogAnalysisResults = ({ sourceId }: { sourceId: string }) => {
const { isLoading: isLoadingLogEntryRate, logEntryRate } = useLogEntryRate({ sourceId });

const isLoading = useMemo(() => isLoadingLogEntryRate, [isLoadingLogEntryRate]);

return {
isLoading,
logEntryRate,
};
};

export const LogAnalysisResults = createContainer(useLogAnalysisResults);
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* 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 { useMemo, useState } from 'react';
import { kfetch } from 'ui/kfetch';

import {
getLogEntryRateRequestPayloadRT,
getLogEntryRateSuccessReponsePayloadRT,
GetLogEntryRateSuccessResponsePayload,
LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH,
} from '../../../../common/http_api/log_analysis';
import { createPlainError, throwErrors } from '../../../../common/runtime_types';
import { useTrackedPromise } from '../../../utils/use_tracked_promise';

type LogEntryRateResults = GetLogEntryRateSuccessResponsePayload['data'];

export const useLogEntryRate = ({ sourceId }: { sourceId: string }) => {
const [logEntryRate, setLogEntryRate] = useState<LogEntryRateResults | null>(null);

const [getLogEntryRateRequest, getLogEntryRate] = useTrackedPromise(
{
cancelPreviousOn: 'resolution',
createPromise: async () => {
return await kfetch({
method: 'POST',
pathname: LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH,
body: JSON.stringify(
getLogEntryRateRequestPayloadRT.encode({
data: {
sourceId, // TODO: get from hook arguments
timeRange: {
startTime: Date.now(), // TODO: get from hook arguments
endTime: Date.now() + 1000 * 60 * 60, // TODO: get from hook arguments
},
bucketDuration: 15 * 60 * 1000, // TODO: get from hook arguments
},
})
),
});
},
onResolve: response => {
const { data } = getLogEntryRateSuccessReponsePayloadRT
.decode(response)
.getOrElseL(throwErrors(createPlainError));

setLogEntryRate(data);
},
},
[sourceId]
);

const isLoading = useMemo(() => getLogEntryRateRequest.state === 'pending', [
getLogEntryRateRequest.state,
]);

return {
getLogEntryRate,
isLoading,
logEntryRate,
};
};
4 changes: 2 additions & 2 deletions x-pack/legacy/plugins/infra/server/infra_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { createSnapshotResolvers } from './graphql/snapshot';
import { createSourceStatusResolvers } from './graphql/source_status';
import { createSourcesResolvers } from './graphql/sources';
import { InfraBackendLibs } from './lib/infra_types';
import { initLegacyLoggingRoutes } from './logging_legacy';
import { initLogAnalysisGetLogEntryRateRoute } from './routes/log_analysis';
import { initMetricExplorerRoute } from './routes/metrics_explorer';
import { initMetadataRoute } from './routes/metadata';

Expand All @@ -31,8 +31,8 @@ export const initInfraServer = (libs: InfraBackendLibs) => {

libs.framework.registerGraphQLEndpoint('/api/infra/graphql', schema);

initLegacyLoggingRoutes(libs.framework);
initIpToHostName(libs);
initLogAnalysisGetLogEntryRateRoute(libs);
initMetricExplorerRoute(libs);
initMetadataRoute(libs);
};
Loading

0 comments on commit b03c1e1

Please sign in to comment.