mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
[ML] advanced settings validators
This commit is contained in:
parent
75de64f3c3
commit
8dc6d5b6ca
5 changed files with 25 additions and 13 deletions
|
@ -8,20 +8,31 @@
|
|||
import { CombinedJobWithStats } from '../types/anomaly_detection_jobs';
|
||||
import { resolveMaxTimeInterval } from './job_utils';
|
||||
import { isDefined } from '../types/guards';
|
||||
import { parseInterval } from './parse_interval';
|
||||
|
||||
const narrowBucketLength = 60;
|
||||
|
||||
/**
|
||||
* Resolved the lookback interval for the rule
|
||||
* using the formula max(2m, 2 * bucket_span) + query_delay + 1s
|
||||
*/
|
||||
export function getLookbackInterval(jobs: CombinedJobWithStats[]): number {
|
||||
const narrowBucketLength = 60;
|
||||
|
||||
const bucketSpanInSeconds = Math.round(
|
||||
const bucketSpanInSeconds = Math.ceil(
|
||||
resolveMaxTimeInterval(jobs.map((v) => v.analysis_config.bucket_span)) ?? 0
|
||||
);
|
||||
const queryDelayInSeconds = Math.round(
|
||||
const queryDelayInSeconds = Math.ceil(
|
||||
resolveMaxTimeInterval(jobs.map((v) => v.datafeed_config.query_delay).filter(isDefined)) ?? 0
|
||||
);
|
||||
|
||||
return Math.max(2 * narrowBucketLength, 2 * bucketSpanInSeconds) + queryDelayInSeconds + 1;
|
||||
}
|
||||
|
||||
export function getTopNBuckets(job: CombinedJobWithStats): number {
|
||||
const bucketSpan = parseInterval(job.analysis_config.bucket_span);
|
||||
|
||||
if (bucketSpan === null) {
|
||||
throw new Error('Unable to resolve a bucket span length');
|
||||
}
|
||||
|
||||
return Math.ceil(narrowBucketLength / bucketSpan.asSeconds());
|
||||
}
|
||||
|
|
|
@ -86,6 +86,10 @@ export function memoryInputValidator(allowedUnits = ALLOWED_DATA_UNITS) {
|
|||
|
||||
export function timeIntervalInputValidator() {
|
||||
return (value: string) => {
|
||||
if (value === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
const r = parseInterval(value);
|
||||
if (r === null) {
|
||||
return {
|
||||
|
|
|
@ -27,7 +27,7 @@ import { InterimResultsControl } from './interim_results_control';
|
|||
import { ConfigValidator } from './config_validator';
|
||||
import { CombinedJobWithStats } from '../../common/types/anomaly_detection_jobs';
|
||||
import { AdvancedSettings } from './advanced_settings';
|
||||
import { getLookbackInterval } from '../../common/util/alerts';
|
||||
import { getLookbackInterval, getTopNBuckets } from '../../common/util/alerts';
|
||||
|
||||
interface MlAnomalyAlertTriggerProps {
|
||||
alertParams: MlAnomalyDetectionAlertParams;
|
||||
|
@ -121,11 +121,11 @@ const MlAnomalyAlertTrigger: FC<MlAnomalyAlertTriggerProps> = ({
|
|||
|
||||
const advancedSettings = useMemo(() => {
|
||||
let { lookbackInterval, topNBuckets } = alertParams;
|
||||
if (lookbackInterval === undefined && jobConfigs.length > 0) {
|
||||
if ((lookbackInterval === undefined || lookbackInterval === '') && jobConfigs.length > 0) {
|
||||
lookbackInterval = `${getLookbackInterval(jobConfigs)}s`;
|
||||
}
|
||||
if (topNBuckets === undefined && jobConfigs.length > 0) {
|
||||
topNBuckets = 1;
|
||||
topNBuckets = getTopNBuckets(jobConfigs[0]);
|
||||
}
|
||||
return {
|
||||
lookbackInterval,
|
||||
|
|
|
@ -67,7 +67,7 @@ export const SeverityControl: FC<SeveritySelectorProps> = React.memo(({ value, o
|
|||
value={value ?? ANOMALY_THRESHOLD.LOW}
|
||||
onChange={(e) => {
|
||||
// @ts-ignore Property 'value' does not exist on type 'EventTarget' | (EventTarget & HTMLInputElement)
|
||||
onChange(e.target.value);
|
||||
onChange(Number(e.target.value));
|
||||
}}
|
||||
showLabels
|
||||
showValue
|
||||
|
|
|
@ -9,7 +9,7 @@ import { EuiFieldText, EuiFormRow } from '@elastic/eui';
|
|||
import React, { FC, ReactNode, useMemo } from 'react';
|
||||
import { invalidTimeIntervalMessage } from '../application/jobs/new_job/common/job_validator/util';
|
||||
import { composeValidators } from '../../common';
|
||||
import { requiredValidator, timeIntervalInputValidator } from '../../common/util/validators';
|
||||
import { timeIntervalInputValidator } from '../../common/util/validators';
|
||||
|
||||
interface TimeIntervalControlProps {
|
||||
label: string | ReactNode;
|
||||
|
@ -18,10 +18,7 @@ interface TimeIntervalControlProps {
|
|||
}
|
||||
|
||||
export const TimeIntervalControl: FC<TimeIntervalControlProps> = ({ value, onChange, label }) => {
|
||||
const validators = useMemo(
|
||||
() => composeValidators(requiredValidator(), timeIntervalInputValidator()),
|
||||
[]
|
||||
);
|
||||
const validators = useMemo(() => composeValidators(timeIntervalInputValidator()), []);
|
||||
|
||||
const validationErrors = useMemo(() => validators(value), [value]);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue