From a29fdf552bd8aa7e5b8d2a648ffbeb8e489af349 Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Wed, 22 Sep 2021 14:15:55 -0600 Subject: [PATCH] [Monitoring] Add KQL filter bar to alerts (#111663) * [Monitoring] Add KQL filter bar to alerts * Finish adding filters to UI * Adding filterQuery to all the backend alert functions * removing unused translations * fixing types * Moving alerting code to async imports Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../{server/lib => common}/ccs_utils.test.js | 0 .../{server/lib => common}/ccs_utils.ts | 3 +- .../plugins/monitoring/common/types/alerts.ts | 4 + .../ccr_read_exceptions_alert/index.tsx | 11 +- .../param_details_form/expression.tsx | 57 +++- .../use_derived_index_pattern.tsx | 44 +++ .../cpu_usage_alert/cpu_usage_alert.tsx | 11 +- .../public/alerts/disk_usage_alert/index.tsx | 11 +- .../alerts/large_shard_size_alert/index.tsx | 11 +- .../public/alerts/legacy_alert/expression.tsx | 56 ++++ .../alerts/legacy_alert/legacy_alert.tsx | 21 +- .../alerts/memory_usage_alert/index.tsx | 11 +- .../thread_pool_rejections_alert/index.tsx | 6 +- .../kuery_bar/autocomplete_field.tsx | 316 ++++++++++++++++++ .../public/components/kuery_bar/index.tsx | 98 ++++++ .../components/kuery_bar/suggestion_item.tsx | 119 +++++++ .../kuery_bar/with_kuery_autocompletion.tsx | 111 ++++++ x-pack/plugins/monitoring/public/lib/kuery.ts | 23 ++ .../monitoring/public/lib/typed_react.tsx | 82 +++++ x-pack/plugins/monitoring/public/plugin.ts | 52 +-- .../server/alerts/ccr_read_exceptions_rule.ts | 5 +- .../server/alerts/cluster_health_rule.ts | 7 +- .../server/alerts/cpu_usage_rule.ts | 5 +- .../server/alerts/disk_usage_rule.ts | 5 +- .../elasticsearch_version_mismatch_rule.ts | 3 +- .../alerts/kibana_version_mismatch_rule.ts | 3 +- .../server/alerts/large_shard_size_rule.ts | 5 +- .../server/alerts/license_expiration_rule.ts | 2 +- .../alerts/logstash_version_mismatch_rule.ts | 3 +- .../server/alerts/memory_usage_rule.ts | 5 +- .../alerts/missing_monitoring_data_rule.ts | 5 +- .../server/alerts/nodes_changed_rule.ts | 3 +- .../thread_pool_rejections_rule_base.ts | 5 +- .../lib/fetch_stack_product_usage.ts | 2 +- .../lib/get_stack_products_usage.ts | 2 +- .../lib/alerts/fetch_ccr_read_exceptions.ts | 12 +- .../server/lib/alerts/fetch_cluster_health.ts | 12 +- .../alerts/fetch_cpu_usage_node_stats.test.ts | 7 +- .../lib/alerts/fetch_cpu_usage_node_stats.ts | 12 +- .../lib/alerts/fetch_disk_usage_node_stats.ts | 12 +- .../alerts/fetch_elasticsearch_versions.ts | 12 +- .../lib/alerts/fetch_index_shard_size.ts | 12 +- .../lib/alerts/fetch_kibana_versions.ts | 12 +- .../server/lib/alerts/fetch_licenses.ts | 12 +- .../lib/alerts/fetch_logstash_versions.ts | 12 +- .../alerts/fetch_memory_usage_node_stats.ts | 12 +- .../alerts/fetch_missing_monitoring_data.ts | 12 +- .../alerts/fetch_nodes_from_cluster_stats.ts | 12 +- .../fetch_thread_pool_rejections_stats.ts | 12 +- .../server/lib/cluster/get_clusters_stats.ts | 2 +- .../server/lib/cluster/get_index_patterns.ts | 2 +- .../server/lib/logs/init_infra_source.ts | 2 +- .../server/routes/api/v1/apm/instance.js | 2 +- .../server/routes/api/v1/apm/instances.js | 2 +- .../server/routes/api/v1/apm/overview.js | 2 +- .../server/routes/api/v1/beats/beat_detail.js | 2 +- .../server/routes/api/v1/beats/beats.js | 2 +- .../server/routes/api/v1/beats/overview.js | 2 +- .../server/routes/api/v1/elasticsearch/ccr.ts | 2 +- .../routes/api/v1/elasticsearch/ccr_shard.ts | 2 +- .../api/v1/elasticsearch/index_detail.js | 2 +- .../routes/api/v1/elasticsearch/indices.js | 2 +- .../routes/api/v1/elasticsearch/ml_jobs.js | 2 +- .../api/v1/elasticsearch/node_detail.js | 2 +- .../routes/api/v1/elasticsearch/nodes.js | 2 +- .../routes/api/v1/elasticsearch/overview.js | 2 +- .../check/internal_monitoring.ts | 2 +- .../server/routes/api/v1/kibana/instance.ts | 2 +- .../server/routes/api/v1/kibana/instances.js | 2 +- .../server/routes/api/v1/kibana/overview.js | 2 +- .../server/routes/api/v1/logstash/node.js | 2 +- .../server/routes/api/v1/logstash/nodes.js | 2 +- .../server/routes/api/v1/logstash/overview.js | 2 +- .../server/routes/api/v1/logstash/pipeline.js | 2 +- .../pipelines/cluster_pipeline_ids.js | 2 +- .../logstash/pipelines/cluster_pipelines.js | 2 +- .../v1/logstash/pipelines/node_pipelines.js | 2 +- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 79 files changed, 1208 insertions(+), 120 deletions(-) rename x-pack/plugins/monitoring/{server/lib => common}/ccs_utils.test.js (100%) rename x-pack/plugins/monitoring/{server/lib => common}/ccs_utils.ts (96%) create mode 100644 x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx create mode 100644 x-pack/plugins/monitoring/public/alerts/legacy_alert/expression.tsx create mode 100644 x-pack/plugins/monitoring/public/components/kuery_bar/autocomplete_field.tsx create mode 100644 x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx create mode 100644 x-pack/plugins/monitoring/public/components/kuery_bar/suggestion_item.tsx create mode 100644 x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx create mode 100644 x-pack/plugins/monitoring/public/lib/kuery.ts create mode 100644 x-pack/plugins/monitoring/public/lib/typed_react.tsx diff --git a/x-pack/plugins/monitoring/server/lib/ccs_utils.test.js b/x-pack/plugins/monitoring/common/ccs_utils.test.js similarity index 100% rename from x-pack/plugins/monitoring/server/lib/ccs_utils.test.js rename to x-pack/plugins/monitoring/common/ccs_utils.test.js diff --git a/x-pack/plugins/monitoring/server/lib/ccs_utils.ts b/x-pack/plugins/monitoring/common/ccs_utils.ts similarity index 96% rename from x-pack/plugins/monitoring/server/lib/ccs_utils.ts rename to x-pack/plugins/monitoring/common/ccs_utils.ts index 1d899456913b9..7efe6e43ddbbd 100644 --- a/x-pack/plugins/monitoring/server/lib/ccs_utils.ts +++ b/x-pack/plugins/monitoring/common/ccs_utils.ts @@ -6,7 +6,8 @@ */ import { isFunction, get } from 'lodash'; -import type { MonitoringConfig } from '../config'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import type { MonitoringConfig } from '../server/config'; type Config = Partial & { get?: (key: string) => any; diff --git a/x-pack/plugins/monitoring/common/types/alerts.ts b/x-pack/plugins/monitoring/common/types/alerts.ts index 17bbffce19a18..1f68b0c55a046 100644 --- a/x-pack/plugins/monitoring/common/types/alerts.ts +++ b/x-pack/plugins/monitoring/common/types/alerts.ts @@ -48,12 +48,16 @@ export interface CommonAlertParams { duration: string; threshold?: number; limit?: string; + filterQuery?: string; + filterQueryText?: string; [key: string]: unknown; } export interface ThreadPoolRejectionsAlertParams { threshold: number; duration: string; + filterQuery?: string; + filterQueryText?: string; } export interface AlertEnableAction { diff --git a/x-pack/plugins/monitoring/public/alerts/ccr_read_exceptions_alert/index.tsx b/x-pack/plugins/monitoring/public/alerts/ccr_read_exceptions_alert/index.tsx index 1de9a175026a6..64eab04cbd5ce 100644 --- a/x-pack/plugins/monitoring/public/alerts/ccr_read_exceptions_alert/index.tsx +++ b/x-pack/plugins/monitoring/public/alerts/ccr_read_exceptions_alert/index.tsx @@ -15,6 +15,7 @@ import { RULE_REQUIRES_APP_CONTEXT, } from '../../../common/constants'; import { AlertTypeParams } from '../../../../alerting/common'; +import { MonitoringConfig } from '../../types'; interface ValidateOptions extends AlertTypeParams { duration: string; @@ -36,7 +37,9 @@ const validate = (inputValues: ValidateOptions): ValidationResult => { return validationResult; }; -export function createCCRReadExceptionsAlertType(): AlertTypeModel { +export function createCCRReadExceptionsAlertType( + config: MonitoringConfig +): AlertTypeModel { return { id: RULE_CCR_READ_EXCEPTIONS, description: RULE_DETAILS[RULE_CCR_READ_EXCEPTIONS].description, @@ -45,7 +48,11 @@ export function createCCRReadExceptionsAlertType(): AlertTypeModel ( - + ), validate, defaultActionMessage: '{{context.internalFullMessage}}', diff --git a/x-pack/plugins/monitoring/public/alerts/components/param_details_form/expression.tsx b/x-pack/plugins/monitoring/public/alerts/components/param_details_form/expression.tsx index df17ce1a911a0..827eed955d535 100644 --- a/x-pack/plugins/monitoring/public/alerts/components/param_details_form/expression.tsx +++ b/x-pack/plugins/monitoring/public/alerts/components/param_details_form/expression.tsx @@ -5,14 +5,23 @@ * 2.0. */ -import React, { Fragment } from 'react'; -import { EuiForm, EuiSpacer } from '@elastic/eui'; +import React, { Fragment, useCallback } from 'react'; +import { EuiForm, EuiFormRow, EuiSpacer } from '@elastic/eui'; +import { DataPublicPluginStart } from 'src/plugins/data/public'; +import { debounce } from 'lodash'; +import { i18n } from '@kbn/i18n'; import { CommonAlertParamDetails } from '../../../../common/types/alerts'; import { AlertParamDuration } from '../../flyout_expressions/alert_param_duration'; import { AlertParamType } from '../../../../common/enums'; import { AlertParamPercentage } from '../../flyout_expressions/alert_param_percentage'; import { AlertParamNumber } from '../../flyout_expressions/alert_param_number'; import { AlertParamTextField } from '../../flyout_expressions/alert_param_textfield'; +import { MonitoringConfig } from '../../../types'; +import { useDerivedIndexPattern } from './use_derived_index_pattern'; +import { KueryBar } from '../../../components/kuery_bar'; +import { convertKueryToElasticSearchQuery } from '../../../lib/kuery'; + +const FILTER_TYPING_DEBOUNCE_MS = 500; export interface Props { alertParams: { [property: string]: any }; @@ -20,10 +29,14 @@ export interface Props { setAlertProperty: (property: string, value: any) => void; errors: { [key: string]: string[] }; paramDetails: CommonAlertParamDetails; + data: DataPublicPluginStart; + config?: MonitoringConfig; } export const Expression: React.FC = (props) => { - const { alertParams, paramDetails, setAlertParams, errors } = props; + const { alertParams, paramDetails, setAlertParams, errors, config, data } = props; + + const { derivedIndexPattern } = useDerivedIndexPattern(data, config); const alertParamsUi = Object.keys(paramDetails).map((alertParamName) => { const details = paramDetails[alertParamName]; @@ -77,10 +90,44 @@ export const Expression: React.FC = (props) => { } }); + const onFilterChange = useCallback( + (filter: string) => { + setAlertParams('filterQueryText', filter); + setAlertParams( + 'filterQuery', + convertKueryToElasticSearchQuery(filter, derivedIndexPattern) || '' + ); + }, + [setAlertParams, derivedIndexPattern] + ); + + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + const debouncedOnFilterChange = useCallback(debounce(onFilterChange, FILTER_TYPING_DEBOUNCE_MS), [ + onFilterChange, + ]); + return ( - {alertParamsUi} - + + {alertParamsUi} + + + + + + ); }; diff --git a/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx b/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx new file mode 100644 index 0000000000000..1a4d88d690b84 --- /dev/null +++ b/x-pack/plugins/monitoring/public/alerts/components/param_details_form/use_derived_index_pattern.tsx @@ -0,0 +1,44 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { useEffect, useState } from 'react'; +import { DataPublicPluginStart, IFieldType, IIndexPattern } from 'src/plugins/data/public'; +import { + INDEX_PATTERN_BEATS, + INDEX_PATTERN_ELASTICSEARCH, + INDEX_PATTERN_KIBANA, + INDEX_PATTERN_LOGSTASH, +} from '../../../../common/constants'; +import { prefixIndexPattern } from '../../../../common/ccs_utils'; +import { MonitoringConfig } from '../../../types'; + +const INDEX_PATTERNS = `${INDEX_PATTERN_ELASTICSEARCH},${INDEX_PATTERN_KIBANA},${INDEX_PATTERN_LOGSTASH},${INDEX_PATTERN_BEATS}`; + +export const useDerivedIndexPattern = ( + data: DataPublicPluginStart, + config?: MonitoringConfig +): { loading: boolean; derivedIndexPattern: IIndexPattern } => { + const indexPattern = prefixIndexPattern(config || ({} as MonitoringConfig), INDEX_PATTERNS, '*'); + const [loading, setLoading] = useState(true); + const [fields, setFields] = useState([]); + useEffect(() => { + (async function fetchData() { + const result = await data.indexPatterns.getFieldsForWildcard({ + pattern: indexPattern, + }); + setFields(result); + setLoading(false); + })(); + }, [indexPattern, data.indexPatterns]); + return { + loading, + derivedIndexPattern: { + title: indexPattern, + fields, + }, + }; +}; diff --git a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx b/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx index ec7a583ec2ba1..f0e0a413435f9 100644 --- a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx +++ b/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/cpu_usage_alert.tsx @@ -11,8 +11,11 @@ import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types'; import { RULE_CPU_USAGE, RULE_DETAILS, RULE_REQUIRES_APP_CONTEXT } from '../../../common/constants'; import { validate, MonitoringAlertTypeParams } from '../components/param_details_form/validation'; import { Expression, Props } from '../components/param_details_form/expression'; +import { MonitoringConfig } from '../../types'; -export function createCpuUsageAlertType(): AlertTypeModel { +export function createCpuUsageAlertType( + config: MonitoringConfig +): AlertTypeModel { return { id: RULE_CPU_USAGE, description: RULE_DETAILS[RULE_CPU_USAGE].description, @@ -21,7 +24,11 @@ export function createCpuUsageAlertType(): AlertTypeModel ( - + ), validate, defaultActionMessage: '{{context.internalFullMessage}}', diff --git a/x-pack/plugins/monitoring/public/alerts/disk_usage_alert/index.tsx b/x-pack/plugins/monitoring/public/alerts/disk_usage_alert/index.tsx index 779945da0c9e0..5f9f9536ae567 100644 --- a/x-pack/plugins/monitoring/public/alerts/disk_usage_alert/index.tsx +++ b/x-pack/plugins/monitoring/public/alerts/disk_usage_alert/index.tsx @@ -16,8 +16,11 @@ import { RULE_DETAILS, RULE_REQUIRES_APP_CONTEXT, } from '../../../common/constants'; +import { MonitoringConfig } from '../../types'; -export function createDiskUsageAlertType(): AlertTypeModel { +export function createDiskUsageAlertType( + config: MonitoringConfig +): AlertTypeModel { return { id: RULE_DISK_USAGE, description: RULE_DETAILS[RULE_DISK_USAGE].description, @@ -26,7 +29,11 @@ export function createDiskUsageAlertType(): AlertTypeModel ( - + ), validate, defaultActionMessage: '{{context.internalFullMessage}}', diff --git a/x-pack/plugins/monitoring/public/alerts/large_shard_size_alert/index.tsx b/x-pack/plugins/monitoring/public/alerts/large_shard_size_alert/index.tsx index e0f595abe7602..afaf20d60d882 100644 --- a/x-pack/plugins/monitoring/public/alerts/large_shard_size_alert/index.tsx +++ b/x-pack/plugins/monitoring/public/alerts/large_shard_size_alert/index.tsx @@ -15,6 +15,7 @@ import { RULE_REQUIRES_APP_CONTEXT, } from '../../../common/constants'; import { AlertTypeParams } from '../../../../alerting/common'; +import { MonitoringConfig } from '../../types'; interface ValidateOptions extends AlertTypeParams { indexPattern: string; @@ -36,7 +37,9 @@ const validate = (inputValues: ValidateOptions): ValidationResult => { return validationResult; }; -export function createLargeShardSizeAlertType(): AlertTypeModel { +export function createLargeShardSizeAlertType( + config: MonitoringConfig +): AlertTypeModel { return { id: RULE_LARGE_SHARD_SIZE, description: RULE_DETAILS[RULE_LARGE_SHARD_SIZE].description, @@ -45,7 +48,11 @@ export function createLargeShardSizeAlertType(): AlertTypeModel return `${docLinks.links.monitoring.alertsKibanaLargeShardSize}`; }, alertParamsExpression: (props: Props) => ( - + ), validate, defaultActionMessage: '{{context.internalFullMessage}}', diff --git a/x-pack/plugins/monitoring/public/alerts/legacy_alert/expression.tsx b/x-pack/plugins/monitoring/public/alerts/legacy_alert/expression.tsx new file mode 100644 index 0000000000000..fe6adf66c1d4f --- /dev/null +++ b/x-pack/plugins/monitoring/public/alerts/legacy_alert/expression.tsx @@ -0,0 +1,56 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import React, { useCallback } from 'react'; +import { debounce } from 'lodash'; +import { EuiSpacer, EuiForm, EuiFormRow } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { useDerivedIndexPattern } from '../components/param_details_form/use_derived_index_pattern'; +import { convertKueryToElasticSearchQuery } from '../../lib/kuery'; +import { KueryBar } from '../../components/kuery_bar'; +import { Props } from '../components/param_details_form/expression'; + +const FILTER_TYPING_DEBOUNCE_MS = 500; + +export const Expression = ({ alertParams, config, setAlertParams, data }: Props) => { + const { derivedIndexPattern } = useDerivedIndexPattern(data, config); + const onFilterChange = useCallback( + (filter: string) => { + setAlertParams('filterQueryText', filter); + setAlertParams( + 'filterQuery', + convertKueryToElasticSearchQuery(filter, derivedIndexPattern) || '' + ); + }, + [setAlertParams, derivedIndexPattern] + ); + + /* eslint-disable-next-line react-hooks/exhaustive-deps */ + const debouncedOnFilterChange = useCallback(debounce(onFilterChange, FILTER_TYPING_DEBOUNCE_MS), [ + onFilterChange, + ]); + return ( + + + + + + + ); +}; diff --git a/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx b/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx index cac4873bc0c79..a6c22035c5a5a 100644 --- a/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx +++ b/x-pack/plugins/monitoring/public/alerts/legacy_alert/legacy_alert.tsx @@ -5,9 +5,7 @@ * 2.0. */ -import React, { Fragment } from 'react'; -import { i18n } from '@kbn/i18n'; -import { EuiTextColor, EuiSpacer } from '@elastic/eui'; +import React from 'react'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types'; import { @@ -15,8 +13,11 @@ import { LEGACY_RULE_DETAILS, RULE_REQUIRES_APP_CONTEXT, } from '../../../common/constants'; +import { MonitoringConfig } from '../../types'; +import { Expression } from './expression'; +import { Props } from '../components/param_details_form/expression'; -export function createLegacyAlertTypes(): AlertTypeModel[] { +export function createLegacyAlertTypes(config: MonitoringConfig): AlertTypeModel[] { return LEGACY_RULES.map((legacyAlert) => { return { id: legacyAlert, @@ -25,17 +26,7 @@ export function createLegacyAlertTypes(): AlertTypeModel[] { documentationUrl(docLinks) { return `${docLinks.links.monitoring.alertsKibanaClusterAlerts}`; }, - alertParamsExpression: () => ( - - - - {i18n.translate('xpack.monitoring.alerts.legacyAlert.expressionText', { - defaultMessage: 'There is nothing to configure.', - })} - - - - ), + alertParamsExpression: (props: Props) => , defaultActionMessage: '{{context.internalFullMessage}}', validate: () => ({ errors: {} }), requiresAppContext: RULE_REQUIRES_APP_CONTEXT, diff --git a/x-pack/plugins/monitoring/public/alerts/memory_usage_alert/index.tsx b/x-pack/plugins/monitoring/public/alerts/memory_usage_alert/index.tsx index 3e55b6d5454ff..2fe0c9b77c0eb 100644 --- a/x-pack/plugins/monitoring/public/alerts/memory_usage_alert/index.tsx +++ b/x-pack/plugins/monitoring/public/alerts/memory_usage_alert/index.tsx @@ -16,8 +16,11 @@ import { RULE_DETAILS, RULE_REQUIRES_APP_CONTEXT, } from '../../../common/constants'; +import { MonitoringConfig } from '../../types'; -export function createMemoryUsageAlertType(): AlertTypeModel { +export function createMemoryUsageAlertType( + config: MonitoringConfig +): AlertTypeModel { return { id: RULE_MEMORY_USAGE, description: RULE_DETAILS[RULE_MEMORY_USAGE].description, @@ -26,7 +29,11 @@ export function createMemoryUsageAlertType(): AlertTypeModel ( - + ), validate, defaultActionMessage: '{{context.internalFullMessage}}', diff --git a/x-pack/plugins/monitoring/public/alerts/thread_pool_rejections_alert/index.tsx b/x-pack/plugins/monitoring/public/alerts/thread_pool_rejections_alert/index.tsx index 7fd9438e1cea3..e8a15ad835581 100644 --- a/x-pack/plugins/monitoring/public/alerts/thread_pool_rejections_alert/index.tsx +++ b/x-pack/plugins/monitoring/public/alerts/thread_pool_rejections_alert/index.tsx @@ -13,6 +13,7 @@ import { Expression, Props } from '../components/param_details_form/expression'; import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types'; import { CommonAlertParamDetails } from '../../../common/types/alerts'; import { RULE_REQUIRES_APP_CONTEXT } from '../../../common/constants'; +import { MonitoringConfig } from '../../types'; interface ThreadPoolTypes { [key: string]: unknown; @@ -26,7 +27,8 @@ interface ThreadPoolRejectionAlertDetails { export function createThreadPoolRejectionsAlertType( alertId: string, - threadPoolAlertDetails: ThreadPoolRejectionAlertDetails + threadPoolAlertDetails: ThreadPoolRejectionAlertDetails, + config: MonitoringConfig ): AlertTypeModel { return { id: alertId, @@ -38,7 +40,7 @@ export function createThreadPoolRejectionsAlertType( alertParamsExpression: (props: Props) => ( <> - + ), validate: (inputValues: ThreadPoolTypes) => { diff --git a/x-pack/plugins/monitoring/public/components/kuery_bar/autocomplete_field.tsx b/x-pack/plugins/monitoring/public/components/kuery_bar/autocomplete_field.tsx new file mode 100644 index 0000000000000..522256ea49b98 --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/kuery_bar/autocomplete_field.tsx @@ -0,0 +1,316 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiFieldSearch, EuiOutsideClickDetector, EuiPanel } from '@elastic/eui'; +import React from 'react'; +import { QuerySuggestion } from '../../../../../../src/plugins/data/public'; +import { euiStyled } from '../../../../../../src/plugins/kibana_react/common'; +import { composeStateUpdaters } from '../../lib/typed_react'; +import { SuggestionItem } from './suggestion_item'; + +interface AutocompleteFieldProps { + isLoadingSuggestions: boolean; + isValid: boolean; + loadSuggestions: (value: string, cursorPosition: number, maxCount?: number) => void; + onSubmit?: (value: string) => void; + onChange?: (value: string) => void; + placeholder?: string; + suggestions: QuerySuggestion[]; + value: string; + disabled?: boolean; + autoFocus?: boolean; + 'aria-label'?: string; +} + +interface AutocompleteFieldState { + areSuggestionsVisible: boolean; + isFocused: boolean; + selectedIndex: number | null; +} + +export class AutocompleteField extends React.Component< + AutocompleteFieldProps, + AutocompleteFieldState +> { + public readonly state: AutocompleteFieldState = { + areSuggestionsVisible: false, + isFocused: false, + selectedIndex: null, + }; + + private inputElement: HTMLInputElement | null = null; + + public render() { + const { + suggestions, + isLoadingSuggestions, + isValid, + placeholder, + value, + disabled, + 'aria-label': ariaLabel, + } = this.props; + const { areSuggestionsVisible, selectedIndex } = this.state; + + return ( + + + + {areSuggestionsVisible && !isLoadingSuggestions && suggestions.length > 0 ? ( + + {suggestions.map((suggestion, suggestionIndex) => ( + + ))} + + ) : null} + + + ); + } + + public componentDidMount() { + if (this.inputElement && this.props.autoFocus) { + this.inputElement.focus(); + } + } + + public componentDidUpdate(prevProps: AutocompleteFieldProps) { + const hasNewValue = prevProps.value !== this.props.value; + const hasNewSuggestions = prevProps.suggestions !== this.props.suggestions; + + if (hasNewValue) { + this.updateSuggestions(); + } + + if (hasNewValue && this.props.value === '') { + this.submit(); + } + + if (hasNewSuggestions && this.state.isFocused) { + this.showSuggestions(); + } + } + + private handleChangeInputRef = (element: HTMLInputElement | null) => { + this.inputElement = element; + }; + + private handleChange = (evt: React.ChangeEvent) => { + this.changeValue(evt.currentTarget.value); + }; + + private handleKeyDown = (evt: React.KeyboardEvent) => { + const { suggestions } = this.props; + + switch (evt.key) { + case 'ArrowUp': + evt.preventDefault(); + if (suggestions.length > 0) { + this.setState( + composeStateUpdaters(withSuggestionsVisible, withPreviousSuggestionSelected) + ); + } + break; + case 'ArrowDown': + evt.preventDefault(); + if (suggestions.length > 0) { + this.setState(composeStateUpdaters(withSuggestionsVisible, withNextSuggestionSelected)); + } else { + this.updateSuggestions(); + } + break; + case 'Enter': + evt.preventDefault(); + if (this.state.selectedIndex !== null) { + this.applySelectedSuggestion(); + } else { + this.submit(); + } + break; + case 'Escape': + evt.preventDefault(); + this.setState(withSuggestionsHidden); + break; + } + }; + + private handleKeyUp = (evt: React.KeyboardEvent) => { + switch (evt.key) { + case 'ArrowLeft': + case 'ArrowRight': + case 'Home': + case 'End': + this.updateSuggestions(); + break; + } + }; + + private handleFocus = () => { + this.setState(composeStateUpdaters(withSuggestionsVisible, withFocused)); + }; + + private handleBlur = () => { + this.setState(composeStateUpdaters(withSuggestionsHidden, withUnfocused)); + }; + + private selectSuggestionAt = (index: number) => () => { + this.setState(withSuggestionAtIndexSelected(index)); + }; + + private applySelectedSuggestion = () => { + if (this.state.selectedIndex !== null) { + this.applySuggestionAt(this.state.selectedIndex)(); + } + }; + + private applySuggestionAt = (index: number) => () => { + const { value, suggestions } = this.props; + const selectedSuggestion = suggestions[index]; + + if (!selectedSuggestion) { + return; + } + + const newValue = + value.substr(0, selectedSuggestion.start) + + selectedSuggestion.text + + value.substr(selectedSuggestion.end); + + this.setState(withSuggestionsHidden); + this.changeValue(newValue); + this.focusInputElement(); + }; + + private changeValue = (value: string) => { + const { onChange } = this.props; + + if (onChange) { + onChange(value); + } + }; + + private focusInputElement = () => { + if (this.inputElement) { + this.inputElement.focus(); + } + }; + + private showSuggestions = () => { + this.setState(withSuggestionsVisible); + }; + + private submit = () => { + const { isValid, onSubmit, value } = this.props; + + if (isValid && onSubmit) { + onSubmit(value); + } + + this.setState(withSuggestionsHidden); + }; + + private updateSuggestions = () => { + const inputCursorPosition = this.inputElement ? this.inputElement.selectionStart || 0 : 0; + this.props.loadSuggestions(this.props.value, inputCursorPosition, 200); + }; +} + +const withPreviousSuggestionSelected = ( + state: AutocompleteFieldState, + props: AutocompleteFieldProps +): AutocompleteFieldState => ({ + ...state, + selectedIndex: + props.suggestions.length === 0 + ? null + : state.selectedIndex !== null + ? (state.selectedIndex + props.suggestions.length - 1) % props.suggestions.length + : Math.max(props.suggestions.length - 1, 0), +}); + +const withNextSuggestionSelected = ( + state: AutocompleteFieldState, + props: AutocompleteFieldProps +): AutocompleteFieldState => ({ + ...state, + selectedIndex: + props.suggestions.length === 0 + ? null + : state.selectedIndex !== null + ? (state.selectedIndex + 1) % props.suggestions.length + : 0, +}); + +const withSuggestionAtIndexSelected = + (suggestionIndex: number) => + (state: AutocompleteFieldState, props: AutocompleteFieldProps): AutocompleteFieldState => ({ + ...state, + selectedIndex: + props.suggestions.length === 0 + ? null + : suggestionIndex >= 0 && suggestionIndex < props.suggestions.length + ? suggestionIndex + : 0, + }); + +const withSuggestionsVisible = (state: AutocompleteFieldState) => ({ + ...state, + areSuggestionsVisible: true, +}); + +const withSuggestionsHidden = (state: AutocompleteFieldState) => ({ + ...state, + areSuggestionsVisible: false, + selectedIndex: null, +}); + +const withFocused = (state: AutocompleteFieldState) => ({ + ...state, + isFocused: true, +}); + +const withUnfocused = (state: AutocompleteFieldState) => ({ + ...state, + isFocused: false, +}); + +const AutocompleteContainer = euiStyled.div` + position: relative; +`; + +const SuggestionsPanel = euiStyled(EuiPanel).attrs(() => ({ + paddingSize: 'none', + hasShadow: true, +}))` + position: absolute; + width: 100%; + margin-top: 2px; + overflow-x: hidden; + overflow-y: scroll; + z-index: ${(props) => props.theme.eui.euiZLevel1}; + max-height: 322px; +`; diff --git a/x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx b/x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx new file mode 100644 index 0000000000000..ca0a8122772f3 --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/kuery_bar/index.tsx @@ -0,0 +1,98 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; + +import React, { useEffect, useState } from 'react'; +import { WithKueryAutocompletion } from './with_kuery_autocompletion'; +import { AutocompleteField } from './autocomplete_field'; +import { esKuery, IIndexPattern, QuerySuggestion } from '../../../../../../src/plugins/data/public'; + +type LoadSuggestionsFn = ( + e: string, + p: number, + m?: number, + transform?: (s: QuerySuggestion[]) => QuerySuggestion[] +) => void; +export type CurryLoadSuggestionsType = (loadSuggestions: LoadSuggestionsFn) => LoadSuggestionsFn; + +interface Props { + derivedIndexPattern: IIndexPattern; + onSubmit: (query: string) => void; + onChange?: (query: string) => void; + value?: string | null; + placeholder?: string; + curryLoadSuggestions?: CurryLoadSuggestionsType; +} + +function validateQuery(query: string) { + try { + esKuery.fromKueryExpression(query); + } catch (err) { + return false; + } + return true; +} + +export const KueryBar = ({ + derivedIndexPattern, + onSubmit, + onChange, + value, + placeholder, + curryLoadSuggestions = defaultCurryLoadSuggestions, +}: Props) => { + const [draftQuery, setDraftQuery] = useState(value || ''); + const [isValid, setValidation] = useState(true); + + // This ensures that if value changes out side this component it will update. + useEffect(() => { + if (value) { + setDraftQuery(value); + } + }, [value]); + + const handleChange = (query: string) => { + setValidation(validateQuery(query)); + setDraftQuery(query); + if (onChange) { + onChange(query); + } + }; + + const filteredDerivedIndexPattern = { + ...derivedIndexPattern, + fields: derivedIndexPattern.fields, + }; + + const defaultPlaceholder = i18n.translate('xpack.monitoring.alerts.kqlSearchFieldPlaceholder', { + defaultMessage: 'Search for monitoring data', + }); + + return ( + + {({ isLoadingSuggestions, loadSuggestions, suggestions }) => ( + + )} + + ); +}; + +const defaultCurryLoadSuggestions: CurryLoadSuggestionsType = + (loadSuggestions) => + (...args) => + loadSuggestions(...args); diff --git a/x-pack/plugins/monitoring/public/components/kuery_bar/suggestion_item.tsx b/x-pack/plugins/monitoring/public/components/kuery_bar/suggestion_item.tsx new file mode 100644 index 0000000000000..3681bf26987cc --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/kuery_bar/suggestion_item.tsx @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { EuiIcon } from '@elastic/eui'; +import { transparentize } from 'polished'; +import React from 'react'; +import { euiStyled } from '../../../../../../src/plugins/kibana_react/common'; +import { QuerySuggestion, QuerySuggestionTypes } from '../../../../../../src/plugins/data/public'; + +interface Props { + isSelected?: boolean; + onClick?: React.MouseEventHandler; + onMouseEnter?: React.MouseEventHandler; + suggestion: QuerySuggestion; +} + +export const SuggestionItem: React.FC = (props) => { + const { isSelected, onClick, onMouseEnter, suggestion } = props; + + return ( + + + + + {suggestion.text} + {suggestion.description} + + ); +}; + +SuggestionItem.defaultProps = { + isSelected: false, +}; + +const SuggestionItemContainer = euiStyled.div<{ + isSelected?: boolean; +}>` + display: flex; + flex-direction: row; + font-size: ${(props) => props.theme.eui.euiFontSizeS}; + height: ${(props) => props.theme.eui.euiSizeXL}; + white-space: nowrap; + background-color: ${(props) => + props.isSelected ? props.theme.eui.euiColorLightestShade : 'transparent'}; +`; + +const SuggestionItemField = euiStyled.div` + align-items: center; + cursor: pointer; + display: flex; + flex-direction: row; + height: ${(props) => props.theme.eui.euiSizeXL}; + padding: ${(props) => props.theme.eui.euiSizeXS}; +`; + +const SuggestionItemIconField = euiStyled(SuggestionItemField)<{ + suggestionType: QuerySuggestionTypes; +}>` + background-color: ${(props) => + transparentize(0.9, getEuiIconColor(props.theme, props.suggestionType))}; + color: ${(props) => getEuiIconColor(props.theme, props.suggestionType)}; + flex: 0 0 auto; + justify-content: center; + width: ${(props) => props.theme.eui.euiSizeXL}; +`; + +const SuggestionItemTextField = euiStyled(SuggestionItemField)` + flex: 2 0 0; + font-family: ${(props) => props.theme.eui.euiCodeFontFamily}; +`; + +const SuggestionItemDescriptionField = euiStyled(SuggestionItemField)` + flex: 3 0 0; + + p { + display: inline; + + span { + font-family: ${(props) => props.theme.eui.euiCodeFontFamily}; + } + } +`; + +const getEuiIconType = (suggestionType: QuerySuggestionTypes) => { + switch (suggestionType) { + case QuerySuggestionTypes.Field: + return 'kqlField'; + case QuerySuggestionTypes.Value: + return 'kqlValue'; + case QuerySuggestionTypes.RecentSearch: + return 'search'; + case QuerySuggestionTypes.Conjunction: + return 'kqlSelector'; + case QuerySuggestionTypes.Operator: + return 'kqlOperand'; + default: + return 'empty'; + } +}; + +const getEuiIconColor = (theme: any, suggestionType: QuerySuggestionTypes): string => { + switch (suggestionType) { + case QuerySuggestionTypes.Field: + return theme?.eui.euiColorVis7; + case QuerySuggestionTypes.Value: + return theme?.eui.euiColorVis0; + case QuerySuggestionTypes.Operator: + return theme?.eui.euiColorVis1; + case QuerySuggestionTypes.Conjunction: + return theme?.eui.euiColorVis2; + case QuerySuggestionTypes.RecentSearch: + default: + return theme?.eui.euiColorMediumShade; + } +}; diff --git a/x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx b/x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx new file mode 100644 index 0000000000000..8d79bf4039846 --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/kuery_bar/with_kuery_autocompletion.tsx @@ -0,0 +1,111 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import { QuerySuggestion, IIndexPattern, DataPublicPluginStart } from 'src/plugins/data/public'; +import { + withKibana, + KibanaReactContextValue, + KibanaServices, +} from '../../../../../../src/plugins/kibana_react/public'; +import { RendererFunction } from '../../lib/typed_react'; + +interface WithKueryAutocompletionLifecycleProps { + kibana: KibanaReactContextValue<{ data: DataPublicPluginStart } & KibanaServices>; + children: RendererFunction<{ + isLoadingSuggestions: boolean; + loadSuggestions: (expression: string, cursorPosition: number, maxSuggestions?: number) => void; + suggestions: QuerySuggestion[]; + }>; + indexPattern: IIndexPattern; +} + +interface WithKueryAutocompletionLifecycleState { + // lacking cancellation support in the autocompletion api, + // this is used to keep older, slower requests from clobbering newer ones + currentRequest: { + expression: string; + cursorPosition: number; + } | null; + suggestions: QuerySuggestion[]; +} + +class WithKueryAutocompletionComponent extends React.Component< + WithKueryAutocompletionLifecycleProps, + WithKueryAutocompletionLifecycleState +> { + public readonly state: WithKueryAutocompletionLifecycleState = { + currentRequest: null, + suggestions: [], + }; + + public render() { + const { currentRequest, suggestions } = this.state; + + return this.props.children({ + isLoadingSuggestions: currentRequest !== null, + loadSuggestions: this.loadSuggestions, + suggestions, + }); + } + + private loadSuggestions = async ( + expression: string, + cursorPosition: number, + maxSuggestions?: number, + transformSuggestions?: (s: QuerySuggestion[]) => QuerySuggestion[] + ) => { + const { indexPattern } = this.props; + const language = 'kuery'; + const hasQuerySuggestions = + this.props.kibana.services.data?.autocomplete.hasQuerySuggestions(language); + + if (!hasQuerySuggestions) { + return; + } + + this.setState({ + currentRequest: { + expression, + cursorPosition, + }, + suggestions: [], + }); + + const suggestions = + (await this.props.kibana.services.data.autocomplete.getQuerySuggestions({ + language, + query: expression, + selectionStart: cursorPosition, + selectionEnd: cursorPosition, + indexPatterns: [indexPattern], + boolFilter: [], + })) || []; + + const transformedSuggestions = transformSuggestions + ? transformSuggestions(suggestions) + : suggestions; + + this.setState((state) => + state.currentRequest && + state.currentRequest.expression !== expression && + state.currentRequest.cursorPosition !== cursorPosition + ? state // ignore this result, since a newer request is in flight + : { + ...state, + currentRequest: null, + suggestions: maxSuggestions + ? transformedSuggestions.slice(0, maxSuggestions) + : transformedSuggestions, + } + ); + }; +} + +export const WithKueryAutocompletion = withKibana( + WithKueryAutocompletionComponent +); diff --git a/x-pack/plugins/monitoring/public/lib/kuery.ts b/x-pack/plugins/monitoring/public/lib/kuery.ts new file mode 100644 index 0000000000000..19706d7664c22 --- /dev/null +++ b/x-pack/plugins/monitoring/public/lib/kuery.ts @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { esKuery, IIndexPattern } from '../../../../../src/plugins/data/public'; + +export const convertKueryToElasticSearchQuery = ( + kueryExpression: string, + indexPattern: IIndexPattern +) => { + try { + return kueryExpression + ? JSON.stringify( + esKuery.toElasticsearchQuery(esKuery.fromKueryExpression(kueryExpression), indexPattern) + ) + : ''; + } catch (err) { + return ''; + } +}; diff --git a/x-pack/plugins/monitoring/public/lib/typed_react.tsx b/x-pack/plugins/monitoring/public/lib/typed_react.tsx new file mode 100644 index 0000000000000..b5b7a440c117c --- /dev/null +++ b/x-pack/plugins/monitoring/public/lib/typed_react.tsx @@ -0,0 +1,82 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { omit } from 'lodash'; +import React from 'react'; +import { InferableComponentEnhancerWithProps, ConnectedComponent } from 'react-redux'; + +export type RendererResult = React.ReactElement | null; +export type RendererFunction = (args: RenderArgs) => Result; + +export type ChildFunctionRendererProps = { + children: RendererFunction; + initializeOnMount?: boolean; + resetOnUnmount?: boolean; +} & RenderArgs; + +interface ChildFunctionRendererOptions { + onInitialize?: (props: RenderArgs) => void; + onCleanup?: (props: RenderArgs) => void; +} + +export const asChildFunctionRenderer = ( + hoc: InferableComponentEnhancerWithProps, + { onInitialize, onCleanup }: ChildFunctionRendererOptions = {} +): ConnectedComponent< + React.ComponentClass<{}>, + { + children: RendererFunction; + initializeOnMount?: boolean; + resetOnUnmount?: boolean; + } & OwnProps +> => + hoc( + class ChildFunctionRenderer extends React.Component> { + public displayName = 'ChildFunctionRenderer'; + + public componentDidMount() { + if (this.props.initializeOnMount && onInitialize) { + onInitialize(this.getRendererArgs()); + } + } + + public componentWillUnmount() { + if (this.props.resetOnUnmount && onCleanup) { + onCleanup(this.getRendererArgs()); + } + } + + public render() { + return (this.props.children as ChildFunctionRendererProps['children'])( + this.getRendererArgs() + ); + } + + private getRendererArgs = () => + omit(this.props, ['children', 'initializeOnMount', 'resetOnUnmount']) as Pick< + ChildFunctionRendererProps, + keyof InjectedProps + >; + } as any + ); + +export type StateUpdater = ( + prevState: Readonly, + prevProps: Readonly +) => State | null; + +export type PropsOfContainer = Container extends InferableComponentEnhancerWithProps< + infer InjectedProps, + any +> + ? InjectedProps + : never; + +export function composeStateUpdaters(...updaters: Array>) { + return (state: State, props: Props) => + updaters.reduce((currentState, updater) => updater(currentState, props) || currentState, state); +} diff --git a/x-pack/plugins/monitoring/public/plugin.ts b/x-pack/plugins/monitoring/public/plugin.ts index ad71cdbeb106c..aee5072947531 100644 --- a/x-pack/plugins/monitoring/public/plugin.ts +++ b/x-pack/plugins/monitoring/public/plugin.ts @@ -28,14 +28,6 @@ import { RULE_THREAD_POOL_WRITE_REJECTIONS, RULE_DETAILS, } from '../common/constants'; -import { createCpuUsageAlertType } from './alerts/cpu_usage_alert'; -import { createMissingMonitoringDataAlertType } from './alerts/missing_monitoring_data_alert'; -import { createLegacyAlertTypes } from './alerts/legacy_alert'; -import { createDiskUsageAlertType } from './alerts/disk_usage_alert'; -import { createThreadPoolRejectionsAlertType } from './alerts/thread_pool_rejections_alert'; -import { createMemoryUsageAlertType } from './alerts/memory_usage_alert'; -import { createCCRReadExceptionsAlertType } from './alerts/ccr_read_exceptions_alert'; -import { createLargeShardSizeAlertType } from './alerts/large_shard_size_alert'; import { setConfig } from './external_config'; interface MonitoringSetupPluginDependencies { @@ -49,11 +41,11 @@ const HASH_CHANGE = 'hashchange'; export class MonitoringPlugin implements - Plugin + Plugin { constructor(private initializerContext: PluginInitializerContext) {} - public setup( + public async setup( core: CoreSetup, plugins: MonitoringSetupPluginDependencies ) { @@ -86,7 +78,7 @@ export class MonitoringPlugin }); } - this.registerAlerts(plugins); + await this.registerAlerts(plugins, monitoring); const app: App = { id, @@ -152,7 +144,6 @@ export class MonitoringPlugin }; core.application.register(app); - return true; } public start(core: CoreStart, plugins: any) {} @@ -192,29 +183,48 @@ export class MonitoringPlugin ]; } - private registerAlerts(plugins: MonitoringSetupPluginDependencies) { + private async registerAlerts( + plugins: MonitoringSetupPluginDependencies, + config: MonitoringConfig + ) { const { triggersActionsUi: { ruleTypeRegistry }, } = plugins; - ruleTypeRegistry.register(createCpuUsageAlertType()); - ruleTypeRegistry.register(createDiskUsageAlertType()); - ruleTypeRegistry.register(createMemoryUsageAlertType()); + + const { createCpuUsageAlertType } = await import('./alerts/cpu_usage_alert'); + const { createMissingMonitoringDataAlertType } = await import( + './alerts/missing_monitoring_data_alert' + ); + const { createLegacyAlertTypes } = await import('./alerts/legacy_alert'); + const { createDiskUsageAlertType } = await import('./alerts/disk_usage_alert'); + const { createThreadPoolRejectionsAlertType } = await import( + './alerts/thread_pool_rejections_alert' + ); + const { createMemoryUsageAlertType } = await import('./alerts/memory_usage_alert'); + const { createCCRReadExceptionsAlertType } = await import('./alerts/ccr_read_exceptions_alert'); + const { createLargeShardSizeAlertType } = await import('./alerts/large_shard_size_alert'); + + ruleTypeRegistry.register(createCpuUsageAlertType(config)); + ruleTypeRegistry.register(createDiskUsageAlertType(config)); + ruleTypeRegistry.register(createMemoryUsageAlertType(config)); ruleTypeRegistry.register(createMissingMonitoringDataAlertType()); ruleTypeRegistry.register( createThreadPoolRejectionsAlertType( RULE_THREAD_POOL_SEARCH_REJECTIONS, - RULE_DETAILS[RULE_THREAD_POOL_SEARCH_REJECTIONS] + RULE_DETAILS[RULE_THREAD_POOL_SEARCH_REJECTIONS], + config ) ); ruleTypeRegistry.register( createThreadPoolRejectionsAlertType( RULE_THREAD_POOL_WRITE_REJECTIONS, - RULE_DETAILS[RULE_THREAD_POOL_WRITE_REJECTIONS] + RULE_DETAILS[RULE_THREAD_POOL_WRITE_REJECTIONS], + config ) ); - ruleTypeRegistry.register(createCCRReadExceptionsAlertType()); - ruleTypeRegistry.register(createLargeShardSizeAlertType()); - const legacyAlertTypes = createLegacyAlertTypes(); + ruleTypeRegistry.register(createCCRReadExceptionsAlertType(config)); + ruleTypeRegistry.register(createLargeShardSizeAlertType(config)); + const legacyAlertTypes = createLegacyAlertTypes(config); for (const legacyAlertType of legacyAlertTypes) { ruleTypeRegistry.register(legacyAlertType); } diff --git a/x-pack/plugins/monitoring/server/alerts/ccr_read_exceptions_rule.ts b/x-pack/plugins/monitoring/server/alerts/ccr_read_exceptions_rule.ts index 3a50aca7d4b84..e3a3537ea2eaf 100644 --- a/x-pack/plugins/monitoring/server/alerts/ccr_read_exceptions_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/ccr_read_exceptions_rule.ts @@ -88,7 +88,8 @@ export class CCRReadExceptionsRule extends BaseRule { esIndexPattern, startMs, endMs, - Globals.app.config.ui.max_bucket_size + Globals.app.config.ui.max_bucket_size, + params.filterQuery ); return stats.map((stat) => { @@ -278,7 +279,7 @@ export class CCRReadExceptionsRule extends BaseRule { state: AlertingDefaults.ALERT_STATE.firing, remoteCluster, followerIndex, - /* continue to send "remoteClusters" and "followerIndices" values for users still using it though + /* continue to send "remoteClusters" and "followerIndices" values for users still using it though we have replaced it with "remoteCluster" and "followerIndex" in the template due to alerts per index instead of all indices see https://github.com/elastic/kibana/issues/100136#issuecomment-865229431 */ diff --git a/x-pack/plugins/monitoring/server/alerts/cluster_health_rule.ts b/x-pack/plugins/monitoring/server/alerts/cluster_health_rule.ts index 7fac3b74a1b66..b9b9b90845eea 100644 --- a/x-pack/plugins/monitoring/server/alerts/cluster_health_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/cluster_health_rule.ts @@ -73,7 +73,12 @@ export class ClusterHealthRule extends BaseRule { if (availableCcs) { esIndexPattern = getCcsIndexPattern(esIndexPattern, availableCcs); } - const healths = await fetchClusterHealth(esClient, clusters, esIndexPattern); + const healths = await fetchClusterHealth( + esClient, + clusters, + esIndexPattern, + params.filterQuery + ); return healths.map((clusterHealth) => { const shouldFire = clusterHealth.health !== AlertClusterHealthType.Green; const severity = diff --git a/x-pack/plugins/monitoring/server/alerts/cpu_usage_rule.ts b/x-pack/plugins/monitoring/server/alerts/cpu_usage_rule.ts index 2e57a3c22de1b..7e38efcb819ea 100644 --- a/x-pack/plugins/monitoring/server/alerts/cpu_usage_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/cpu_usage_rule.ts @@ -76,7 +76,8 @@ export class CpuUsageRule extends BaseRule { esIndexPattern, startMs, endMs, - Globals.app.config.ui.max_bucket_size + Globals.app.config.ui.max_bucket_size, + params.filterQuery ); return stats.map((stat) => { if (Globals.app.config.ui.container.elasticsearch.enabled) { @@ -203,7 +204,7 @@ export class CpuUsageRule extends BaseRule { internalShortMessage, internalFullMessage: Globals.app.isCloud ? internalShortMessage : internalFullMessage, state: AlertingDefaults.ALERT_STATE.firing, - /* continue to send "nodes" and "count" values for users before https://github.com/elastic/kibana/pull/102544 + /* continue to send "nodes" and "count" values for users before https://github.com/elastic/kibana/pull/102544 see https://github.com/elastic/kibana/issues/100136#issuecomment-865229431 */ nodes: `${firingNode.nodeName}:${firingNode.cpuUsage}`, diff --git a/x-pack/plugins/monitoring/server/alerts/disk_usage_rule.ts b/x-pack/plugins/monitoring/server/alerts/disk_usage_rule.ts index ae3025c1db92c..bac70baebb4e2 100644 --- a/x-pack/plugins/monitoring/server/alerts/disk_usage_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/disk_usage_rule.ts @@ -72,7 +72,8 @@ export class DiskUsageRule extends BaseRule { clusters, esIndexPattern, duration as string, - Globals.app.config.ui.max_bucket_size + Globals.app.config.ui.max_bucket_size, + params.filterQuery ); return stats.map((stat) => { @@ -212,7 +213,7 @@ export class DiskUsageRule extends BaseRule { internalShortMessage, internalFullMessage: Globals.app.isCloud ? internalShortMessage : internalFullMessage, state: AlertingDefaults.ALERT_STATE.firing, - /* continue to send "nodes" and "count" values for users before https://github.com/elastic/kibana/pull/102544 + /* continue to send "nodes" and "count" values for users before https://github.com/elastic/kibana/pull/102544 see https://github.com/elastic/kibana/issues/100136#issuecomment-865229431 */ nodes: `${firingNode.nodeName}:${firingNode.diskUsage}`, diff --git a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_rule.ts b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_rule.ts index 6a5abcb4975f4..352cac531f8e8 100644 --- a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_rule.ts @@ -66,7 +66,8 @@ export class ElasticsearchVersionMismatchRule extends BaseRule { esClient, clusters, esIndexPattern, - Globals.app.config.ui.max_bucket_size + Globals.app.config.ui.max_bucket_size, + params.filterQuery ); return elasticsearchVersions.map((elasticsearchVersion) => { diff --git a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_rule.ts b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_rule.ts index 90275ea4d23a8..6d9410ed0e5a0 100644 --- a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_rule.ts @@ -79,7 +79,8 @@ export class KibanaVersionMismatchRule extends BaseRule { esClient, clusters, kibanaIndexPattern, - Globals.app.config.ui.max_bucket_size + Globals.app.config.ui.max_bucket_size, + params.filterQuery ); return kibanaVersions.map((kibanaVersion) => { diff --git a/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.ts b/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.ts index 86f96daa3b21d..b0370a23159d7 100644 --- a/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.ts @@ -75,7 +75,8 @@ export class LargeShardSizeRule extends BaseRule { esIndexPattern, threshold!, shardIndexPatterns, - Globals.app.config.ui.max_bucket_size + Globals.app.config.ui.max_bucket_size, + params.filterQuery ); return stats.map((stat) => { @@ -211,7 +212,7 @@ export class LargeShardSizeRule extends BaseRule { internalShortMessage, internalFullMessage, state: AlertingDefaults.ALERT_STATE.firing, - /* continue to send "shardIndices" values for users still using it though + /* continue to send "shardIndices" values for users still using it though we have replaced it with shardIndex in the template due to alerts per index instead of all indices see https://github.com/elastic/kibana/issues/100136#issuecomment-865229431 */ diff --git a/x-pack/plugins/monitoring/server/alerts/license_expiration_rule.ts b/x-pack/plugins/monitoring/server/alerts/license_expiration_rule.ts index 67ea8bd57b491..c26929b05ab26 100644 --- a/x-pack/plugins/monitoring/server/alerts/license_expiration_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/license_expiration_rule.ts @@ -87,7 +87,7 @@ export class LicenseExpirationRule extends BaseRule { if (availableCcs) { esIndexPattern = getCcsIndexPattern(esIndexPattern, availableCcs); } - const licenses = await fetchLicenses(esClient, clusters, esIndexPattern); + const licenses = await fetchLicenses(esClient, clusters, esIndexPattern, params.filterQuery); return licenses.map((license) => { const { clusterUuid, type, expiryDateMS, status, ccs } = license; diff --git a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_rule.ts b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_rule.ts index 0f9ad4dd4b117..e59ed9efbefb2 100644 --- a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_rule.ts @@ -66,7 +66,8 @@ export class LogstashVersionMismatchRule extends BaseRule { esClient, clusters, logstashIndexPattern, - Globals.app.config.ui.max_bucket_size + Globals.app.config.ui.max_bucket_size, + params.filterQuery ); return logstashVersions.map((logstashVersion) => { diff --git a/x-pack/plugins/monitoring/server/alerts/memory_usage_rule.ts b/x-pack/plugins/monitoring/server/alerts/memory_usage_rule.ts index 384610e659d47..d94e1234ce813 100644 --- a/x-pack/plugins/monitoring/server/alerts/memory_usage_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/memory_usage_rule.ts @@ -82,7 +82,8 @@ export class MemoryUsageRule extends BaseRule { esIndexPattern, startMs, endMs, - Globals.app.config.ui.max_bucket_size + Globals.app.config.ui.max_bucket_size, + params.filterQuery ); return stats.map((stat) => { @@ -223,7 +224,7 @@ export class MemoryUsageRule extends BaseRule { internalShortMessage, internalFullMessage: Globals.app.isCloud ? internalShortMessage : internalFullMessage, state: AlertingDefaults.ALERT_STATE.firing, - /* continue to send "nodes" and "count" values for users before https://github.com/elastic/kibana/pull/102544 + /* continue to send "nodes" and "count" values for users before https://github.com/elastic/kibana/pull/102544 see https://github.com/elastic/kibana/issues/100136#issuecomment-865229431 */ nodes: `${firingNode.nodeName}:${firingNode.memoryUsage.toFixed(2)}`, diff --git a/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_rule.ts b/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_rule.ts index 32e4ff738c71b..1b45b19fe89f8 100644 --- a/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_rule.ts @@ -75,7 +75,8 @@ export class MissingMonitoringDataRule extends BaseRule { indexPattern, Globals.app.config.ui.max_bucket_size, now, - now - limit - LIMIT_BUFFER + now - limit - LIMIT_BUFFER, + params.filterQuery ); return missingData.map((missing) => { return { @@ -198,7 +199,7 @@ export class MissingMonitoringDataRule extends BaseRule { internalShortMessage, internalFullMessage: Globals.app.isCloud ? internalShortMessage : internalFullMessage, state: AlertingDefaults.ALERT_STATE.firing, - /* continue to send "nodes" and "count" values for users before https://github.com/elastic/kibana/pull/102544 + /* continue to send "nodes" and "count" values for users before https://github.com/elastic/kibana/pull/102544 see https://github.com/elastic/kibana/issues/100136#issuecomment-865229431 */ nodes: `node: ${firingNode.nodeName}`, diff --git a/x-pack/plugins/monitoring/server/alerts/nodes_changed_rule.ts b/x-pack/plugins/monitoring/server/alerts/nodes_changed_rule.ts index 90bd70f32c8cb..6645466f30c73 100644 --- a/x-pack/plugins/monitoring/server/alerts/nodes_changed_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/nodes_changed_rule.ts @@ -114,7 +114,8 @@ export class NodesChangedRule extends BaseRule { const nodesFromClusterStats = await fetchNodesFromClusterStats( esClient, clusters, - esIndexPattern + esIndexPattern, + params.filterQuery ); return nodesFromClusterStats.map((nodes) => { const { removed, added, restarted } = getNodeStates(nodes); diff --git a/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_rule_base.ts b/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_rule_base.ts index c478b2f687c02..678f8b429167f 100644 --- a/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_rule_base.ts +++ b/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_rule_base.ts @@ -86,7 +86,8 @@ export class ThreadPoolRejectionsRuleBase extends BaseRule { esIndexPattern, Globals.app.config.ui.max_bucket_size, this.threadPoolType, - duration + duration, + params.filterQuery ); return stats.map((stat) => { @@ -257,7 +258,7 @@ export class ThreadPoolRejectionsRuleBase extends BaseRule { internalFullMessage: Globals.app.isCloud ? internalShortMessage : internalFullMessage, threadPoolType: type, state: AlertingDefaults.ALERT_STATE.firing, - /* continue to send "count" value for users before https://github.com/elastic/kibana/pull/102544 + /* continue to send "count" value for users before https://github.com/elastic/kibana/pull/102544 see https://github.com/elastic/kibana/issues/100136#issuecomment-865229431 */ count: 1, diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.ts index 527ed503c8faf..0d3aab8283688 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_stack_product_usage.ts @@ -10,7 +10,7 @@ import { ElasticsearchClient } from 'src/core/server'; import { estypes } from '@elastic/elasticsearch'; import { MonitoringConfig } from '../../../config'; // @ts-ignore -import { prefixIndexPattern } from '../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../common/ccs_utils'; import { StackProductUsage } from '../types'; interface ESResponse { diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.ts index 7cce1b392112f..25a1892a9f38d 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.ts @@ -12,7 +12,7 @@ import { MonitoringConfig } from '../../../config'; // @ts-ignore import { getIndexPatterns } from '../../../lib/cluster/get_index_patterns'; // @ts-ignore -import { prefixIndexPattern } from '../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../common/ccs_utils'; import { INDEX_PATTERN_ELASTICSEARCH, INDEX_PATTERN_KIBANA, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.ts index 560751d1297d5..e7a5923207d60 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_ccr_read_exceptions.ts @@ -14,7 +14,8 @@ export async function fetchCCRReadExceptions( index: string, startMs: number, endMs: number, - size: number + size: number, + filterQuery?: string ): Promise { const params = { index, @@ -93,6 +94,15 @@ export async function fetchCCRReadExceptions( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); const stats: CCRReadExceptionsStats[] = []; // @ts-expect-error declare aggegations type explicitly diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.ts index 85bfbd9dbd049..b2004f0c7c710 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cluster_health.ts @@ -11,7 +11,8 @@ import { ElasticsearchSource, ElasticsearchResponse } from '../../../common/type export async function fetchClusterHealth( esClient: ElasticsearchClient, clusters: AlertCluster[], - index: string + index: string, + filterQuery?: string ): Promise { const params = { index, @@ -59,6 +60,15 @@ export async function fetchClusterHealth( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const result = await esClient.search(params); const response: ElasticsearchResponse = result.body as ElasticsearchResponse; return (response.hits?.hits ?? []).map((hit) => { diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.test.ts index 90cd456f18037..8f0083f1f533f 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.test.ts @@ -201,7 +201,9 @@ describe('fetchCpuUsageNodeStats', () => { {} as estypes.SearchResponse ); }); - await fetchCpuUsageNodeStats(esClient, clusters, index, startMs, endMs, size); + const filterQuery = + '{"bool":{"should":[{"exists":{"field":"cluster_uuid"}}],"minimum_should_match":1}}'; + await fetchCpuUsageNodeStats(esClient, clusters, index, startMs, endMs, size, filterQuery); expect(params).toStrictEqual({ index: '.monitoring-es-*', filter_path: ['aggregations'], @@ -213,6 +215,9 @@ describe('fetchCpuUsageNodeStats', () => { { terms: { cluster_uuid: ['abc123'] } }, { term: { type: 'node_stats' } }, { range: { timestamp: { format: 'epoch_millis', gte: 0, lte: 0 } } }, + { + bool: { should: [{ exists: { field: 'cluster_uuid' } }], minimum_should_match: 1 }, + }, ], }, }, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts index 6f7d27916a7b1..2ad42870e9958 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_cpu_usage_node_stats.ts @@ -29,7 +29,8 @@ export async function fetchCpuUsageNodeStats( index: string, startMs: number, endMs: number, - size: number + size: number, + filterQuery?: string ): Promise { // Using pure MS didn't seem to work well with the date_histogram interval // but minutes does @@ -140,6 +141,15 @@ export async function fetchCpuUsageNodeStats( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); const stats: AlertCpuUsageNodeStats[] = []; const clusterBuckets = get( diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts index 70f05991d4229..2d4872c0bd895 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts @@ -14,7 +14,8 @@ export async function fetchDiskUsageNodeStats( clusters: AlertCluster[], index: string, duration: string, - size: number + size: number, + filterQuery?: string ): Promise { const clustersIds = clusters.map((cluster) => cluster.clusterUuid); const params = { @@ -99,6 +100,15 @@ export async function fetchDiskUsageNodeStats( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); const stats: AlertDiskUsageNodeStats[] = []; // @ts-expect-error declare type for aggregations explicitly diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.ts index f2f311ac870a5..6ca2e89048df9 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_elasticsearch_versions.ts @@ -12,7 +12,8 @@ export async function fetchElasticsearchVersions( esClient: ElasticsearchClient, clusters: AlertCluster[], index: string, - size: number + size: number, + filterQuery?: string ): Promise { const params = { index, @@ -60,6 +61,15 @@ export async function fetchElasticsearchVersions( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const result = await esClient.search(params); const response: ElasticsearchResponse = result.body as ElasticsearchResponse; return (response.hits?.hits ?? []).map((hit) => { diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts index 7e7ea5e6bfdd2..98bb546b43ab9 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_index_shard_size.ts @@ -35,7 +35,8 @@ export async function fetchIndexShardSize( index: string, threshold: number, shardIndexPatterns: string, - size: number + size: number, + filterQuery?: string ): Promise { const params = { index, @@ -104,6 +105,15 @@ export async function fetchIndexShardSize( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.must.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); // @ts-expect-error declare aggegations type explicitly const { buckets: clusterBuckets } = response.aggregations?.clusters; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.ts index e57b45e2570fa..71813f3a526de 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_kibana_versions.ts @@ -16,7 +16,8 @@ export async function fetchKibanaVersions( esClient: ElasticsearchClient, clusters: AlertCluster[], index: string, - size: number + size: number, + filterQuery?: string ): Promise { const params = { index, @@ -89,6 +90,15 @@ export async function fetchKibanaVersions( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); const indexName = get(response, 'aggregations.index.buckets[0].key', ''); const clusterList = get(response, 'aggregations.cluster.buckets', []) as ESAggResponse[]; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts index 38ff82cf29832..b7bdf2fb6be72 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_licenses.ts @@ -11,7 +11,8 @@ import { ElasticsearchSource } from '../../../common/types/es'; export async function fetchLicenses( esClient: ElasticsearchClient, clusters: AlertCluster[], - index: string + index: string, + filterQuery?: string ): Promise { const params = { index, @@ -59,6 +60,15 @@ export async function fetchLicenses( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); return ( response?.hits?.hits.map((hit) => { diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.ts index 774ee2551ec07..112c2fe798b10 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_logstash_versions.ts @@ -16,7 +16,8 @@ export async function fetchLogstashVersions( esClient: ElasticsearchClient, clusters: AlertCluster[], index: string, - size: number + size: number, + filterQuery?: string ): Promise { const params = { index, @@ -89,6 +90,15 @@ export async function fetchLogstashVersions( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); const indexName = get(response, 'aggregations.index.buckets[0].key', ''); const clusterList = get(response, 'aggregations.cluster.buckets', []) as ESAggResponse[]; diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts index f34a8dcff1db7..9403ae5d79a70 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_memory_usage_node_stats.ts @@ -15,7 +15,8 @@ export async function fetchMemoryUsageNodeStats( index: string, startMs: number, endMs: number, - size: number + size: number, + filterQuery?: string ): Promise { const clustersIds = clusters.map((cluster) => cluster.clusterUuid); const params = { @@ -92,6 +93,15 @@ export async function fetchMemoryUsageNodeStats( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); const stats: AlertMemoryUsageNodeStats[] = []; // @ts-expect-error declare type for aggregations explicitly diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts index 856ca7c919885..cdf0f21b52b09 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_missing_monitoring_data.ts @@ -47,7 +47,8 @@ export async function fetchMissingMonitoringData( index: string, size: number, nowInMs: number, - startMs: number + startMs: number, + filterQuery?: string ): Promise { const endMs = nowInMs; const params = { @@ -117,6 +118,15 @@ export async function fetchMissingMonitoringData( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); const clusterBuckets = get( response, diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.ts index dcc8e6516c69b..3dc3e315318fc 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_nodes_from_cluster_stats.ts @@ -26,7 +26,8 @@ function formatNode( export async function fetchNodesFromClusterStats( esClient: ElasticsearchClient, clusters: AlertCluster[], - index: string + index: string, + filterQuery?: string ): Promise { const params = { index, @@ -88,6 +89,15 @@ export async function fetchNodesFromClusterStats( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); const nodes: AlertClusterStatsNodes[] = []; // @ts-expect-error declare type for aggregations explicitly diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts index 132f7692a7579..0d1d052b5f866 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_thread_pool_rejections_stats.ts @@ -36,7 +36,8 @@ export async function fetchThreadPoolRejectionStats( index: string, size: number, threadType: string, - duration: string + duration: string, + filterQuery?: string ): Promise { const clustersIds = clusters.map((cluster) => cluster.clusterUuid); const params = { @@ -94,6 +95,15 @@ export async function fetchThreadPoolRejectionStats( }, }; + try { + if (filterQuery) { + const filterQueryObject = JSON.parse(filterQuery); + params.body.query.bool.filter.push(filterQueryObject); + } + } catch (e) { + // meh + } + const { body: response } = await esClient.search(params); const stats: AlertThreadPoolRejectionsStats[] = []; // @ts-expect-error declare type for aggregations explicitly diff --git a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_stats.ts b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_stats.ts index 6eb21165d7256..a2201ca958e35 100644 --- a/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_stats.ts +++ b/x-pack/plugins/monitoring/server/lib/cluster/get_clusters_stats.ts @@ -12,7 +12,7 @@ import { createQuery } from '../create_query'; // @ts-ignore import { ElasticsearchMetric } from '../metrics'; // @ts-ignore -import { parseCrossClusterPrefix } from '../ccs_utils'; +import { parseCrossClusterPrefix } from '../../../common/ccs_utils'; import { getClustersState } from './get_clusters_state'; import { ElasticsearchResponse, ElasticsearchModifiedSource } from '../../../common/types/es'; import { LegacyRequest } from '../../types'; diff --git a/x-pack/plugins/monitoring/server/lib/cluster/get_index_patterns.ts b/x-pack/plugins/monitoring/server/lib/cluster/get_index_patterns.ts index d908d6180772e..ccfe380edec09 100644 --- a/x-pack/plugins/monitoring/server/lib/cluster/get_index_patterns.ts +++ b/x-pack/plugins/monitoring/server/lib/cluster/get_index_patterns.ts @@ -6,7 +6,7 @@ */ import { LegacyServer } from '../../types'; -import { prefixIndexPattern } from '../ccs_utils'; +import { prefixIndexPattern } from '../../../common/ccs_utils'; import { INDEX_PATTERN_ELASTICSEARCH, INDEX_PATTERN_KIBANA, diff --git a/x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts b/x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts index c0fa931676870..727e47b62bc92 100644 --- a/x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts +++ b/x-pack/plugins/monitoring/server/lib/logs/init_infra_source.ts @@ -6,7 +6,7 @@ */ // @ts-ignore -import { prefixIndexPattern } from '../ccs_utils'; +import { prefixIndexPattern } from '../../../common/ccs_utils'; import { INFRA_SOURCE_ID } from '../../../common/constants'; import { MonitoringConfig } from '../../config'; import { InfraPluginSetup } from '../../../../infra/server'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.js b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.js index 4884b8151f61f..a0b00167101fe 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instance.js @@ -6,7 +6,7 @@ */ import { schema } from '@kbn/config-schema'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { metricSet } from './metric_set_instance'; import { handleError } from '../../../../lib/errors'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.js b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.js index 53afa4c3f01b4..95f378ff5b98d 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/instances.js @@ -6,7 +6,7 @@ */ import { schema } from '@kbn/config-schema'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { getStats, getApms } from '../../../../lib/apm'; import { handleError } from '../../../../lib/errors'; import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.js index 7a772594b4bc2..ea7f3f41b842e 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/apm/overview.js @@ -6,7 +6,7 @@ */ import { schema } from '@kbn/config-schema'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { metricSet } from './metric_set_overview'; import { handleError } from '../../../../lib/errors'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js index 919efe98f3df3..851380fede77d 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beat_detail.js @@ -6,7 +6,7 @@ */ import { schema } from '@kbn/config-schema'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { getBeatSummary } from '../../../../lib/beats'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { handleError } from '../../../../lib/errors'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js index 57b24e59e66ab..fa35ccb9371c2 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/beats.js @@ -6,7 +6,7 @@ */ import { schema } from '@kbn/config-schema'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { getStats, getBeats } from '../../../../lib/beats'; import { handleError } from '../../../../lib/errors'; import { INDEX_PATTERN_BEATS } from '../../../../../common/constants'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js index 5f1bb1778bc9a..4abf46b3ad1ce 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/beats/overview.js @@ -6,7 +6,7 @@ */ import { schema } from '@kbn/config-schema'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { getLatestStats, getStats } from '../../../../lib/beats'; import { handleError } from '../../../../lib/errors'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.ts index 73b646126ce98..898cfc82463d9 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr.ts @@ -11,7 +11,7 @@ import { get, groupBy } from 'lodash'; // @ts-ignore import { handleError } from '../../../../lib/errors/handle_error'; // @ts-ignore -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; import { ElasticsearchResponse, diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.ts index 5ecb84d97618b..d07a660222407 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ccr_shard.ts @@ -10,7 +10,7 @@ import { schema } from '@kbn/config-schema'; // @ts-ignore import { handleError } from '../../../../lib/errors/handle_error'; // @ts-ignore -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; // @ts-ignore import { getMetrics } from '../../../../lib/details/get_metrics'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js index 89ca911f44268..e99ae04ab282c 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/index_detail.js @@ -12,7 +12,7 @@ import { getIndexSummary } from '../../../../lib/elasticsearch/indices'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { getShardAllocation, getShardStats } from '../../../../lib/elasticsearch/shards'; import { handleError } from '../../../../lib/errors/handle_error'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { metricSet } from './metric_set_index_detail'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; import { getLogs } from '../../../../lib/logs/get_logs'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js index 8099ecf3462cc..76e769ac030ba 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/indices.js @@ -10,7 +10,7 @@ import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; import { getIndices } from '../../../../lib/elasticsearch/indices'; import { handleError } from '../../../../lib/errors/handle_error'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js index e23c23f7a819d..5853cc3d6ee9d 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/ml_jobs.js @@ -10,7 +10,7 @@ import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats'; import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; import { getMlJobs } from '../../../../lib/elasticsearch/get_ml_jobs'; import { handleError } from '../../../../lib/errors/handle_error'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js index 2122f8ceb2215..5f77d0394a4f1 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/node_detail.js @@ -12,7 +12,7 @@ import { getNodeSummary } from '../../../../lib/elasticsearch/nodes'; import { getShardStats, getShardAllocation } from '../../../../lib/elasticsearch/shards'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { handleError } from '../../../../lib/errors/handle_error'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { metricSets } from './metric_set_node_detail'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; import { getLogs } from '../../../../lib/logs/get_logs'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js index db12e28916b65..7ea2e6e1e1440 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/nodes.js @@ -11,7 +11,7 @@ import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; import { getNodes } from '../../../../lib/elasticsearch/nodes'; import { getNodesShardCount } from '../../../../lib/elasticsearch/shards/get_nodes_shard_count'; import { handleError } from '../../../../lib/errors/handle_error'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; import { getPaginatedNodes } from '../../../../lib/elasticsearch/nodes/get_nodes/get_paginated_nodes'; import { LISTING_METRICS_NAMES } from '../../../../lib/elasticsearch/nodes/get_nodes/nodes_listing_metrics'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js index c76513df721ba..a0fc524768eb9 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch/overview.js @@ -11,7 +11,7 @@ import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status'; import { getLastRecovery } from '../../../../lib/elasticsearch/get_last_recovery'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { handleError } from '../../../../lib/errors/handle_error'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { metricSet } from './metric_set_overview'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants'; import { getLogs } from '../../../../lib/logs'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts index d05d60866d119..3cd2b8b73b315 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/elasticsearch_settings/check/internal_monitoring.ts @@ -14,7 +14,7 @@ import { INDEX_PATTERN_LOGSTASH, } from '../../../../../../common/constants'; // @ts-ignore -import { prefixIndexPattern } from '../../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../../common/ccs_utils'; // @ts-ignore import { handleError } from '../../../../../lib/errors'; import { RouteDependencies, LegacyServer } from '../../../../../types'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instance.ts b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instance.ts index d16f568b475b4..613ca39275c2d 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instance.ts +++ b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instance.ts @@ -12,7 +12,7 @@ import { handleError } from '../../../../lib/errors'; // @ts-ignore import { getMetrics } from '../../../../lib/details/get_metrics'; // @ts-ignore -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; // @ts-ignore import { metricSet } from './metric_set_instance'; import { INDEX_PATTERN_KIBANA } from '../../../../../common/constants'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instances.js b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instances.js index 59618f0a217b5..f9b3498cd684e 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instances.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/instances.js @@ -6,7 +6,7 @@ */ import { schema } from '@kbn/config-schema'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { getKibanaClusterStatus } from './_get_kibana_cluster_status'; import { getKibanas } from '../../../../lib/kibana/get_kibanas'; import { handleError } from '../../../../lib/errors'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/overview.js index cca36d2aad1a7..f9a9443c3533b 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/kibana/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/kibana/overview.js @@ -6,7 +6,7 @@ */ import { schema } from '@kbn/config-schema'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { getKibanaClusterStatus } from './_get_kibana_cluster_status'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { metricSet } from './metric_set_overview'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/node.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/node.js index b81b4ea796c63..d3ecea95430ca 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/node.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/node.js @@ -9,7 +9,7 @@ import { schema } from '@kbn/config-schema'; import { getNodeInfo } from '../../../../lib/logstash/get_node_info'; import { handleError } from '../../../../lib/errors'; import { getMetrics } from '../../../../lib/details/get_metrics'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { metricSets } from './metric_set_node'; import { INDEX_PATTERN_LOGSTASH } from '../../../../../common/constants'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/nodes.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/nodes.js index 74b89ab41be92..051fb7d38fd41 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/nodes.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/nodes.js @@ -9,7 +9,7 @@ import { schema } from '@kbn/config-schema'; import { getClusterStatus } from '../../../../lib/logstash/get_cluster_status'; import { getNodes } from '../../../../lib/logstash/get_nodes'; import { handleError } from '../../../../lib/errors'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { INDEX_PATTERN_LOGSTASH } from '../../../../../common/constants'; /* diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/overview.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/overview.js index 23dd64a1afb74..89a6a93fb207d 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/overview.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/overview.js @@ -9,7 +9,7 @@ import { schema } from '@kbn/config-schema'; import { getClusterStatus } from '../../../../lib/logstash/get_cluster_status'; import { getMetrics } from '../../../../lib/details/get_metrics'; import { handleError } from '../../../../lib/errors'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { metricSet } from './metric_set_overview'; import { INDEX_PATTERN_LOGSTASH } from '../../../../../common/constants'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipeline.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipeline.js index 4243b2d6c3a5c..6b81059f0c256 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipeline.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipeline.js @@ -10,7 +10,7 @@ import { handleError } from '../../../../lib/errors'; import { getPipelineVersions } from '../../../../lib/logstash/get_pipeline_versions'; import { getPipeline } from '../../../../lib/logstash/get_pipeline'; import { getPipelineVertex } from '../../../../lib/logstash/get_pipeline_vertex'; -import { prefixIndexPattern } from '../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../common/ccs_utils'; import { INDEX_PATTERN_LOGSTASH } from '../../../../../common/constants'; function getPipelineVersion(versions, pipelineHash) { diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipeline_ids.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipeline_ids.js index c881ff7b3d23c..7f14b74da207d 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipeline_ids.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipeline_ids.js @@ -7,7 +7,7 @@ import { schema } from '@kbn/config-schema'; import { handleError } from '../../../../../lib/errors'; -import { prefixIndexPattern } from '../../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../../common/ccs_utils'; import { INDEX_PATTERN_LOGSTASH } from '../../../../../../common/constants'; import { getLogstashPipelineIds } from '../../../../../lib/logstash/get_pipeline_ids'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js index 1f7a5e1d436b1..b7d86e86e7a07 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/cluster_pipelines.js @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import { getClusterStatus } from '../../../../../lib/logstash/get_cluster_status'; import { handleError } from '../../../../../lib/errors'; -import { prefixIndexPattern } from '../../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../../common/ccs_utils'; import { INDEX_PATTERN_LOGSTASH } from '../../../../../../common/constants'; import { getPaginatedPipelines } from '../../../../../lib/logstash/get_paginated_pipelines'; diff --git a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/node_pipelines.js b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/node_pipelines.js index 47b8fd81a4d44..f31e88b5b8b08 100644 --- a/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/node_pipelines.js +++ b/x-pack/plugins/monitoring/server/routes/api/v1/logstash/pipelines/node_pipelines.js @@ -8,7 +8,7 @@ import { schema } from '@kbn/config-schema'; import { getNodeInfo } from '../../../../../lib/logstash/get_node_info'; import { handleError } from '../../../../../lib/errors'; -import { prefixIndexPattern } from '../../../../../lib/ccs_utils'; +import { prefixIndexPattern } from '../../../../../../common/ccs_utils'; import { INDEX_PATTERN_LOGSTASH } from '../../../../../../common/constants'; import { getPaginatedPipelines } from '../../../../../lib/logstash/get_paginated_pipelines'; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 8fd02c5dba865..09bee9e8acf8a 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -17602,7 +17602,6 @@ "xpack.monitoring.alerts.kibanaVersionMismatch.label": "Kibana バージョン不一致", "xpack.monitoring.alerts.kibanaVersionMismatch.shortAction": "すべてのインスタンスのバージョンが同じことを確認してください。", "xpack.monitoring.alerts.kibanaVersionMismatch.ui.firingMessage": "このクラスターでは、複数のバージョンの Kibana({versions})が実行されています。", - "xpack.monitoring.alerts.legacyAlert.expressionText": "構成するものがありません。", "xpack.monitoring.alerts.licenseExpiration.action": "ライセンスを更新してください。", "xpack.monitoring.alerts.licenseExpiration.actionVariables.clusterName": "ライセンスが属しているクラスター。", "xpack.monitoring.alerts.licenseExpiration.actionVariables.expiredDate": "ライセンスの有効期限。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index bd1224a8fd057..70116bab479c3 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -17877,7 +17877,6 @@ "xpack.monitoring.alerts.kibanaVersionMismatch.label": "Kibana 版本不匹配", "xpack.monitoring.alerts.kibanaVersionMismatch.shortAction": "确认所有实例具有相同的版本。", "xpack.monitoring.alerts.kibanaVersionMismatch.ui.firingMessage": "在此集群中正运行着多个 Kibana 版本 ({versions})。", - "xpack.monitoring.alerts.legacyAlert.expressionText": "没有可配置的内容。", "xpack.monitoring.alerts.licenseExpiration.action": "请更新您的许可证。", "xpack.monitoring.alerts.licenseExpiration.actionVariables.clusterName": "许可证所属的集群。", "xpack.monitoring.alerts.licenseExpiration.actionVariables.expiredDate": "许可证过期日期。",