Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Remove static page of initialization and failure case, add auto-check…
Browse files Browse the repository at this point in the history
… of detector state when initializing (#232)

* Remove static page of initialization and failure case, add auto-check of detector state when initializing
  • Loading branch information
yizheliu-amazon authored Jun 20, 2020
1 parent 04eb664 commit 9adf784
Show file tree
Hide file tree
Showing 11 changed files with 101 additions and 204 deletions.
3 changes: 2 additions & 1 deletion public/models/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export type UiMetaData = {
[key: string]: UiFeature;
};
};

export type Detector = {
primaryTerm: number;
seqNo: number;
Expand All @@ -103,7 +104,7 @@ export type Detector = {
enabledTime?: number;
disabledTime?: number;
curState: DETECTOR_STATE;
initializationError: string;
stateError: string;
};

export type DetectorListItem = {
Expand Down

This file was deleted.

This file was deleted.

97 changes: 78 additions & 19 deletions public/pages/DetectorResults/containers/AnomalyResults.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from '@elastic/eui';
import { get } from 'lodash';
import React, { useEffect, Fragment } from 'react';
import { useSelector } from 'react-redux';
import { useSelector, useDispatch } from 'react-redux';
import { RouteComponentProps } from 'react-router';
//@ts-ignore
import chrome from 'ui/chrome';
Expand All @@ -40,6 +40,9 @@ import {
INIT_ERROR_MESSAGE_FIELD,
INIT_ACTION_ITEM_FIELD,
} from '../utils/utils';
import { getDetector } from '../../../redux/reducers/ad';
import { MIN_IN_MILLI_SECS } from '../../../../server/utils/constants';
import { getInitFailureMessageAndActionItem } from '../../DetectorDetail/utils/helpers';

interface AnomalyResultsProps extends RouteComponentProps {
detectorId: string;
Expand All @@ -48,6 +51,7 @@ interface AnomalyResultsProps extends RouteComponentProps {
}

export function AnomalyResults(props: AnomalyResultsProps) {
const dispatch = useDispatch();
const detectorId = props.detectorId;
const detector = useSelector(
(state: AppState) => state.ad.detectors[detectorId]
Expand All @@ -61,6 +65,19 @@ export function AnomalyResults(props: AnomalyResultsProps) {
]);
}, []);

const fetchDetector = async () => {
await dispatch(getDetector(detectorId));
};

useEffect(() => {
if (detector && detector.curState === DETECTOR_STATE.INIT) {
const id = setInterval(fetchDetector, MIN_IN_MILLI_SECS);
return () => {
clearInterval(id);
};
}
}, [detector]);

const monitors = useSelector((state: AppState) => state.alerting.monitors);
const monitor = get(monitors, `${detectorId}.0`);

Expand All @@ -78,18 +95,23 @@ export function AnomalyResults(props: AnomalyResultsProps) {
// @ts-ignore
isDetectorPaused && detector.lastUpdateTime > detector.disabledTime;

const isDetectorInitializingAgain =
detector &&
detector.curState === DETECTOR_STATE.INIT &&
detector.enabled &&
detector.disabledTime;
const isDetectorInitializing =
detector && detector.curState === DETECTOR_STATE.INIT;

const initializationInfo = getDetectorInitializationInfo(detector);

const isInitOvertime = get(initializationInfo, IS_INIT_OVERTIME_FIELD, false);
const initDetails = get(initializationInfo, INIT_DETAILS_FIELD, {});
const initErrorMessage = get(initDetails, INIT_ERROR_MESSAGE_FIELD, '');
const initActionItem = get(initDetails, INIT_ACTION_ITEM_FIELD, '');

const isInitializingNormally = isDetectorInitializing && !isInitOvertime;

const isDetectorFailed =
detector &&
(detector.curState === DETECTOR_STATE.INIT_FAILURE ||
detector.curState === DETECTOR_STATE.UNEXPECTED_FAILURE);

return (
<Fragment>
<EuiPage style={{ marginTop: '16px', paddingTop: '0px' }}>
Expand All @@ -99,45 +121,82 @@ export function AnomalyResults(props: AnomalyResultsProps) {
<Fragment>
{isDetectorRunning ||
isDetectorPaused ||
isDetectorInitializingAgain ? (
isDetectorInitializing ||
isDetectorFailed ? (
<Fragment>
{isDetectorUpdated || isDetectorInitializingAgain ? (
{isDetectorUpdated ||
isDetectorInitializing ||
isDetectorFailed ? (
<EuiCallOut
title={
isDetectorUpdated
? 'The detector configuration has changed since it was last stopped.'
: !isInitOvertime
? 'The detector is being re-initialized based on the latest configuration changes.'
: `Detector initialization is not complete because ${initErrorMessage}.`
: isInitializingNormally
? 'The detector is being initialized based on the latest configuration changes.'
: isInitOvertime
? `Detector initialization is not complete because ${initErrorMessage}.`
: // detector has failure
`The detector is not initialized because ${get(
getInitFailureMessageAndActionItem(
//@ts-ignore
detector.stateError
),
'cause',
''
)}.`
}
color={
isInitializingNormally
? 'primary'
: isInitOvertime || isDetectorUpdated
? 'warning'
: // detector has failure
'danger'
}
color="warning"
iconType="alert"
iconType={isInitializingNormally ? 'iInCircle' : 'alert'}
style={{ marginBottom: '20px' }}
>
{isDetectorUpdated ? (
<p>
Restart the detector to see accurate anomalies based
on configuration changes.
</p>
) : !isInitOvertime ? (
) : isInitializingNormally ? (
<p>
After the initialization is complete, you will see the
anomaly results based on your latest configuration
changes.
</p>
) : (
) : isInitOvertime ? (
<p>{`${initActionItem}`}</p>
) : (
// detector has failure
<p>{`${get(
getInitFailureMessageAndActionItem(
//@ts-ignore
detector.stateError
),
'actionItem',
''
)}`}</p>
)}
<EuiButton
onClick={props.onSwitchToConfiguration}
color="warning"
color={
isInitializingNormally
? 'primary'
: isInitOvertime || isDetectorUpdated
? 'warning'
: // detector has failure
'danger'
}
style={{ marginRight: '8px' }}
>
View detector configuration
</EuiButton>
{isDetectorUpdated ? (
{isDetectorUpdated || isDetectorFailed ? (
<EuiButton
color="warning"
color={isDetectorFailed ? 'danger' : 'warning'}
onClick={props.onStartDetector}
iconType={'play'}
style={{ marginLeft: '8px' }}
Expand All @@ -157,7 +216,7 @@ export function AnomalyResults(props: AnomalyResultsProps) {
}
/>
</Fragment>
) : detector && detector.curState !== DETECTOR_STATE.RUNNING ? (
) : detector ? (
<Fragment>
<DetectorStateDetails
detectorId={detectorId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ export const AnomalyResultsLiveChart = (
clearInterval(intervalId);
};
}
}, []);
}, [props.detector]);

const showLoader = useDelayedLoader(isLoading);

Expand Down Expand Up @@ -381,7 +381,15 @@ export const AnomalyResultsLiveChart = (
</EuiFlexItem>
</EuiFlexGroup>
) : (
<EuiText>{`Not available when the detector is ${props.detector.curState.toLowerCase()}.`}</EuiText>
<EuiText>
{'Not available when the detector ' +
`${
props.detector.curState === DETECTOR_STATE.INIT_FAILURE ||
props.detector.curState === DETECTOR_STATE.UNEXPECTED_FAILURE
? 'initialization has failed.'
: `is ${props.detector.curState.toLowerCase()}.`
}`}
</EuiText>
)}
</ContentPanel>
</React.Fragment>
Expand Down
Loading

0 comments on commit 9adf784

Please sign in to comment.