Skip to content

Commit

Permalink
Add dataset filtering to the anomalies page
Browse files Browse the repository at this point in the history
Make dataset fetching a common functionality

Add anomaies datasets route

Hook up datasets with client side hook and UI

Hook up dataset filtering to anomalies API endpoint

Hook up dataset filtering with log entry rate endpoint
  • Loading branch information
Kerry350 committed Jul 9, 2020
1 parent f585973 commit 216cc9e
Show file tree
Hide file tree
Showing 26 changed files with 512 additions and 123 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './log_entry_category_examples';
export * from './log_entry_rate';
export * from './log_entry_examples';
export * from './log_entry_anomalies';
export * from './log_entry_anomalies_datasets';
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ export const getLogEntryAnomaliesRequestPayloadRT = rt.type({
pagination: paginationRT,
// Sort properties
sort: sortRT,
// Dataset filters
datasets: rt.array(rt.string),
}),
]),
});
Expand Down
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_ANOMALIES_DATASETS_PATH =
'/api/infra/log_analysis/results/log_entry_anomalies_datasets';

/**
* request
*/

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

export type GetLogEntryAnomaliesDatasetsRequestPayload = rt.TypeOf<
typeof getLogEntryAnomaliesDatasetsRequestPayloadRT
>;

/**
* response
*/

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

export type GetLogEntryAnomaliesDatasetsSuccessResponsePayload = rt.TypeOf<
typeof getLogEntryAnomaliesDatasetsSuccessReponsePayloadRT
>;

export const getLogEntryAnomaliesDatasetsResponsePayloadRT = rt.union([
getLogEntryAnomaliesDatasetsSuccessReponsePayloadRT,
badRequestErrorRT,
forbiddenErrorRT,
]);

export type GetLogEntryAnomaliesDatasetsReponsePayload = rt.TypeOf<
typeof getLogEntryAnomaliesDatasetsResponsePayloadRT
>;
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,16 @@ export const LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH =
*/

export const getLogEntryRateRequestPayloadRT = rt.type({
data: rt.type({
bucketDuration: rt.number,
sourceId: rt.string,
timeRange: timeRangeRT,
}),
data: rt.intersection([
rt.type({
bucketDuration: rt.number,
sourceId: rt.string,
timeRange: timeRangeRT,
}),
rt.partial({
datasets: rt.array(rt.string),
}),
]),
});

export type GetLogEntryRateRequestPayload = rt.TypeOf<typeof getLogEntryRateRequestPayloadRT>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React, { useCallback, useMemo } from 'react';

import { getFriendlyNameForPartitionId } from '../../../../../../common/log_analysis';
import { getFriendlyNameForPartitionId } from '../../../../common/log_analysis';

type DatasetOptionProps = EuiComboBoxOptionOption<string>;

Expand Down Expand Up @@ -51,7 +51,7 @@ export const DatasetsSelector: React.FunctionComponent<{
};

const datasetFilterPlaceholder = i18n.translate(
'xpack.infra.logs.logEntryCategories.datasetFilterPlaceholder',
'xpack.infra.logs.analysis.datasetFilterPlaceholder',
{
defaultMessage: 'Filter by datasets',
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { BetaBadge } from '../../../../../components/beta_badge';
import { LoadingOverlayWrapper } from '../../../../../components/loading_overlay_wrapper';
import { RecreateJobButton } from '../../../../../components/logging/log_analysis_job_status';
import { AnalyzeInMlButton } from '../../../../../components/logging/log_analysis_results';
import { DatasetsSelector } from './datasets_selector';
import { DatasetsSelector } from '../../../../../components/logging/log_analysis_results/datasets_selector';
import { TopCategoriesTable } from './top_categories_table';

export const TopCategoriesSection: React.FunctionComponent<{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
StringTimeRange,
useLogAnalysisResultsUrlState,
} from './use_log_entry_rate_results_url_state';
import { DatasetsSelector } from '../../../components/logging/log_analysis_results/datasets_selector';

const JOB_STATUS_POLLING_INTERVAL = 30000;

Expand Down Expand Up @@ -76,15 +77,17 @@ export const LogEntryRateResultsContent: React.FunctionComponent<LogEntryRateRes
[queryTimeRange.value.endTime, queryTimeRange.value.startTime]
);

const [selectedDatasets, setSelectedDatasets] = useState<string[]>([]);

const { getLogEntryRate, isLoading, logEntryRate } = useLogEntryRateResults({
sourceId,
startTime: queryTimeRange.value.startTime,
endTime: queryTimeRange.value.endTime,
bucketDuration,
filteredDatasets: selectedDatasets,
});

const {
getLogEntryAnomalies,
isLoadingLogEntryAnomalies,
logEntryAnomalies,
page,
Expand All @@ -94,13 +97,16 @@ export const LogEntryRateResultsContent: React.FunctionComponent<LogEntryRateRes
changePaginationOptions,
sortOptions,
paginationOptions,
datasets,
isLoadingDatasets,
} = useLogEntryAnomaliesResults({
sourceId,
startTime: queryTimeRange.value.startTime,
endTime: queryTimeRange.value.endTime,
lastChangedTime: queryTimeRange.lastChangedTime,
defaultSortOptions: SORT_DEFAULTS,
defaultPaginationOptions: PAGINATION_DEFAULTS,
filteredDatasets: selectedDatasets,
});

const handleQueryTimeRangeChange = useCallback(
Expand Down Expand Up @@ -173,7 +179,7 @@ export const LogEntryRateResultsContent: React.FunctionComponent<LogEntryRateRes

useEffect(() => {
getLogEntryRate();
}, [getLogEntryRate, getLogEntryAnomalies, queryTimeRange.lastChangedTime]);
}, [getLogEntryRate, selectedDatasets, queryTimeRange.lastChangedTime]);

useEffect(() => {
fetchModuleDefinition();
Expand All @@ -197,7 +203,15 @@ export const LogEntryRateResultsContent: React.FunctionComponent<LogEntryRateRes
<ResultsContentPage>
<EuiFlexGroup direction="column">
<EuiFlexItem grow={false}>
<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexGroup justifyContent="spaceBetween">
<EuiFlexItem>
<DatasetsSelector
availableDatasets={datasets}
isLoading={isLoadingDatasets}
selectedDatasets={selectedDatasets}
onChangeDatasetSelection={setSelectedDatasets}
/>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiSuperDatePicker
start={selectedTimeRange.startTime}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ export const callGetLogEntryAnomaliesAPI = async (
startTime: number,
endTime: number,
sort: Sort,
pagination: Pagination
pagination: Pagination,
datasets?: string[]
) => {
const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_PATH, {
method: 'POST',
Expand All @@ -32,6 +33,7 @@ export const callGetLogEntryAnomaliesAPI = async (
},
sort,
pagination,
datasets,
},
})
),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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 { fold } from 'fp-ts/lib/Either';
import { pipe } from 'fp-ts/lib/pipeable';
import { identity } from 'fp-ts/lib/function';
import { npStart } from '../../../../legacy_singletons';

import {
getLogEntryAnomaliesDatasetsRequestPayloadRT,
getLogEntryAnomaliesDatasetsSuccessReponsePayloadRT,
LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH,
} from '../../../../../common/http_api/log_analysis';
import { createPlainError, throwErrors } from '../../../../../common/runtime_types';

export const callGetLogEntryAnomaliesDatasetsAPI = async (
sourceId: string,
startTime: number,
endTime: number
) => {
const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_ANOMALIES_DATASETS_PATH, {
method: 'POST',
body: JSON.stringify(
getLogEntryAnomaliesDatasetsRequestPayloadRT.encode({
data: {
sourceId,
timeRange: {
startTime,
endTime,
},
},
})
),
});

return pipe(
getLogEntryAnomaliesDatasetsSuccessReponsePayloadRT.decode(response),
fold(throwErrors(createPlainError), identity)
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export const callGetLogEntryRateAPI = async (
sourceId: string,
startTime: number,
endTime: number,
bucketDuration: number
bucketDuration: number,
datasets?: string[]
) => {
const response = await npStart.http.fetch(LOG_ANALYSIS_GET_LOG_ENTRY_RATE_PATH, {
method: 'POST',
Expand All @@ -32,6 +33,7 @@ export const callGetLogEntryRateAPI = async (
endTime,
},
bucketDuration,
datasets,
},
})
),
Expand Down
Loading

0 comments on commit 216cc9e

Please sign in to comment.