Skip to content

Commit

Permalink
[Logs UI] Add "Analyze in ML" buttons (#48268)
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerry350 committed Oct 16, 2019
1 parent 9f11d0d commit 3162194
Show file tree
Hide file tree
Showing 7 changed files with 135 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import createContainer from 'constate-latest';
import { useMemo, useCallback, useEffect } from 'react';

import { callGetMlModuleAPI } from './api/ml_get_module';
import { bucketSpan } from '../../../../common/log_analysis';
import { bucketSpan, getJobId } from '../../../../common/log_analysis';
import { useTrackedPromise } from '../../../utils/use_tracked_promise';
import { callJobsSummaryAPI } from './api/ml_get_jobs_summary_api';
import { callSetupMlModuleAPI, SetupMlModuleResponsePayload } from './api/ml_setup_module_api';
Expand Down Expand Up @@ -138,6 +138,12 @@ export const useLogAnalysisJobs = ({
fetchModuleDefinition();
}, [fetchModuleDefinition]);

const jobIds = useMemo(() => {
return {
'log-entry-rate': getJobId(spaceId, sourceId, 'log-entry-rate'),
};
}, [sourceId, spaceId]);

return {
fetchJobStatus,
isLoadingSetupStatus,
Expand All @@ -149,6 +155,7 @@ export const useLogAnalysisJobs = ({
viewSetupForReconfiguration,
viewSetupForUpdate,
viewResults,
jobIds,
};
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ import numeral from '@elastic/numeral';
import { FormattedMessage } from '@kbn/i18n/react';
import moment from 'moment';
import React, { useCallback, useContext, useMemo, useState } from 'react';
import euiStyled from '../../../../../../common/eui_styled_components';
import { TimeRange } from '../../../../common/http_api/shared/time_range';
import { bucketSpan } from '../../../../common/log_analysis';
import euiStyled from '../../../../../../common/eui_styled_components';
import { LoadingPage } from '../../../components/loading_page';
import {
LogAnalysisJobs,
Expand Down Expand Up @@ -134,6 +134,7 @@ export const AnalysisResultsContent = ({
setupStatus,
viewSetupForReconfiguration,
viewSetupForUpdate,
jobIds,
} = useContext(LogAnalysisJobs.Context);

useInterval(() => {
Expand Down Expand Up @@ -214,6 +215,7 @@ export const AnalysisResultsContent = ({
setTimeRange={handleChartTimeRangeChange}
setupStatus={setupStatus}
timeRange={queryTimeRange}
jobId={jobIds['log-entry-rate']}
/>
</EuiPanel>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/*
* 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 React from 'react';
import url from 'url';
import { EuiButton } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import chrome from 'ui/chrome';
import { QueryString } from 'ui/utils/query_string';
import { encode } from 'rison-node';
import { TimeRange } from '../../../../../common/http_api/shared/time_range';

export const AnalyzeInMlButton: React.FunctionComponent<{
jobId: string;
partition?: string;
timeRange: TimeRange;
}> = ({ jobId, partition, timeRange }) => {
const pathname = chrome.addBasePath('/app/ml');
const buttonLabel = (
<FormattedMessage
id="xpack.infra.logs.analysis.analyzeInMlButtonLabel"
defaultMessage="Analyze in ML"
/>
);
return partition ? (
<EuiButton
fill={false}
href={getPartitionSpecificSingleMetricViewerLink(pathname, jobId, partition, timeRange)}
>
{buttonLabel}
</EuiButton>
) : (
<EuiButton fill={true} href={getOverallAnomalyExplorerLink(pathname, jobId, timeRange)}>
{buttonLabel}
</EuiButton>
);
};

const getOverallAnomalyExplorerLink = (pathname: string, jobId: string, timeRange: TimeRange) => {
const { from, to } = convertTimeRangeToParams(timeRange);

const _g = encode({
ml: {
jobIds: [jobId],
},
time: {
from,
to,
},
});

const hash = `/explorer?${QueryString.encode({ _g })}`;

return url.format({
pathname,
hash,
});
};

const getPartitionSpecificSingleMetricViewerLink = (
pathname: string,
jobId: string,
partition: string,
timeRange: TimeRange
) => {
const { from, to } = convertTimeRangeToParams(timeRange);

const _g = encode({
ml: {
jobIds: [jobId],
},
time: {
from,
to,
mode: 'absolute',
},
});

const _a = encode({
mlTimeSeriesExplorer: {
entities: { 'event.dataset': partition },
},
});

const hash = `/timeseriesexplorer?${QueryString.encode({ _g, _a })}`;

return url.format({
pathname,
hash,
});
};

const convertTimeRangeToParams = (timeRange: TimeRange): { from: string; to: string } => {
return {
from: new Date(timeRange.startTime).toISOString(),
to: new Date(timeRange.endTime).toISOString(),
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import React, { useMemo } from 'react';
import { i18n } from '@kbn/i18n';
import numeral from '@elastic/numeral';
import { EuiFlexGroup, EuiFlexItem, EuiStat } from '@elastic/eui';
import { EuiFlexGroup, EuiFlexItem, EuiStat, EuiSpacer } from '@elastic/eui';
import { AnomaliesChart } from './chart';
import { GetLogEntryRateSuccessResponsePayload } from '../../../../../../common/http_api/log_analysis/results/log_entry_rate';
import { TimeRange } from '../../../../../../common/http_api/shared/time_range';
Expand All @@ -17,14 +17,16 @@ import {
formatAnomalyScore,
getTotalNumberOfLogEntriesForPartition,
} from '../helpers/data_formatters';
import { AnalyzeInMlButton } from '../analyze_in_ml_button';

export const AnomaliesTableExpandedRow: React.FunctionComponent<{
partitionId: string;
topAnomalyScore: number;
results: GetLogEntryRateSuccessResponsePayload['data'];
setTimeRange: (timeRange: TimeRange) => void;
timeRange: TimeRange;
}> = ({ results, timeRange, setTimeRange, topAnomalyScore, partitionId }) => {
jobId: string;
}> = ({ results, timeRange, setTimeRange, topAnomalyScore, partitionId, jobId }) => {
const logEntryRateSeries = useMemo(
() =>
results && results.histogramBuckets
Expand Down Expand Up @@ -83,6 +85,12 @@ export const AnomaliesTableExpandedRow: React.FunctionComponent<{
)}
reverse
/>
<EuiSpacer size="s" />
<EuiFlexGroup>
<EuiFlexItem grow={false}>
<AnalyzeInMlButton jobId={jobId} timeRange={timeRange} partition={partitionId} />
</EuiFlexItem>
</EuiFlexGroup>
</EuiFlexItem>
</EuiFlexGroup>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
*/

import {
EuiButton,
EuiEmptyPrompt,
EuiFlexGroup,
EuiFlexItem,
Expand All @@ -16,7 +15,6 @@ import {
} from '@elastic/eui';
import numeral from '@elastic/numeral';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import React, { useMemo } from 'react';

import euiStyled from '../../../../../../../../common/eui_styled_components';
Expand All @@ -32,6 +30,7 @@ import {
import { AnomaliesChart } from './chart';
import { AnomaliesTable } from './table';
import { LogAnalysisJobProblemIndicator } from '../../../../../components/logging/log_analysis_job_status';
import { AnalyzeInMlButton } from '../analyze_in_ml_button';

export const AnomaliesResults: React.FunctionComponent<{
isLoading: boolean;
Expand All @@ -42,6 +41,7 @@ export const AnomaliesResults: React.FunctionComponent<{
timeRange: TimeRange;
viewSetupForReconfiguration: () => void;
viewSetupForUpdate: () => void;
jobId: string;
}> = ({
isLoading,
jobStatus,
Expand All @@ -51,6 +51,7 @@ export const AnomaliesResults: React.FunctionComponent<{
timeRange,
viewSetupForReconfiguration,
viewSetupForUpdate,
jobId,
}) => {
const title = i18n.translate('xpack.infra.logs.analysis.anomaliesSectionTitle', {
defaultMessage: 'Anomalies',
Expand Down Expand Up @@ -105,12 +106,7 @@ export const AnomaliesResults: React.FunctionComponent<{
</EuiTitle>
</EuiFlexItem>
<EuiFlexItem grow={false}>
<EuiButton fill>
<FormattedMessage
id="xpack.infra.logs.analysis.analyzeInMlButtonLabel"
defaultMessage="Analyze in ML"
/>
</EuiButton>
<AnalyzeInMlButton jobId={jobId} timeRange={timeRange} />
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="m" />
Expand Down Expand Up @@ -193,7 +189,12 @@ export const AnomaliesResults: React.FunctionComponent<{
</EuiFlexItem>
</EuiFlexGroup>
<EuiSpacer size="l" />
<AnomaliesTable results={results} setTimeRange={setTimeRange} timeRange={timeRange} />
<AnomaliesTable
results={results}
setTimeRange={setTimeRange}
timeRange={timeRange}
jobId={jobId}
/>
</>
)}
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ export const AnomaliesTable: React.FunctionComponent<{
results: GetLogEntryRateSuccessResponsePayload['data'];
setTimeRange: (timeRange: TimeRange) => void;
timeRange: TimeRange;
}> = ({ results, timeRange, setTimeRange }) => {
jobId: string;
}> = ({ results, timeRange, setTimeRange, jobId }) => {
const tableItems: TableItem[] = useMemo(() => {
return Object.entries(getTopAnomalyScoresByPartition(results)).map(([key, value]) => {
return {
Expand Down Expand Up @@ -112,6 +113,7 @@ export const AnomaliesTable: React.FunctionComponent<{
topAnomalyScore={item.topAnomalyScore}
setTimeRange={setTimeRange}
timeRange={timeRange}
jobId={jobId}
/>
),
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,5 @@ import { npSetup } from 'ui/new_platform';
*/
export const useKibanaInjectedVar = (name: string, defaultValue?: unknown) => {
const injectedMetadata = npSetup.core.injectedMetadata;

return injectedMetadata.getInjectedVar(name, defaultValue);
};

0 comments on commit 3162194

Please sign in to comment.