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

Add detector state page #65

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 60 additions & 1 deletion public/pages/DetectorDetail/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,63 @@
export enum DETECTOR_DETAIL_TABS {
RESULTS = 'results',
CONFIGURATIONS = 'configurations',
};
}

const DEFAULT_ACTION_ITEM = 'Please restart this detector to retry.';
// Known causes:
// https://github.com/opendistro-for-elasticsearch/anomaly-detection/blob/development/src/main/java/com/amazon/opendistroforelasticsearch/ad/transport/AnomalyResultTransportAction.java#L174-L185
export const DETECTOR_INIT_FAILURES = Object.freeze({
NO_TRAINING_DATA: {
//https://github.com/opendistro-for-elasticsearch/anomaly-detection/blob/development/src/main/java/com/amazon/opendistroforelasticsearch/ad/transport/AnomalyResultTransportAction.java#L801
keyword: 'Cannot get training data',
cause: 'lack of data ingestion',
actionItem:
'Please make sure your data ingestion is working. Or increase your detector time interval if data source has infrequent ingestion.',
},
COLD_START_ERROR: {
//https://github.com/opendistro-for-elasticsearch/anomaly-detection/blob/development/src/main/java/com/amazon/opendistroforelasticsearch/ad/transport/AnomalyResultTransportAction.java#L811
keyword: 'Error while cold start',
cause: 'error is found while model initialization',
actionItem: DEFAULT_ACTION_ITEM,
},
AD_MODEL_MEMORY_REACH_LIMIT: {
//https://github.com/opendistro-for-elasticsearch/anomaly-detection/blob/development/src/main/java/com/amazon/opendistroforelasticsearch/ad/ml/ModelManager.java#L272
keyword: 'AD models memory usage exceeds our limit',
cause: 'lack of memory for detector models',
actionItem:
'Model of this detector is too large, please reduce the number of features in this detector.',
},
DETECTOR_MEMORY_REACH_LIMIT: {
//https://github.com/opendistro-for-elasticsearch/anomaly-detection/blob/development/src/main/java/com/amazon/opendistroforelasticsearch/ad/ml/ModelManager.java#L783
keyword: 'Exceeded memory limit',
cause: 'lack of memory',
actionItem:
"Try deleting or stop other detectors that you don't actively use, increase your cluster size, reduce the number of features in this detector, or scale up with an instance type of more memory.",
},
DATA_INDEX_NOT_FOUND: {
//https://github.com/opendistro-for-elasticsearch/anomaly-detection/blob/development/src/main/java/com/amazon/opendistroforelasticsearch/ad/transport/AnomalyResultTransportAction.java#L366
keyword: 'Having trouble querying data: ',
cause: 'data index not found',
actionItem: 'Please make sure your data index does exist.',
},
ALL_FEATURES_DISABLED: {
//https://github.com/opendistro-for-elasticsearch/anomaly-detection/blob/development/src/main/java/com/amazon/opendistroforelasticsearch/ad/transport/AnomalyResultTransportAction.java#L368
keyword:
'Having trouble querying data because all of your features have been disabled',
cause: 'all features in this detector are disabled',
actionItem:
'Please enable some of your features and re-start your detector.',
},
DETECTOR_UNDEFINED: {
//https://github.com/opendistro-for-elasticsearch/anomaly-detection/blob/development/src/main/java/com/amazon/opendistroforelasticsearch/ad/transport/AnomalyResultTransportAction.java#L230
keyword: 'AnomalyDetector is not available',
cause: 'your detector is not defined',
actionItem: 'Please make sure your detector is defined.',
},
UNKNOWN_EXCEPTION: {
//https://github.com/opendistro-for-elasticsearch/anomaly-detection/blob/development/src/main/java/com/amazon/opendistroforelasticsearch/ad/transport/AnomalyResultTransportAction.java#L438
keyword: 'We might have bug',
cause: 'unknown error',
actionItem: DEFAULT_ACTION_ITEM,
},
});
27 changes: 27 additions & 0 deletions public/pages/DetectorDetail/utils/helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import { DETECTOR_INIT_FAILURES } from './constants';

export const getInitFailureMessageAndActionItem = (error: string): object => {
const failureDetails = Object.values(DETECTOR_INIT_FAILURES);
const failureDetail = failureDetails.find(failure =>
error.includes(failure.keyword)
);
if (!failureDetail) {
return DETECTOR_INIT_FAILURES.UNKNOWN_EXCEPTION;
}
return failureDetail;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { Fragment } from 'react';
import { Detector } from '../../../../models/interfaces';

export interface DetectorFeatureRequiredProps {
detector: Detector;
}

export const DetectorFeatureRequired = (
props: DetectorFeatureRequiredProps
) => {
return (
<EuiEmptyPrompt
style={{ maxWidth: '75%' }}
title={<h2>Features are required to run a detector</h2>}
body={
<Fragment>
<p>
Specify index fields that you want to find anomalies for by defining
features. Once you define the features, you can preview your
anomalies from a sample feature output.
</p>
</Fragment>
}
actions={[
<EuiButton
color="primary"
fill
href={`#/detectors/${props.detector.id}/features`}
style={{ width: '250px' }}
>
View detector configuration
</EuiButton>,
]}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
import React from 'react';
import { EuiButton, EuiEmptyPrompt, EuiIcon } from '@elastic/eui';
import { Fragment } from 'react';
import { Detector } from '../../../../models/interfaces';

export interface DetectorInitializationFailureProps {
detector: Detector;
onStartDetector(): void;
failureDetail: any;
onSwitchToConfiguration(): void;
}

export const DetectorInitializationFailure = (
props: DetectorInitializationFailureProps
) => {
return (
<EuiEmptyPrompt
style={{ maxWidth: '75%' }}
title={
<div>
<EuiIcon type="alert" size="l" color="danger" />

<h2>
{`The detector cannot be initialized due to ${props.failureDetail.cause}`}
</h2>
</div>
}
body={
<Fragment>
<p>{`${props.failureDetail.actionItem}`}</p>
</Fragment>
}
actions={[
<EuiButton
onClick={props.onSwitchToConfiguration}
style={{ width: '250px' }}
>
View detector configuration
</EuiButton>,
<EuiButton
onClick={props.onStartDetector}
iconType={'play'}
style={{ width: '250px' }}
>
Restart detector
</EuiButton>,
]}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
import React from 'react';
import { EuiButton, EuiEmptyPrompt, EuiLoadingSpinner } from '@elastic/eui';
import { Fragment } from 'react';
import { Detector } from '../../../../models/interfaces';

export interface DetectorInitializingProps {
detector: Detector;
onSwitchToConfiguration(): void;
}

export const DetectorInitializing = (props: DetectorInitializingProps) => {
return (
<EuiEmptyPrompt
style={{ maxWidth: '75%' }}
title={
<div>
<EuiLoadingSpinner size="l" />
<h2>The detector is initializing...</h2>
</div>
}
body={
<Fragment>
<p>
Based on your latest update to the detector configuration, the
detector is collecting sufficient data to generate accurate
real-time anomalies.
</p>
<p>
The longer the detector interval is, the longer the initialization
will take.
</p>
</Fragment>
}
actions={
<EuiButton
onClick={props.onSwitchToConfiguration}
style={{ width: '250px' }}
>
View detector configuration
</EuiButton>
}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

import React from 'react';
import { EuiButton, EuiEmptyPrompt } from '@elastic/eui';
import { Fragment } from 'react';
import { Detector } from '../../../../models/interfaces';

export interface DetectorStoppedProps {
detector: Detector;
onStartDetector(): void;
onSwitchToConfiguration(): void;
}

export const DetectorStopped = (props: DetectorStoppedProps) => {
return (
<EuiEmptyPrompt
style={{ maxWidth: '75%' }}
title={<h2>The detector is stopped</h2>}
body={
<Fragment>
{props.detector.enabledTime ? (
<p>
The detector is stopped due to your latest update to the detector
configuration. Run the detector to see anomalies.
</p>
) : (
<p>
The detector is never started. Please start the detector to see
anomalies.
</p>
)}
</Fragment>
}
actions={[
<EuiButton
onClick={props.onSwitchToConfiguration}
style={{ width: '250px' }}
>
View detector configuration
</EuiButton>,
<EuiButton
fill={!props.detector.enabledTime}
onClick={props.onStartDetector}
iconType={'play'}
style={{ width: '250px' }}
>
{props.detector.enabledTime ? 'Restart detector' : 'Start detector'}
</EuiButton>,
]}
/>
);
};
Loading