mirror of
https://github.com/elastic/kibana.git
synced 2025-04-25 02:09:32 -04:00
[Metrics UI] Display Too Many Buckets error when previewing Inventory Alerts (#70508)
* [Metrics UI] Display Too Many Buckets error when previewing Inventory Alerts * Fix typecheck
This commit is contained in:
parent
e7c54d3684
commit
5e869b0e77
3 changed files with 103 additions and 74 deletions
|
@ -5,6 +5,10 @@
|
||||||
*/
|
*/
|
||||||
import { mapValues, last, first } from 'lodash';
|
import { mapValues, last, first } from 'lodash';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import {
|
||||||
|
isTooManyBucketsPreviewException,
|
||||||
|
TOO_MANY_BUCKETS_PREVIEW_EXCEPTION,
|
||||||
|
} from '../../../../common/alerting/metrics';
|
||||||
import {
|
import {
|
||||||
InfraDatabaseSearchResponse,
|
InfraDatabaseSearchResponse,
|
||||||
CallWithRequestParams,
|
CallWithRequestParams,
|
||||||
|
@ -57,18 +61,23 @@ export const evaluateCondition = async (
|
||||||
|
|
||||||
const comparisonFunction = comparatorMap[comparator];
|
const comparisonFunction = comparatorMap[comparator];
|
||||||
|
|
||||||
return mapValues(currentValues, (value) => ({
|
const result = mapValues(currentValues, (value) => {
|
||||||
|
if (isTooManyBucketsPreviewException(value)) throw value;
|
||||||
|
return {
|
||||||
...condition,
|
...condition,
|
||||||
shouldFire:
|
shouldFire:
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
value !== null &&
|
value !== null &&
|
||||||
(Array.isArray(value)
|
(Array.isArray(value)
|
||||||
? value.map((v) => comparisonFunction(Number(v), threshold))
|
? value.map((v) => comparisonFunction(Number(v), threshold))
|
||||||
: comparisonFunction(value, threshold)),
|
: comparisonFunction(value as number, threshold)),
|
||||||
isNoData: value === null,
|
isNoData: value === null,
|
||||||
isError: value === undefined,
|
isError: value === undefined,
|
||||||
currentValue: getCurrentValue(value),
|
currentValue: getCurrentValue(value),
|
||||||
}));
|
};
|
||||||
|
}) as unknown; // Typescript doesn't seem to know what `throw` is doing
|
||||||
|
|
||||||
|
return result as Record<string, ConditionResult>;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCurrentValue: (value: any) => number = (value) => {
|
const getCurrentValue: (value: any) => number = (value) => {
|
||||||
|
@ -99,7 +108,7 @@ const getData = async (
|
||||||
timerange,
|
timerange,
|
||||||
includeTimeseries: Boolean(timerange.lookbackSize),
|
includeTimeseries: Boolean(timerange.lookbackSize),
|
||||||
};
|
};
|
||||||
|
try {
|
||||||
const { nodes } = await snapshot.getNodes(esClient, options);
|
const { nodes } = await snapshot.getNodes(esClient, options);
|
||||||
|
|
||||||
return nodes.reduce((acc, n) => {
|
return nodes.reduce((acc, n) => {
|
||||||
|
@ -114,6 +123,21 @@ const getData = async (
|
||||||
}
|
}
|
||||||
return acc;
|
return acc;
|
||||||
}, {} as Record<string, number | Array<number | string | null | undefined> | undefined | null>);
|
}, {} as Record<string, number | Array<number | string | null | undefined> | undefined | null>);
|
||||||
|
} catch (e) {
|
||||||
|
if (timerange.lookbackSize) {
|
||||||
|
// This code should only ever be reached when previewing the alert, not executing it
|
||||||
|
const causedByType = e.body?.error?.caused_by?.type;
|
||||||
|
if (causedByType === 'too_many_buckets_exception') {
|
||||||
|
return {
|
||||||
|
'*': {
|
||||||
|
[TOO_MANY_BUCKETS_PREVIEW_EXCEPTION]: true,
|
||||||
|
maxBuckets: e.body.error.caused_by.max_buckets,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return { '*': undefined };
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const comparatorMap = {
|
const comparatorMap = {
|
||||||
|
|
|
@ -6,6 +6,10 @@
|
||||||
import { Unit } from '@elastic/datemath';
|
import { Unit } from '@elastic/datemath';
|
||||||
import { first } from 'lodash';
|
import { first } from 'lodash';
|
||||||
import { InventoryMetricConditions } from './types';
|
import { InventoryMetricConditions } from './types';
|
||||||
|
import {
|
||||||
|
TOO_MANY_BUCKETS_PREVIEW_EXCEPTION,
|
||||||
|
isTooManyBucketsPreviewException,
|
||||||
|
} from '../../../../common/alerting/metrics';
|
||||||
import { ILegacyScopedClusterClient } from '../../../../../../../src/core/server';
|
import { ILegacyScopedClusterClient } from '../../../../../../../src/core/server';
|
||||||
import { InfraSource } from '../../../../common/http_api/source_api';
|
import { InfraSource } from '../../../../common/http_api/source_api';
|
||||||
import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds';
|
import { getIntervalInSeconds } from '../../../utils/get_interval_in_seconds';
|
||||||
|
@ -46,7 +50,7 @@ export const previewInventoryMetricThresholdAlert = async ({
|
||||||
|
|
||||||
const alertIntervalInSeconds = getIntervalInSeconds(alertInterval);
|
const alertIntervalInSeconds = getIntervalInSeconds(alertInterval);
|
||||||
const alertResultsPerExecution = alertIntervalInSeconds / bucketIntervalInSeconds;
|
const alertResultsPerExecution = alertIntervalInSeconds / bucketIntervalInSeconds;
|
||||||
|
try {
|
||||||
const results = await Promise.all(
|
const results = await Promise.all(
|
||||||
criteria.map((c) =>
|
criteria.map((c) =>
|
||||||
evaluateCondition(c, nodeType, config, callCluster, filterQuery, lookbackSize)
|
evaluateCondition(c, nodeType, config, callCluster, filterQuery, lookbackSize)
|
||||||
|
@ -80,4 +84,9 @@ export const previewInventoryMetricThresholdAlert = async ({
|
||||||
});
|
});
|
||||||
|
|
||||||
return previewResults;
|
return previewResults;
|
||||||
|
} catch (e) {
|
||||||
|
if (!isTooManyBucketsPreviewException(e)) throw e;
|
||||||
|
const { maxBuckets } = e;
|
||||||
|
throw new Error(`${TOO_MANY_BUCKETS_PREVIEW_EXCEPTION}:${maxBuckets}`);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
import { mapValues, first, last, isNaN } from 'lodash';
|
import { mapValues, first, last, isNaN } from 'lodash';
|
||||||
import {
|
import {
|
||||||
TooManyBucketsPreviewExceptionMetadata,
|
|
||||||
isTooManyBucketsPreviewException,
|
isTooManyBucketsPreviewException,
|
||||||
TOO_MANY_BUCKETS_PREVIEW_EXCEPTION,
|
TOO_MANY_BUCKETS_PREVIEW_EXCEPTION,
|
||||||
} from '../../../../../common/alerting/metrics';
|
} from '../../../../../common/alerting/metrics';
|
||||||
|
@ -58,9 +57,7 @@ export const evaluateAlert = (
|
||||||
);
|
);
|
||||||
const { threshold, comparator } = criterion;
|
const { threshold, comparator } = criterion;
|
||||||
const comparisonFunction = comparatorMap[comparator];
|
const comparisonFunction = comparatorMap[comparator];
|
||||||
return mapValues(
|
return mapValues(currentValues, (values: number | number[] | null) => {
|
||||||
currentValues,
|
|
||||||
(values: number | number[] | null | TooManyBucketsPreviewExceptionMetadata) => {
|
|
||||||
if (isTooManyBucketsPreviewException(values)) throw values;
|
if (isTooManyBucketsPreviewException(values)) throw values;
|
||||||
return {
|
return {
|
||||||
...criterion,
|
...criterion,
|
||||||
|
@ -72,8 +69,7 @@ export const evaluateAlert = (
|
||||||
isNoData: values === null,
|
isNoData: values === null,
|
||||||
isError: isNaN(values),
|
isError: isNaN(values),
|
||||||
};
|
};
|
||||||
}
|
});
|
||||||
);
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue