Skip to content

Commit

Permalink
[7.x] [Logs UI] Show log analysis ML jobs in a list (#71132) (#71551)
Browse files Browse the repository at this point in the history
Backports the following commits to 7.x:
 - [Logs UI] Show log analysis ML jobs in a list (#71132)
  • Loading branch information
weltenwort authored Jul 14, 2020
1 parent b4a5162 commit 8e7c699
Show file tree
Hide file tree
Showing 42 changed files with 714 additions and 358 deletions.
10 changes: 1 addition & 9 deletions x-pack/plugins/infra/common/log_analysis/log_analysis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,10 @@ export type JobStatus =
| 'finished'
| 'failed';

export type SetupStatusRequiredReason =
| 'missing' // jobs are missing
| 'reconfiguration' // the configurations don't match the source configurations
| 'update'; // the definitions don't match the module definitions

export type SetupStatus =
| { type: 'initializing' } // acquiring job statuses to determine setup status
| { type: 'unknown' } // job status could not be acquired (failed request etc)
| {
type: 'required';
reason: SetupStatusRequiredReason;
} // setup required
| { type: 'required' } // setup required
| { type: 'pending' } // In the process of setting up the module for the first time or retrying, waiting for response
| { type: 'succeeded' } // setup succeeded, notifying user
| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
*/

export * from './log_analysis_job_problem_indicator';
export * from './notices_section';
export * from './recreate_job_button';
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@ import React from 'react';
import { RecreateJobCallout } from './recreate_job_callout';

export const JobConfigurationOutdatedCallout: React.FC<{
moduleName: string;
onRecreateMlJob: () => void;
}> = ({ onRecreateMlJob }) => (
<RecreateJobCallout title={jobConfigurationOutdatedTitle} onRecreateMlJob={onRecreateMlJob}>
}> = ({ moduleName, onRecreateMlJob }) => (
<RecreateJobCallout
title={i18n.translate('xpack.infra.logs.analysis.jobConfigurationOutdatedCalloutTitle', {
defaultMessage: 'The {moduleName} ML job configuration is outdated',
values: {
moduleName,
},
})}
onRecreateMlJob={onRecreateMlJob}
>
<FormattedMessage
id="xpack.infra.logs.analysis.jobConfigurationOutdatedCalloutMessage"
defaultMessage="The ML job was created using a different source configuration. Recreate the job to apply the current configuration. This removes previously detected anomalies."
defaultMessage="The {moduleName} ML job was created using a different source configuration. Recreate the job to apply the current configuration. This removes previously detected anomalies."
values={{
moduleName,
}}
/>
</RecreateJobCallout>
);

const jobConfigurationOutdatedTitle = i18n.translate(
'xpack.infra.logs.analysis.jobConfigurationOutdatedCalloutTitle',
{
defaultMessage: 'ML job configuration outdated',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,24 @@ import React from 'react';
import { RecreateJobCallout } from './recreate_job_callout';

export const JobDefinitionOutdatedCallout: React.FC<{
moduleName: string;
onRecreateMlJob: () => void;
}> = ({ onRecreateMlJob }) => (
<RecreateJobCallout title={jobDefinitionOutdatedTitle} onRecreateMlJob={onRecreateMlJob}>
}> = ({ moduleName, onRecreateMlJob }) => (
<RecreateJobCallout
title={i18n.translate('xpack.infra.logs.analysis.jobDefinitionOutdatedCalloutTitle', {
defaultMessage: 'The {moduleName} ML job definition is outdated',
values: {
moduleName,
},
})}
onRecreateMlJob={onRecreateMlJob}
>
<FormattedMessage
id="xpack.infra.logs.analysis.jobDefinitionOutdatedCalloutMessage"
defaultMessage="A newer version of the ML job is available. Recreate the job to deploy the newer version. This removes previously detected anomalies."
defaultMessage="A newer version of the {moduleName} ML job is available. Recreate the job to deploy the newer version. This removes previously detected anomalies."
values={{
moduleName,
}}
/>
</RecreateJobCallout>
);

const jobDefinitionOutdatedTitle = i18n.translate(
'xpack.infra.logs.analysis.jobDefinitionOutdatedCalloutTitle',
{
defaultMessage: 'ML job definition outdated',
}
);
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,31 @@ export const LogAnalysisJobProblemIndicator: React.FC<{
hasOutdatedJobDefinitions: boolean;
hasStoppedJobs: boolean;
isFirstUse: boolean;
moduleName: string;
onRecreateMlJobForReconfiguration: () => void;
onRecreateMlJobForUpdate: () => void;
}> = ({
hasOutdatedJobConfigurations,
hasOutdatedJobDefinitions,
hasStoppedJobs,
isFirstUse,
moduleName,
onRecreateMlJobForReconfiguration,
onRecreateMlJobForUpdate,
}) => {
return (
<>
{hasOutdatedJobDefinitions ? (
<JobDefinitionOutdatedCallout onRecreateMlJob={onRecreateMlJobForUpdate} />
<JobDefinitionOutdatedCallout
moduleName={moduleName}
onRecreateMlJob={onRecreateMlJobForUpdate}
/>
) : null}
{hasOutdatedJobConfigurations ? (
<JobConfigurationOutdatedCallout onRecreateMlJob={onRecreateMlJobForReconfiguration} />
<JobConfigurationOutdatedCallout
moduleName={moduleName}
onRecreateMlJob={onRecreateMlJobForReconfiguration}
/>
) : null}
{hasStoppedJobs ? <JobStoppedCallout /> : null}
{isFirstUse ? <FirstUseCallout /> : null}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
*/

import React from 'react';
import { LogAnalysisJobProblemIndicator } from '../../../../../components/logging/log_analysis_job_status';
import { QualityWarning } from './quality_warnings';
import { QualityWarning } from '../../../containers/logs/log_analysis/log_analysis_module_types';
import { LogAnalysisJobProblemIndicator } from './log_analysis_job_problem_indicator';
import { CategoryQualityWarnings } from './quality_warning_notices';

export const CategoryJobNoticesSection: React.FC<{
hasOutdatedJobConfigurations: boolean;
hasOutdatedJobDefinitions: boolean;
hasStoppedJobs: boolean;
isFirstUse: boolean;
moduleName: string;
onRecreateMlJobForReconfiguration: () => void;
onRecreateMlJobForUpdate: () => void;
qualityWarnings: QualityWarning[];
Expand All @@ -22,6 +23,7 @@ export const CategoryJobNoticesSection: React.FC<{
hasOutdatedJobDefinitions,
hasStoppedJobs,
isFirstUse,
moduleName,
onRecreateMlJobForReconfiguration,
onRecreateMlJobForUpdate,
qualityWarnings,
Expand All @@ -32,6 +34,7 @@ export const CategoryJobNoticesSection: React.FC<{
hasOutdatedJobDefinitions={hasOutdatedJobDefinitions}
hasStoppedJobs={hasStoppedJobs}
isFirstUse={isFirstUse}
moduleName={moduleName}
onRecreateMlJobForReconfiguration={onRecreateMlJobForReconfiguration}
onRecreateMlJobForUpdate={onRecreateMlJobForUpdate}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { EuiCallOut } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';
import { CategoryQualityWarningReason, QualityWarning } from './quality_warnings';
import type {
CategoryQualityWarningReason,
QualityWarning,
} from '../../../containers/logs/log_analysis/log_analysis_module_types';

export const CategoryQualityWarnings: React.FC<{ qualityWarnings: QualityWarning[] }> = ({
qualityWarnings,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const InitialConfigurationStep: React.FunctionComponent<InitialConfigurat
);
};

const editableFormStatus = ['required', 'failed'];
const editableFormStatus = ['required', 'failed', 'skipped'];

const errorCalloutTitle = i18n.translate(
'xpack.infra.analysisSetup.steps.initialConfigurationStep.errorCalloutTitle',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* 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 { EuiButton, PropsOf } from '@elastic/eui';
import { FormattedMessage } from '@kbn/i18n/react';
import React from 'react';

export const ManageJobsButton: React.FunctionComponent<PropsOf<typeof EuiButton>> = (props) => (
<EuiButton {...props}>
<FormattedMessage
id="xpack.infra.logs.analysis.manageMlJobsButtonLabel"
defaultMessage="Manage ML jobs"
/>
</EuiButton>
);
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,10 @@ export const ProcessStep: React.FunctionComponent<ProcessStepProps> = ({
/>
</EuiButton>
</>
) : setupStatus.type === 'required' &&
(setupStatus.reason === 'update' || setupStatus.reason === 'reconfiguration') ? (
<RecreateMLJobsButton isDisabled={!isConfigurationValid} onClick={cleanUpAndSetUp} />
) : (
) : setupStatus.type === 'required' ? (
<CreateMLJobsButton isDisabled={!isConfigurationValid} onClick={setUp} />
) : (
<RecreateMLJobsButton isDisabled={!isConfigurationValid} onClick={cleanUpAndSetUp} />
)}
</EuiText>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,6 @@
* 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 './setup_flyout';
export * from './setup_flyout_state';
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* 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 { EuiSpacer, EuiSteps, EuiText, EuiTitle } from '@elastic/eui';
import React, { useCallback, useMemo } from 'react';
import { useLogEntryCategoriesSetup } from '../../../../containers/logs/log_analysis/modules/log_entry_categories';
import { createInitialConfigurationStep } from '../initial_configuration_step';
import { createProcessStep } from '../process_step';

export const LogEntryCategoriesSetupView: React.FC<{
onClose: () => void;
}> = ({ onClose }) => {
const {
cleanUpAndSetUp,
endTime,
isValidating,
lastSetupErrorMessages,
moduleDescriptor,
setEndTime,
setStartTime,
setValidatedIndices,
setUp,
setupStatus,
startTime,
validatedIndices,
validationErrors,
viewResults,
} = useLogEntryCategoriesSetup();

const viewResultsAndClose = useCallback(() => {
viewResults();
onClose();
}, [viewResults, onClose]);

const steps = useMemo(
() => [
createInitialConfigurationStep({
setStartTime,
setEndTime,
startTime,
endTime,
isValidating,
validatedIndices,
setupStatus,
setValidatedIndices,
validationErrors,
}),
createProcessStep({
cleanUpAndSetUp,
errorMessages: lastSetupErrorMessages,
isConfigurationValid: validationErrors.length <= 0 && !isValidating,
setUp,
setupStatus,
viewResults: viewResultsAndClose,
}),
],
[
cleanUpAndSetUp,
endTime,
isValidating,
lastSetupErrorMessages,
setEndTime,
setStartTime,
setUp,
setValidatedIndices,
setupStatus,
startTime,
validatedIndices,
validationErrors,
viewResultsAndClose,
]
);

return (
<>
<EuiTitle size="s">
<h3>{moduleDescriptor.moduleName} </h3>
</EuiTitle>
<EuiText size="s">{moduleDescriptor.moduleDescription}</EuiText>
<EuiSpacer />
<EuiSteps steps={steps} />
</>
);
};
Loading

0 comments on commit 8e7c699

Please sign in to comment.