diff --git a/x-pack/plugins/monitoring/common/constants.ts b/x-pack/plugins/monitoring/common/constants.ts
index 8be0eb0b06823..6eb0d6e93d58a 100644
--- a/x-pack/plugins/monitoring/common/constants.ts
+++ b/x-pack/plugins/monitoring/common/constants.ts
@@ -231,6 +231,7 @@ export const ALERT_PREFIX = 'monitoring_';
export const ALERT_LICENSE_EXPIRATION = `${ALERT_PREFIX}alert_license_expiration`;
export const ALERT_CLUSTER_HEALTH = `${ALERT_PREFIX}alert_cluster_health`;
export const ALERT_CPU_USAGE = `${ALERT_PREFIX}alert_cpu_usage`;
+export const ALERT_DISK_USAGE = `${ALERT_PREFIX}alert_disk_usage`;
export const ALERT_NODES_CHANGED = `${ALERT_PREFIX}alert_nodes_changed`;
export const ALERT_ELASTICSEARCH_VERSION_MISMATCH = `${ALERT_PREFIX}alert_elasticsearch_version_mismatch`;
export const ALERT_KIBANA_VERSION_MISMATCH = `${ALERT_PREFIX}alert_kibana_version_mismatch`;
@@ -243,6 +244,7 @@ export const ALERTS = [
ALERT_LICENSE_EXPIRATION,
ALERT_CLUSTER_HEALTH,
ALERT_CPU_USAGE,
+ ALERT_DISK_USAGE,
ALERT_NODES_CHANGED,
ALERT_ELASTICSEARCH_VERSION_MISMATCH,
ALERT_KIBANA_VERSION_MISMATCH,
diff --git a/x-pack/plugins/monitoring/common/types.ts b/x-pack/plugins/monitoring/common/types.ts
index f5dc85dce32e1..4216a046fef9f 100644
--- a/x-pack/plugins/monitoring/common/types.ts
+++ b/x-pack/plugins/monitoring/common/types.ts
@@ -27,8 +27,9 @@ export interface CommonAlertState {
meta: any;
}
-// eslint-disable-next-line @typescript-eslint/no-empty-interface
-export interface CommonAlertFilter {}
+export interface CommonAlertFilter {
+ nodeUuid?: string;
+}
export interface CommonAlertCpuUsageFilter extends CommonAlertFilter {
nodeUuid: string;
diff --git a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/expression.tsx b/x-pack/plugins/monitoring/public/alerts/components/duration/expression.tsx
similarity index 85%
rename from x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/expression.tsx
rename to x-pack/plugins/monitoring/public/alerts/components/duration/expression.tsx
index 7dc6155de529e..2df7169efc675 100644
--- a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/expression.tsx
+++ b/x-pack/plugins/monitoring/public/alerts/components/duration/expression.tsx
@@ -6,10 +6,10 @@
import React, { Fragment } from 'react';
import { EuiForm, EuiSpacer } from '@elastic/eui';
-import { CommonAlertParamDetails } from '../../../common/types';
-import { AlertParamDuration } from '../flyout_expressions/alert_param_duration';
-import { AlertParamType } from '../../../common/enums';
-import { AlertParamPercentage } from '../flyout_expressions/alert_param_percentage';
+import { CommonAlertParamDetails } from '../../../../common/types';
+import { AlertParamDuration } from '../../flyout_expressions/alert_param_duration';
+import { AlertParamType } from '../../../../common/enums';
+import { AlertParamPercentage } from '../../flyout_expressions/alert_param_percentage';
export interface Props {
alertParams: { [property: string]: any };
diff --git a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/validation.tsx b/x-pack/plugins/monitoring/public/alerts/components/duration/validation.tsx
similarity index 62%
rename from x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/validation.tsx
rename to x-pack/plugins/monitoring/public/alerts/components/duration/validation.tsx
index 577ec12e634ed..892ee0926ca38 100644
--- a/x-pack/plugins/monitoring/public/alerts/cpu_usage_alert/validation.tsx
+++ b/x-pack/plugins/monitoring/public/alerts/components/duration/validation.tsx
@@ -6,25 +6,30 @@
import { i18n } from '@kbn/i18n';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
-import { ValidationResult } from '../../../../triggers_actions_ui/public/types';
+import { ValidationResult } from '../../../../../triggers_actions_ui/public/types';
-export function validate(opts: any): ValidationResult {
+interface ValidateOptions {
+ duration: string;
+ threshold: number;
+}
+
+export function validate(inputValues: ValidateOptions): ValidationResult {
const validationResult = { errors: {} };
const errors: { [key: string]: string[] } = {
duration: [],
threshold: [],
};
- if (!opts.duration) {
+ if (!inputValues.duration) {
errors.duration.push(
- i18n.translate('xpack.monitoring.alerts.cpuUsage.validation.duration', {
+ i18n.translate('xpack.monitoring.alerts.validation.duration', {
defaultMessage: 'A valid duration is required.',
})
);
}
- if (isNaN(opts.threshold)) {
+ if (isNaN(inputValues.threshold)) {
errors.threshold.push(
- i18n.translate('xpack.monitoring.alerts.cpuUsage.validation.threshold', {
+ i18n.translate('xpack.monitoring.alerts.validation.threshold', {
defaultMessage: 'A valid number is required.',
})
);
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 c9f82eb521433..fb4ecacf57fd6 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
@@ -6,9 +6,9 @@
import React from 'react';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types';
-import { validate } from './validation';
import { ALERT_CPU_USAGE } from '../../../common/constants';
-import { Expression } from './expression';
+import { validate } from '../components/duration/validation';
+import { Expression, Props } from '../components/duration/expression';
// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { CpuUsageAlert } from '../../../server/alerts';
@@ -18,7 +18,7 @@ export function createCpuUsageAlertType(): AlertTypeModel {
id: ALERT_CPU_USAGE,
name: alert.label,
iconClass: 'bell',
- alertParamsExpression: (props: any) => (
+ alertParamsExpression: (props: Props) => (
),
validate,
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
new file mode 100644
index 0000000000000..c2abb35612b38
--- /dev/null
+++ b/x-pack/plugins/monitoring/public/alerts/disk_usage_alert/index.tsx
@@ -0,0 +1,29 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import React from 'react';
+import { validate } from '../components/duration/validation';
+import { Expression, Props } from '../components/duration/expression';
+
+// eslint-disable-next-line @kbn/eslint/no-restricted-paths
+import { AlertTypeModel } from '../../../../triggers_actions_ui/public/types';
+
+// eslint-disable-next-line @kbn/eslint/no-restricted-paths
+import { DiskUsageAlert } from '../../../server/alerts';
+
+export function createDiskUsageAlertType(): AlertTypeModel {
+ return {
+ id: DiskUsageAlert.TYPE,
+ name: DiskUsageAlert.LABEL,
+ iconClass: 'bell',
+ alertParamsExpression: (props: Props) => (
+
+ ),
+ validate,
+ defaultActionMessage: '{{context.internalFullMessage}}',
+ requiresAppContext: true,
+ };
+}
diff --git a/x-pack/plugins/monitoring/public/alerts/lib/replace_tokens.tsx b/x-pack/plugins/monitoring/public/alerts/lib/replace_tokens.tsx
index 29e0822ad684d..02f5703f66382 100644
--- a/x-pack/plugins/monitoring/public/alerts/lib/replace_tokens.tsx
+++ b/x-pack/plugins/monitoring/public/alerts/lib/replace_tokens.tsx
@@ -17,6 +17,7 @@ import { formatTimestampToDuration } from '../../../common';
import { CALCULATE_DURATION_UNTIL } from '../../../common/constants';
import { AlertMessageTokenType } from '../../../common/enums';
import { Legacy } from '../../legacy_shims';
+import { getSafeForExternalLink } from '../../lib/get_safe_for_external_link';
export function replaceTokens(alertMessage: AlertMessage): JSX.Element | string | null {
if (!alertMessage) {
@@ -58,10 +59,11 @@ export function replaceTokens(alertMessage: AlertMessage): JSX.Element | string
const index = text.indexOf(linkPart[0]);
const preString = text.substring(0, index);
const postString = text.substring(index + linkPart[0].length);
+ const safeLink = getSafeForExternalLink(`#/${linkToken.url}`);
element = (
{preString}
- {linkPart[1]}
+ {linkPart[1]}
{postString}
);
@@ -83,7 +85,9 @@ export function replaceTokens(alertMessage: AlertMessage): JSX.Element | string
element = (
{preString}
- {linkPart[1]}
+
+ {linkPart[1]}
+
{postString}
);
diff --git a/x-pack/plugins/monitoring/public/components/cluster/overview/elasticsearch_panel.js b/x-pack/plugins/monitoring/public/components/cluster/overview/elasticsearch_panel.js
index 91752be83eb4f..61a24f31ca89a 100644
--- a/x-pack/plugins/monitoring/public/components/cluster/overview/elasticsearch_panel.js
+++ b/x-pack/plugins/monitoring/public/components/cluster/overview/elasticsearch_panel.js
@@ -40,6 +40,7 @@ import {
ALERT_LICENSE_EXPIRATION,
ALERT_CLUSTER_HEALTH,
ALERT_CPU_USAGE,
+ ALERT_DISK_USAGE,
ALERT_NODES_CHANGED,
ALERT_ELASTICSEARCH_VERSION_MISMATCH,
} from '../../../../common/constants';
@@ -157,6 +158,7 @@ const OVERVIEW_PANEL_ALERTS = [ALERT_CLUSTER_HEALTH, ALERT_LICENSE_EXPIRATION];
const NODES_PANEL_ALERTS = [
ALERT_CPU_USAGE,
+ ALERT_DISK_USAGE,
ALERT_NODES_CHANGED,
ALERT_ELASTICSEARCH_VERSION_MISMATCH,
];
diff --git a/x-pack/plugins/monitoring/public/plugin.ts b/x-pack/plugins/monitoring/public/plugin.ts
index 087e7acc4c703..a9c26ca7103a2 100644
--- a/x-pack/plugins/monitoring/public/plugin.ts
+++ b/x-pack/plugins/monitoring/public/plugin.ts
@@ -24,6 +24,7 @@ import { MonitoringStartPluginDependencies, MonitoringConfig } from './types';
import { TriggersAndActionsUIPublicPluginSetup } from '../../triggers_actions_ui/public';
import { createCpuUsageAlertType } from './alerts/cpu_usage_alert';
import { createLegacyAlertTypes } from './alerts/legacy_alert';
+import { createDiskUsageAlertType } from './alerts/disk_usage_alert';
interface MonitoringSetupPluginDependencies {
home?: HomePublicPluginSetup;
@@ -71,6 +72,7 @@ export class MonitoringPlugin
}
plugins.triggers_actions_ui.alertTypeRegistry.register(createCpuUsageAlertType());
+ plugins.triggers_actions_ui.alertTypeRegistry.register(createDiskUsageAlertType());
const legacyAlertTypes = createLegacyAlertTypes();
for (const legacyAlertType of legacyAlertTypes) {
plugins.triggers_actions_ui.alertTypeRegistry.register(legacyAlertType);
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js
index 5c4b4d28b93cb..8c30e4a2c1b07 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/advanced/index.js
@@ -17,7 +17,11 @@ import template from './index.html';
import { Legacy } from '../../../../legacy_shims';
import { AdvancedNode } from '../../../../components/elasticsearch/node/advanced';
import { MonitoringViewBaseController } from '../../../base_controller';
-import { CODE_PATH_ELASTICSEARCH, ALERT_CPU_USAGE } from '../../../../../common/constants';
+import {
+ CODE_PATH_ELASTICSEARCH,
+ ALERT_CPU_USAGE,
+ ALERT_DISK_USAGE,
+} from '../../../../../common/constants';
function getPageData($injector) {
const $http = $injector.get('$http');
@@ -67,7 +71,7 @@ uiRoutes.when('/elasticsearch/nodes/:node/advanced', {
alerts: {
shouldFetch: true,
options: {
- alertTypeIds: [ALERT_CPU_USAGE],
+ alertTypeIds: [ALERT_CPU_USAGE, ALERT_DISK_USAGE],
filters: [
{
nodeUuid: nodeName,
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js
index b4b3c7ca55303..ed2603e6dfff3 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/node/index.js
@@ -18,7 +18,11 @@ import { Node } from '../../../components/elasticsearch/node/node';
import { labels } from '../../../components/elasticsearch/shard_allocation/lib/labels';
import { nodesByIndices } from '../../../components/elasticsearch/shard_allocation/transformers/nodes_by_indices';
import { MonitoringViewBaseController } from '../../base_controller';
-import { CODE_PATH_ELASTICSEARCH, ALERT_CPU_USAGE } from '../../../../common/constants';
+import {
+ CODE_PATH_ELASTICSEARCH,
+ ALERT_CPU_USAGE,
+ ALERT_DISK_USAGE,
+} from '../../../../common/constants';
uiRoutes.when('/elasticsearch/nodes/:node', {
template,
@@ -51,7 +55,7 @@ uiRoutes.when('/elasticsearch/nodes/:node', {
alerts: {
shouldFetch: true,
options: {
- alertTypeIds: [ALERT_CPU_USAGE],
+ alertTypeIds: [ALERT_CPU_USAGE, ALERT_DISK_USAGE],
filters: [
{
nodeUuid: nodeName,
diff --git a/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js b/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js
index 33584f802a56e..66fcac43e4fc5 100644
--- a/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js
+++ b/x-pack/plugins/monitoring/public/views/elasticsearch/nodes/index.js
@@ -19,6 +19,7 @@ import {
ELASTICSEARCH_SYSTEM_ID,
CODE_PATH_ELASTICSEARCH,
ALERT_CPU_USAGE,
+ ALERT_DISK_USAGE,
} from '../../../../common/constants';
uiRoutes.when('/elasticsearch/nodes', {
@@ -86,7 +87,7 @@ uiRoutes.when('/elasticsearch/nodes', {
alerts: {
shouldFetch: true,
options: {
- alertTypeIds: [ALERT_CPU_USAGE],
+ alertTypeIds: [ALERT_CPU_USAGE, ALERT_DISK_USAGE],
},
},
});
diff --git a/x-pack/plugins/monitoring/server/alerts/alerts_common.ts b/x-pack/plugins/monitoring/server/alerts/alerts_common.ts
new file mode 100644
index 0000000000000..41c8bba17df0a
--- /dev/null
+++ b/x-pack/plugins/monitoring/server/alerts/alerts_common.ts
@@ -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;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { i18n } from '@kbn/i18n';
+import { AlertMessageDocLinkToken } from './types';
+import { AlertMessageTokenType } from '../../common/enums';
+
+export class AlertingDefaults {
+ public static readonly ALERT_STATE = {
+ resolved: i18n.translate('xpack.monitoring.alerts.state.resolved', {
+ defaultMessage: 'resolved',
+ }),
+ firing: i18n.translate('xpack.monitoring.alerts.state.firing', {
+ defaultMessage: 'firing',
+ }),
+ };
+ public static readonly ALERT_TYPE = {
+ context: {
+ internalShortMessage: {
+ name: 'internalShortMessage',
+ description: i18n.translate(
+ 'xpack.monitoring.alerts.actionVariables.internalShortMessage',
+ {
+ defaultMessage: 'The short internal message generated by Elastic.',
+ }
+ ),
+ },
+ internalFullMessage: {
+ name: 'internalFullMessage',
+ description: i18n.translate('xpack.monitoring.alerts.actionVariables.internalFullMessage', {
+ defaultMessage: 'The full internal message generated by Elastic.',
+ }),
+ },
+ state: {
+ name: 'state',
+ description: i18n.translate('xpack.monitoring.alerts.actionVariables.state', {
+ defaultMessage: 'The current state of the alert.',
+ }),
+ },
+ clusterName: {
+ name: 'clusterName',
+ description: i18n.translate('xpack.monitoring.alerts.actionVariables.clusterName', {
+ defaultMessage: 'The cluster to which the nodes belong.',
+ }),
+ },
+ action: {
+ name: 'action',
+ description: i18n.translate('xpack.monitoring.alerts.actionVariables.action', {
+ defaultMessage: 'The recommended action for this alert.',
+ }),
+ },
+ actionPlain: {
+ name: 'actionPlain',
+ description: i18n.translate('xpack.monitoring.alerts.actionVariables.actionPlain', {
+ defaultMessage: 'The recommended action for this alert, without any markdown.',
+ }),
+ },
+ },
+ };
+}
+
+export const createLink = (
+ linkText: string,
+ linkURL: string,
+ type: AlertMessageTokenType = AlertMessageTokenType.DocLink
+) => {
+ const link = type === AlertMessageTokenType.DocLink ? { partialUrl: linkURL } : { url: linkURL };
+ return {
+ text: linkText,
+ tokens: [
+ {
+ ...link,
+ startToken: '#start_link',
+ endToken: '#end_link',
+ type,
+ } as AlertMessageDocLinkToken,
+ ],
+ };
+};
diff --git a/x-pack/plugins/monitoring/server/alerts/alerts_factory.test.ts b/x-pack/plugins/monitoring/server/alerts/alerts_factory.test.ts
index d8fa703c7f785..60693eb42a30e 100644
--- a/x-pack/plugins/monitoring/server/alerts/alerts_factory.test.ts
+++ b/x-pack/plugins/monitoring/server/alerts/alerts_factory.test.ts
@@ -63,6 +63,6 @@ describe('AlertsFactory', () => {
it('should get all', () => {
const alerts = AlertsFactory.getAll();
- expect(alerts.length).toBe(7);
+ expect(alerts.length).toBe(8);
});
});
diff --git a/x-pack/plugins/monitoring/server/alerts/alerts_factory.ts b/x-pack/plugins/monitoring/server/alerts/alerts_factory.ts
index b91eab05cf912..6b1c0d5fffe18 100644
--- a/x-pack/plugins/monitoring/server/alerts/alerts_factory.ts
+++ b/x-pack/plugins/monitoring/server/alerts/alerts_factory.ts
@@ -6,6 +6,7 @@
import {
CpuUsageAlert,
+ DiskUsageAlert,
NodesChangedAlert,
ClusterHealthAlert,
LicenseExpirationAlert,
@@ -18,6 +19,7 @@ import {
ALERT_CLUSTER_HEALTH,
ALERT_LICENSE_EXPIRATION,
ALERT_CPU_USAGE,
+ ALERT_DISK_USAGE,
ALERT_NODES_CHANGED,
ALERT_LOGSTASH_VERSION_MISMATCH,
ALERT_KIBANA_VERSION_MISMATCH,
@@ -29,6 +31,7 @@ export const BY_TYPE = {
[ALERT_CLUSTER_HEALTH]: ClusterHealthAlert,
[ALERT_LICENSE_EXPIRATION]: LicenseExpirationAlert,
[ALERT_CPU_USAGE]: CpuUsageAlert,
+ [ALERT_DISK_USAGE]: DiskUsageAlert,
[ALERT_NODES_CHANGED]: NodesChangedAlert,
[ALERT_LOGSTASH_VERSION_MISMATCH]: LogstashVersionMismatchAlert,
[ALERT_KIBANA_VERSION_MISMATCH]: KibanaVersionMismatchAlert,
diff --git a/x-pack/plugins/monitoring/server/alerts/base_alert.ts b/x-pack/plugins/monitoring/server/alerts/base_alert.ts
index f583b4882f83c..aff84710d27ad 100644
--- a/x-pack/plugins/monitoring/server/alerts/base_alert.ts
+++ b/x-pack/plugins/monitoring/server/alerts/base_alert.ts
@@ -238,7 +238,7 @@ export class BaseAlert {
);
const data = await this.fetchData(params, callCluster, clusters, uiSettings, availableCcs);
- this.processData(data, clusters, services, logger);
+ return await this.processData(data, clusters, services, logger, state);
}
protected async fetchData(
@@ -252,12 +252,13 @@ export class BaseAlert {
throw new Error('Child classes must implement `fetchData`');
}
- protected processData(
+ protected async processData(
data: AlertData[],
clusters: AlertCluster[],
services: AlertServices,
- logger: Logger
- ) {
+ logger: Logger,
+ instanceState: unknown
+ ): Promise> {
for (const item of data) {
const cluster = clusters.find((c: AlertCluster) => c.clusterUuid === item.clusterUuid);
if (!cluster) {
diff --git a/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.test.ts b/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.test.ts
index 66085b53516a2..22b6c6607016f 100644
--- a/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.test.ts
+++ b/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.test.ts
@@ -25,6 +25,7 @@ describe('ClusterHealthAlert', () => {
expect(alert.defaultThrottle).toBe('1d');
// @ts-ignore
expect(alert.actionVariables).toStrictEqual([
+ { name: 'clusterHealth', description: 'The health of the cluster.' },
{
name: 'internalShortMessage',
description: 'The short internal message generated by Elastic.',
@@ -34,7 +35,6 @@ describe('ClusterHealthAlert', () => {
description: 'The full internal message generated by Elastic.',
},
{ name: 'state', description: 'The current state of the alert.' },
- { name: 'clusterHealth', description: 'The health of the cluster.' },
{ name: 'clusterName', description: 'The cluster to which the nodes belong.' },
{ name: 'action', description: 'The recommended action for this alert.' },
{
@@ -129,7 +129,7 @@ describe('ClusterHealthAlert', () => {
alertStates: [
{
cluster: { clusterUuid: 'abc123', clusterName: 'testCluster' },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: {
@@ -157,11 +157,10 @@ describe('ClusterHealthAlert', () => {
],
});
expect(scheduleActions).toHaveBeenCalledWith('default', {
- action:
- '[Allocate missing replica shards.](http://localhost:5601/app/monitoring#elasticsearch/indices?_g=(cluster_uuid:abc123))',
+ action: '[Allocate missing replica shards.](elasticsearch/indices)',
actionPlain: 'Allocate missing replica shards.',
internalFullMessage:
- 'Cluster health alert is firing for testCluster. Current health is yellow. [Allocate missing replica shards.](http://localhost:5601/app/monitoring#elasticsearch/indices?_g=(cluster_uuid:abc123))',
+ 'Cluster health alert is firing for testCluster. Current health is yellow. [Allocate missing replica shards.](elasticsearch/indices)',
internalShortMessage:
'Cluster health alert is firing for testCluster. Current health is yellow. Allocate missing replica shards.',
clusterName,
@@ -210,7 +209,7 @@ describe('ClusterHealthAlert', () => {
clusterUuid,
clusterName,
},
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: null,
@@ -242,7 +241,7 @@ describe('ClusterHealthAlert', () => {
alertStates: [
{
cluster: { clusterUuid, clusterName },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: false,
message: {
diff --git a/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.ts b/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.ts
index bb6c471591417..427dd2f86de00 100644
--- a/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.ts
+++ b/x-pack/plugins/monitoring/server/alerts/cluster_health_alert.ts
@@ -22,6 +22,7 @@ import { AlertMessageTokenType, AlertClusterHealthType } from '../../common/enum
import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts';
import { mapLegacySeverity } from '../lib/alerts/map_legacy_severity';
import { CommonAlertParams } from '../../common/types';
+import { AlertingDefaults } from './alerts_common';
const RED_STATUS_MESSAGE = i18n.translate('xpack.monitoring.alerts.clusterHealth.redMessage', {
defaultMessage: 'Allocate missing primary and replica shards',
@@ -44,30 +45,6 @@ export class ClusterHealthAlert extends BaseAlert {
public isLegacy = true;
protected actionVariables = [
- {
- name: 'internalShortMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.clusterHealth.actionVariables.internalShortMessage',
- {
- defaultMessage: 'The short internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'internalFullMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.clusterHealth.actionVariables.internalFullMessage',
- {
- defaultMessage: 'The full internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'state',
- description: i18n.translate('xpack.monitoring.alerts.clusterHealth.actionVariables.state', {
- defaultMessage: 'The current state of the alert.',
- }),
- },
{
name: 'clusterHealth',
description: i18n.translate(
@@ -77,30 +54,7 @@ export class ClusterHealthAlert extends BaseAlert {
}
),
},
- {
- name: 'clusterName',
- description: i18n.translate(
- 'xpack.monitoring.alerts.clusterHealth.actionVariables.clusterName',
- {
- defaultMessage: 'The cluster to which the nodes belong.',
- }
- ),
- },
- {
- name: 'action',
- description: i18n.translate('xpack.monitoring.alerts.clusterHealth.actionVariables.action', {
- defaultMessage: 'The recommended action for this alert.',
- }),
- },
- {
- name: 'actionPlain',
- description: i18n.translate(
- 'xpack.monitoring.alerts.clusterHealth.actionVariables.actionPlain',
- {
- defaultMessage: 'The recommended action for this alert, without any markdown.',
- }
- ),
- },
+ ...Object.values(AlertingDefaults.ALERT_TYPE.context),
];
protected async fetchData(
@@ -128,7 +82,6 @@ export class ClusterHealthAlert extends BaseAlert {
shouldFire: !legacyAlert.resolved_timestamp,
severity: mapLegacySeverity(legacyAlert.metadata.severity),
meta: legacyAlert,
- ccs: null,
});
return accum;
}, []);
@@ -214,9 +167,7 @@ export class ClusterHealthAlert extends BaseAlert {
},
}
),
- state: i18n.translate('xpack.monitoring.alerts.clusterHealth.resolved', {
- defaultMessage: `resolved`,
- }),
+ state: AlertingDefaults.ALERT_STATE.resolved,
clusterHealth: health,
clusterName: cluster.clusterName,
});
@@ -229,14 +180,8 @@ export class ClusterHealthAlert extends BaseAlert {
: i18n.translate('xpack.monitoring.alerts.clusterHealth.action.warning', {
defaultMessage: `Allocate missing replica shards.`,
});
- const globalState = [`cluster_uuid:${cluster.clusterUuid}`];
- if (alertState.ccs) {
- globalState.push(`ccs:${alertState.ccs}`);
- }
- const url = `${this.kibanaUrl}/app/monitoring#elasticsearch/indices?_g=(${globalState.join(
- ','
- )})`;
- const action = `[${actionText}](${url})`;
+
+ const action = `[${actionText}](elasticsearch/indices)`;
instance.scheduleActions('default', {
internalShortMessage: i18n.translate(
'xpack.monitoring.alerts.clusterHealth.firing.internalShortMessage',
@@ -260,9 +205,7 @@ export class ClusterHealthAlert extends BaseAlert {
},
}
),
- state: i18n.translate('xpack.monitoring.alerts.clusterHealth.firing', {
- defaultMessage: `firing`,
- }),
+ state: AlertingDefaults.ALERT_STATE.firing,
clusterHealth: health,
clusterName: cluster.clusterName,
action,
diff --git a/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.test.ts b/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.test.ts
index 2705a77e0fce4..495fe993cca1b 100644
--- a/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.test.ts
+++ b/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.test.ts
@@ -27,6 +27,8 @@ describe('CpuUsageAlert', () => {
expect(alert.defaultParams).toStrictEqual({ threshold: 85, duration: '5m' });
// @ts-ignore
expect(alert.actionVariables).toStrictEqual([
+ { name: 'nodes', description: 'The list of nodes reporting high cpu usage.' },
+ { name: 'count', description: 'The number of nodes reporting high cpu usage.' },
{
name: 'internalShortMessage',
description: 'The short internal message generated by Elastic.',
@@ -36,8 +38,6 @@ describe('CpuUsageAlert', () => {
description: 'The full internal message generated by Elastic.',
},
{ name: 'state', description: 'The current state of the alert.' },
- { name: 'nodes', description: 'The list of nodes reporting high cpu usage.' },
- { name: 'count', description: 'The number of nodes reporting high cpu usage.' },
{ name: 'clusterName', description: 'The cluster to which the nodes belong.' },
{ name: 'action', description: 'The recommended action for this alert.' },
{
@@ -78,6 +78,7 @@ describe('CpuUsageAlert', () => {
};
const kibanaUrl = 'http://localhost:5601';
+ const hasScheduledActions = jest.fn();
const replaceState = jest.fn();
const scheduleActions = jest.fn();
const getState = jest.fn();
@@ -86,6 +87,7 @@ describe('CpuUsageAlert', () => {
callCluster: jest.fn(),
alertInstanceFactory: jest.fn().mockImplementation(() => {
return {
+ hasScheduledActions,
replaceState,
scheduleActions,
getState,
@@ -133,6 +135,7 @@ describe('CpuUsageAlert', () => {
expect(replaceState).toHaveBeenCalledWith({
alertStates: [
{
+ ccs: undefined,
cluster: { clusterUuid, clusterName },
cpuUsage,
nodeId,
@@ -193,9 +196,9 @@ describe('CpuUsageAlert', () => {
],
});
expect(scheduleActions).toHaveBeenCalledWith('default', {
- internalFullMessage: `CPU usage alert is firing for ${count} node(s) in cluster: ${clusterName}. [View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:${clusterUuid}))`,
+ internalFullMessage: `CPU usage alert is firing for ${count} node(s) in cluster: ${clusterName}. [View nodes](elasticsearch/nodes)`,
internalShortMessage: `CPU usage alert is firing for ${count} node(s) in cluster: ${clusterName}. Verify CPU levels across affected nodes.`,
- action: `[View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:${clusterUuid}))`,
+ action: `[View nodes](elasticsearch/nodes)`,
actionPlain: 'Verify CPU levels across affected nodes.',
clusterName,
count,
@@ -370,9 +373,9 @@ describe('CpuUsageAlert', () => {
} as any);
const count = 1;
expect(scheduleActions).toHaveBeenCalledWith('default', {
- internalFullMessage: `CPU usage alert is firing for ${count} node(s) in cluster: ${clusterName}. [View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:${clusterUuid},ccs:${ccs}))`,
+ internalFullMessage: `CPU usage alert is firing for ${count} node(s) in cluster: ${clusterName}. [View nodes](elasticsearch/nodes)`,
internalShortMessage: `CPU usage alert is firing for ${count} node(s) in cluster: ${clusterName}. Verify CPU levels across affected nodes.`,
- action: `[View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:${clusterUuid},ccs:${ccs}))`,
+ action: `[View nodes](elasticsearch/nodes)`,
actionPlain: 'Verify CPU levels across affected nodes.',
clusterName,
count,
@@ -559,11 +562,10 @@ describe('CpuUsageAlert', () => {
expect(scheduleActions.mock.calls[0]).toEqual([
'default',
{
- action:
- '[View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:abc123))',
+ action: '[View nodes](elasticsearch/nodes)',
actionPlain: 'Verify CPU levels across affected nodes.',
internalFullMessage:
- 'CPU usage alert is firing for 1 node(s) in cluster: testCluster. [View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:abc123))',
+ 'CPU usage alert is firing for 1 node(s) in cluster: testCluster. [View nodes](elasticsearch/nodes)',
internalShortMessage:
'CPU usage alert is firing for 1 node(s) in cluster: testCluster. Verify CPU levels across affected nodes.',
nodes: 'anotherNode:99.00',
@@ -594,7 +596,7 @@ describe('CpuUsageAlert', () => {
expect(scheduleActions).toHaveBeenCalledWith('default', {
internalFullMessage: `CPU usage alert is firing for ${count} node(s) in cluster: ${clusterName}. Verify CPU levels across affected nodes.`,
internalShortMessage: `CPU usage alert is firing for ${count} node(s) in cluster: ${clusterName}. Verify CPU levels across affected nodes.`,
- action: `[View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:${clusterUuid}))`,
+ action: `[View nodes](elasticsearch/nodes)`,
actionPlain: 'Verify CPU levels across affected nodes.',
clusterName,
count,
diff --git a/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.ts b/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.ts
index 5bca84e33da3c..4228354f52748 100644
--- a/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.ts
+++ b/x-pack/plugins/monitoring/server/alerts/cpu_usage_alert.ts
@@ -3,7 +3,7 @@
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
-import { IUiSettingsClient, Logger } from 'kibana/server';
+import { IUiSettingsClient } from 'kibana/server';
import { i18n } from '@kbn/i18n';
import { BaseAlert } from './base_alert';
import {
@@ -16,7 +16,6 @@ import {
AlertMessageTimeToken,
AlertMessageLinkToken,
AlertInstanceState,
- AlertMessageDocLinkToken,
} from './types';
import { AlertInstance, AlertServices } from '../../../alerts/server';
import { INDEX_PATTERN_ELASTICSEARCH, ALERT_CPU_USAGE } from '../../common/constants';
@@ -31,15 +30,9 @@ import {
CommonAlertParams,
CommonAlertParamDetail,
} from '../../common/types';
+import { AlertingDefaults, createLink } from './alerts_common';
import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index';
-const RESOLVED = i18n.translate('xpack.monitoring.alerts.cpuUsage.resolved', {
- defaultMessage: 'resolved',
-});
-const FIRING = i18n.translate('xpack.monitoring.alerts.cpuUsage.firing', {
- defaultMessage: 'firing',
-});
-
const DEFAULT_THRESHOLD = 85;
const DEFAULT_DURATION = '5m';
@@ -75,30 +68,6 @@ export class CpuUsageAlert extends BaseAlert {
};
protected actionVariables = [
- {
- name: 'internalShortMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.cpuUsage.actionVariables.internalShortMessage',
- {
- defaultMessage: 'The short internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'internalFullMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.cpuUsage.actionVariables.internalFullMessage',
- {
- defaultMessage: 'The full internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'state',
- description: i18n.translate('xpack.monitoring.alerts.cpuUsage.actionVariables.state', {
- defaultMessage: 'The current state of the alert.',
- }),
- },
{
name: 'nodes',
description: i18n.translate('xpack.monitoring.alerts.cpuUsage.actionVariables.nodes', {
@@ -111,24 +80,7 @@ export class CpuUsageAlert extends BaseAlert {
defaultMessage: 'The number of nodes reporting high cpu usage.',
}),
},
- {
- name: 'clusterName',
- description: i18n.translate('xpack.monitoring.alerts.cpuUsage.actionVariables.clusterName', {
- defaultMessage: 'The cluster to which the nodes belong.',
- }),
- },
- {
- name: 'action',
- description: i18n.translate('xpack.monitoring.alerts.cpuUsage.actionVariables.action', {
- defaultMessage: 'The recommended action for this alert.',
- }),
- },
- {
- name: 'actionPlain',
- description: i18n.translate('xpack.monitoring.alerts.cpuUsage.actionVariables.actionPlain', {
- defaultMessage: 'The recommended action for this alert, without any markdown.',
- }),
- },
+ ...Object.values(AlertingDefaults.ALERT_TYPE.context),
];
protected async fetchData(
@@ -237,32 +189,18 @@ export class CpuUsageAlert extends BaseAlert {
},
}),
nextSteps: [
- {
- text: i18n.translate('xpack.monitoring.alerts.cpuUsage.ui.nextSteps.hotThreads', {
- defaultMessage: `#start_linkCheck hot threads#end_link`,
+ createLink(
+ i18n.translate('xpack.monitoring.alerts.cpuUsage.ui.nextSteps.hotThreads', {
+ defaultMessage: '#start_linkCheck hot threads#end_link',
}),
- tokens: [
- {
- startToken: '#start_link',
- endToken: '#end_link',
- type: AlertMessageTokenType.DocLink,
- partialUrl: `{elasticWebsiteUrl}/guide/en/elasticsearch/reference/{docLinkVersion}/cluster-nodes-hot-threads.html`,
- } as AlertMessageDocLinkToken,
- ],
- },
- {
- text: i18n.translate('xpack.monitoring.alerts.cpuUsage.ui.nextSteps.runningTasks', {
- defaultMessage: `#start_linkCheck long running tasks#end_link`,
+ `{elasticWebsiteUrl}/guide/en/elasticsearch/reference/{docLinkVersion}/cluster-nodes-hot-threads.html`
+ ),
+ createLink(
+ i18n.translate('xpack.monitoring.alerts.cpuUsage.ui.nextSteps.runningTasks', {
+ defaultMessage: '#start_linkCheck long running tasks#end_link',
}),
- tokens: [
- {
- startToken: '#start_link',
- endToken: '#end_link',
- type: AlertMessageTokenType.DocLink,
- partialUrl: `{elasticWebsiteUrl}/guide/en/elasticsearch/reference/{docLinkVersion}/tasks.html`,
- } as AlertMessageDocLinkToken,
- ],
- },
+ `{elasticWebsiteUrl}/guide/en/elasticsearch/reference/{docLinkVersion}/tasks.html`
+ ),
],
tokens: [
{
@@ -292,13 +230,6 @@ export class CpuUsageAlert extends BaseAlert {
return;
}
- const ccs = instanceState.alertStates.reduce((accum: string, state): string => {
- if (state.ccs) {
- return state.ccs;
- }
- return accum;
- }, '');
-
const firingCount = instanceState.alertStates.filter((alertState) => alertState.ui.isFiring)
.length;
const firingNodes = instanceState.alertStates
@@ -315,14 +246,7 @@ export class CpuUsageAlert extends BaseAlert {
const fullActionText = i18n.translate('xpack.monitoring.alerts.cpuUsage.fullAction', {
defaultMessage: 'View nodes',
});
- const globalState = [`cluster_uuid:${cluster.clusterUuid}`];
- if (ccs) {
- globalState.push(`ccs:${ccs}`);
- }
- const url = `${this.kibanaUrl}/app/monitoring#elasticsearch/nodes?_g=(${globalState.join(
- ','
- )})`;
- const action = `[${fullActionText}](${url})`;
+ const action = `[${fullActionText}](elasticsearch/nodes)`;
const internalShortMessage = i18n.translate(
'xpack.monitoring.alerts.cpuUsage.firing.internalShortMessage',
{
@@ -348,7 +272,7 @@ export class CpuUsageAlert extends BaseAlert {
instance.scheduleActions('default', {
internalShortMessage,
internalFullMessage: this.isCloud ? internalShortMessage : internalFullMessage,
- state: FIRING,
+ state: AlertingDefaults.ALERT_STATE.firing,
nodes: firingNodes,
count: firingCount,
clusterName: cluster.clusterName,
@@ -388,7 +312,7 @@ export class CpuUsageAlert extends BaseAlert {
},
}
),
- state: RESOLVED,
+ state: AlertingDefaults.ALERT_STATE.resolved,
nodes: resolvedNodes,
count: resolvedCount,
clusterName: cluster.clusterName,
@@ -397,18 +321,16 @@ export class CpuUsageAlert extends BaseAlert {
}
}
- protected processData(
+ protected async processData(
data: AlertData[],
clusters: AlertCluster[],
- services: AlertServices,
- logger: Logger
+ services: AlertServices
) {
for (const cluster of clusters) {
const nodes = data.filter((_item) => _item.clusterUuid === cluster.clusterUuid);
if (nodes.length === 0) {
continue;
}
-
const firingNodeUuids = nodes.reduce((list: string[], node) => {
const stat = node.meta as AlertCpuUsageNodeStats;
if (node.shouldFire) {
@@ -437,13 +359,14 @@ export class CpuUsageAlert extends BaseAlert {
} else {
nodeState = this.getDefaultAlertState(cluster, node) as AlertCpuUsageState;
}
-
nodeState.cpuUsage = stat.cpuUsage;
nodeState.nodeId = stat.nodeId;
nodeState.nodeName = stat.nodeName;
if (node.shouldFire) {
- nodeState.ui.triggeredMS = new Date().valueOf();
+ if (!nodeState.ui.isFiring) {
+ nodeState.ui.triggeredMS = new Date().valueOf();
+ }
nodeState.ui.isFiring = true;
nodeState.ui.message = this.getUiMessage(nodeState, node);
nodeState.ui.severity = node.severity;
@@ -455,7 +378,6 @@ export class CpuUsageAlert extends BaseAlert {
nodeState.ui.message = this.getUiMessage(nodeState, node);
shouldExecuteActions = true;
}
-
if (indexInState === -1) {
alertInstanceState.alertStates.push(nodeState);
} else {
@@ -466,7 +388,6 @@ export class CpuUsageAlert extends BaseAlert {
];
}
}
-
instance.replaceState(alertInstanceState);
if (shouldExecuteActions) {
this.executeActions(instance, alertInstanceState, null, cluster);
diff --git a/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.test.ts b/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.test.ts
new file mode 100644
index 0000000000000..546399f666b6c
--- /dev/null
+++ b/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.test.ts
@@ -0,0 +1,221 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { DiskUsageAlert } from './disk_usage_alert';
+import { ALERT_DISK_USAGE } from '../../common/constants';
+import { fetchDiskUsageNodeStats } from '../lib/alerts/fetch_disk_usage_node_stats';
+import { fetchClusters } from '../lib/alerts/fetch_clusters';
+
+type IDiskUsageAlertMock = DiskUsageAlert & {
+ defaultParams: {
+ threshold: number;
+ duration: string;
+ };
+} & {
+ actionVariables: Array<{
+ name: string;
+ description: string;
+ }>;
+};
+
+const RealDate = Date;
+
+jest.mock('../lib/alerts/fetch_disk_usage_node_stats', () => ({
+ fetchDiskUsageNodeStats: jest.fn(),
+}));
+jest.mock('../lib/alerts/fetch_clusters', () => ({
+ fetchClusters: jest.fn(),
+}));
+
+describe('DiskUsageAlert', () => {
+ it('should have defaults', () => {
+ const alert = new DiskUsageAlert() as IDiskUsageAlertMock;
+ expect(alert.type).toBe(ALERT_DISK_USAGE);
+ expect(alert.label).toBe('Disk Usage');
+ expect(alert.defaultThrottle).toBe('1d');
+ expect(alert.defaultParams).toStrictEqual({ threshold: 90, duration: '5m' });
+ expect(alert.actionVariables).toStrictEqual([
+ { name: 'nodes', description: 'The list of nodes reporting high disk usage.' },
+ { name: 'count', description: 'The number of nodes reporting high disk usage.' },
+ {
+ name: 'internalShortMessage',
+ description: 'The short internal message generated by Elastic.',
+ },
+ {
+ name: 'internalFullMessage',
+ description: 'The full internal message generated by Elastic.',
+ },
+ { name: 'state', description: 'The current state of the alert.' },
+ { name: 'clusterName', description: 'The cluster to which the nodes belong.' },
+ { name: 'action', description: 'The recommended action for this alert.' },
+ {
+ name: 'actionPlain',
+ description: 'The recommended action for this alert, without any markdown.',
+ },
+ ]);
+ });
+
+ describe('execute', () => {
+ const FakeDate = function () {};
+ FakeDate.prototype.valueOf = () => 1;
+
+ const clusterUuid = 'abc123';
+ const clusterName = 'testCluster';
+ const nodeId = 'myNodeId';
+ const nodeName = 'myNodeName';
+ const diskUsage = 91;
+ const stat = {
+ clusterUuid,
+ nodeId,
+ nodeName,
+ diskUsage,
+ };
+ const getUiSettingsService = () => ({
+ asScopedToClient: jest.fn(),
+ });
+ const getLogger = () => ({
+ debug: jest.fn(),
+ });
+ const monitoringCluster = null;
+ const config = {
+ ui: {
+ ccs: { enabled: true },
+ container: { elasticsearch: { enabled: false } },
+ metricbeat: { index: 'metricbeat-*' },
+ },
+ };
+ const kibanaUrl = 'http://localhost:5601';
+
+ const hasScheduledActions = jest.fn();
+ const replaceState = jest.fn();
+ const scheduleActions = jest.fn();
+ const getState = jest.fn();
+ const executorOptions = {
+ services: {
+ callCluster: jest.fn(),
+ alertInstanceFactory: jest.fn().mockImplementation(() => {
+ return {
+ hasScheduledActions,
+ replaceState,
+ scheduleActions,
+ getState,
+ };
+ }),
+ },
+ state: {},
+ };
+
+ beforeEach(() => {
+ Date = FakeDate as DateConstructor;
+ (fetchDiskUsageNodeStats as jest.Mock).mockImplementation(() => {
+ return [stat];
+ });
+ (fetchClusters as jest.Mock).mockImplementation(() => {
+ return [{ clusterUuid, clusterName }];
+ });
+ });
+
+ afterEach(() => {
+ Date = RealDate;
+ replaceState.mockReset();
+ scheduleActions.mockReset();
+ getState.mockReset();
+ });
+
+ it('should fire actions', async () => {
+ const alert = new DiskUsageAlert() as IDiskUsageAlertMock;
+ alert.initializeAlertType(
+ getUiSettingsService as any,
+ monitoringCluster as any,
+ getLogger as any,
+ config as any,
+ kibanaUrl,
+ false
+ );
+ const type = alert.getAlertType();
+ await type.executor({
+ ...executorOptions,
+ params: alert.defaultParams,
+ } as any);
+ const count = 1;
+ expect(scheduleActions).toHaveBeenCalledWith('default', {
+ internalFullMessage: `Disk usage alert is firing for ${count} node(s) in cluster: ${clusterName}. [View nodes](elasticsearch/nodes)`,
+ internalShortMessage: `Disk usage alert is firing for ${count} node(s) in cluster: ${clusterName}. Verify disk usage levels across affected nodes.`,
+ action: `[View nodes](elasticsearch/nodes)`,
+ actionPlain: 'Verify disk usage levels across affected nodes.',
+ clusterName,
+ count,
+ nodes: `${nodeName}:${diskUsage.toFixed(2)}`,
+ state: 'firing',
+ });
+ });
+
+ it('should handle ccs', async () => {
+ const ccs = 'testCluster';
+ (fetchDiskUsageNodeStats as jest.Mock).mockImplementation(() => {
+ return [
+ {
+ ...stat,
+ ccs,
+ },
+ ];
+ });
+ const alert = new DiskUsageAlert() as IDiskUsageAlertMock;
+ alert.initializeAlertType(
+ getUiSettingsService as any,
+ monitoringCluster as any,
+ getLogger as any,
+ config as any,
+ kibanaUrl,
+ false
+ );
+ const type = alert.getAlertType();
+ await type.executor({
+ ...executorOptions,
+ params: alert.defaultParams,
+ } as any);
+ const count = 1;
+ expect(scheduleActions).toHaveBeenCalledWith('default', {
+ internalFullMessage: `Disk usage alert is firing for ${count} node(s) in cluster: ${clusterName}. [View nodes](elasticsearch/nodes)`,
+ internalShortMessage: `Disk usage alert is firing for ${count} node(s) in cluster: ${clusterName}. Verify disk usage levels across affected nodes.`,
+ action: `[View nodes](elasticsearch/nodes)`,
+ actionPlain: 'Verify disk usage levels across affected nodes.',
+ clusterName,
+ count,
+ nodes: `${nodeName}:${diskUsage.toFixed(2)}`,
+ state: 'firing',
+ });
+ });
+
+ it('should fire with different messaging for cloud', async () => {
+ const alert = new DiskUsageAlert() as IDiskUsageAlertMock;
+ alert.initializeAlertType(
+ getUiSettingsService as any,
+ monitoringCluster as any,
+ getLogger as any,
+ config as any,
+ kibanaUrl,
+ true
+ );
+ const type = alert.getAlertType();
+ await type.executor({
+ ...executorOptions,
+ params: alert.defaultParams,
+ } as any);
+ const count = 1;
+ expect(scheduleActions).toHaveBeenCalledWith('default', {
+ internalFullMessage: `Disk usage alert is firing for ${count} node(s) in cluster: ${clusterName}. Verify disk usage levels across affected nodes.`,
+ internalShortMessage: `Disk usage alert is firing for ${count} node(s) in cluster: ${clusterName}. Verify disk usage levels across affected nodes.`,
+ action: `[View nodes](elasticsearch/nodes)`,
+ actionPlain: 'Verify disk usage levels across affected nodes.',
+ clusterName,
+ count,
+ nodes: `${nodeName}:${diskUsage.toFixed(2)}`,
+ state: 'firing',
+ });
+ });
+ });
+});
diff --git a/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.ts b/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.ts
new file mode 100644
index 0000000000000..e43dca3ce87b1
--- /dev/null
+++ b/x-pack/plugins/monitoring/server/alerts/disk_usage_alert.ts
@@ -0,0 +1,343 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+import { IUiSettingsClient, Logger } from 'kibana/server';
+import { i18n } from '@kbn/i18n';
+import { BaseAlert } from './base_alert';
+import {
+ AlertData,
+ AlertCluster,
+ AlertState,
+ AlertMessage,
+ AlertDiskUsageState,
+ AlertMessageTimeToken,
+ AlertMessageLinkToken,
+ AlertInstanceState,
+} from './types';
+import { AlertInstance, AlertServices } from '../../../alerts/server';
+import { INDEX_PATTERN_ELASTICSEARCH, ALERT_DISK_USAGE } from '../../common/constants';
+import { fetchDiskUsageNodeStats } from '../lib/alerts/fetch_disk_usage_node_stats';
+import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern';
+import { AlertMessageTokenType, AlertSeverity, AlertParamType } from '../../common/enums';
+import { RawAlertInstance } from '../../../alerts/common';
+import { CommonAlertFilter, CommonAlertParams, CommonAlertParamDetail } from '../../common/types';
+import { AlertingDefaults, createLink } from './alerts_common';
+import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index';
+
+interface ParamDetails {
+ [key: string]: CommonAlertParamDetail;
+}
+
+export class DiskUsageAlert extends BaseAlert {
+ public static readonly PARAM_DETAILS: ParamDetails = {
+ threshold: {
+ label: i18n.translate('xpack.monitoring.alerts.diskUsage.paramDetails.threshold.label', {
+ defaultMessage: `Notify when disk capacity is over`,
+ }),
+ type: AlertParamType.Percentage,
+ },
+ duration: {
+ label: i18n.translate('xpack.monitoring.alerts.diskUsage.paramDetails.duration.label', {
+ defaultMessage: `Look at the average over`,
+ }),
+ type: AlertParamType.Duration,
+ },
+ };
+ public static paramDetails = DiskUsageAlert.PARAM_DETAILS;
+ public static readonly TYPE = ALERT_DISK_USAGE;
+ public static readonly LABEL = i18n.translate('xpack.monitoring.alerts.diskUsage.label', {
+ defaultMessage: 'Disk Usage',
+ });
+ public type = DiskUsageAlert.TYPE;
+ public label = DiskUsageAlert.LABEL;
+
+ protected defaultParams = {
+ threshold: 90,
+ duration: '5m',
+ };
+
+ protected actionVariables = [
+ {
+ name: 'nodes',
+ description: i18n.translate('xpack.monitoring.alerts.diskUsage.actionVariables.nodes', {
+ defaultMessage: 'The list of nodes reporting high disk usage.',
+ }),
+ },
+ {
+ name: 'count',
+ description: i18n.translate('xpack.monitoring.alerts.diskUsage.actionVariables.count', {
+ defaultMessage: 'The number of nodes reporting high disk usage.',
+ }),
+ },
+ ...Object.values(AlertingDefaults.ALERT_TYPE.context),
+ ];
+
+ protected async fetchData(
+ params: CommonAlertParams,
+ callCluster: any,
+ clusters: AlertCluster[],
+ uiSettings: IUiSettingsClient,
+ availableCcs: string[]
+ ): Promise {
+ let esIndexPattern = appendMetricbeatIndex(this.config, INDEX_PATTERN_ELASTICSEARCH);
+ if (availableCcs) {
+ esIndexPattern = getCcsIndexPattern(esIndexPattern, availableCcs);
+ }
+ const { duration, threshold } = params;
+ const stats = await fetchDiskUsageNodeStats(
+ callCluster,
+ clusters,
+ esIndexPattern,
+ duration as string,
+ this.config.ui.max_bucket_size
+ );
+
+ return stats.map((stat) => {
+ const { clusterUuid, nodeId, diskUsage, ccs } = stat;
+ return {
+ instanceKey: `${clusterUuid}:${nodeId}`,
+ shouldFire: diskUsage > threshold,
+ severity: AlertSeverity.Danger,
+ meta: stat,
+ clusterUuid,
+ ccs,
+ };
+ });
+ }
+
+ protected filterAlertInstance(alertInstance: RawAlertInstance, filters: CommonAlertFilter[]) {
+ const alertInstanceStates = alertInstance.state?.alertStates as AlertDiskUsageState[];
+ const nodeUuid = filters?.find((filter) => filter.nodeUuid);
+
+ if (!filters || !filters.length || !alertInstanceStates?.length || !nodeUuid) {
+ return true;
+ }
+
+ const nodeAlerts = alertInstanceStates.filter(({ nodeId }) => nodeId === nodeUuid);
+ return Boolean(nodeAlerts.length);
+ }
+
+ protected getDefaultAlertState(cluster: AlertCluster, item: AlertData): AlertState {
+ const currentState = super.getDefaultAlertState(cluster, item);
+ currentState.ui.severity = AlertSeverity.Warning;
+ return currentState;
+ }
+
+ protected getUiMessage(alertState: AlertState, item: AlertData): AlertMessage {
+ const stat = item.meta as AlertDiskUsageState;
+ if (!alertState.ui.isFiring) {
+ return {
+ text: i18n.translate('xpack.monitoring.alerts.diskUsage.ui.resolvedMessage', {
+ defaultMessage: `The disk usage on node {nodeName} is now under the threshold, currently reporting at {diskUsage}% as of #resolved`,
+ values: {
+ nodeName: stat.nodeName,
+ diskUsage: stat.diskUsage.toFixed(2),
+ },
+ }),
+ tokens: [
+ {
+ startToken: '#resolved',
+ type: AlertMessageTokenType.Time,
+ isAbsolute: true,
+ isRelative: false,
+ timestamp: alertState.ui.resolvedMS,
+ } as AlertMessageTimeToken,
+ ],
+ };
+ }
+ return {
+ text: i18n.translate('xpack.monitoring.alerts.diskUsage.ui.firingMessage', {
+ defaultMessage: `Node #start_link{nodeName}#end_link is reporting disk usage of {diskUsage}% at #absolute`,
+ values: {
+ nodeName: stat.nodeName,
+ diskUsage: stat.diskUsage,
+ },
+ }),
+ nextSteps: [
+ createLink(
+ i18n.translate('xpack.monitoring.alerts.diskUsage.ui.nextSteps.tuneDisk', {
+ defaultMessage: '#start_linkTune for disk usage#end_link',
+ }),
+ `{elasticWebsiteUrl}/guide/en/elasticsearch/reference/{docLinkVersion}/tune-for-disk-usage.html`
+ ),
+ createLink(
+ i18n.translate('xpack.monitoring.alerts.diskUsage.ui.nextSteps.identifyIndices', {
+ defaultMessage: '#start_linkIdentify large indices#end_link',
+ }),
+ 'elasticsearch/indices',
+ AlertMessageTokenType.Link
+ ),
+ createLink(
+ i18n.translate('xpack.monitoring.alerts.diskUsage.ui.nextSteps.ilmPolicies', {
+ defaultMessage: '#start_linkImplement ILM policies#end_link',
+ }),
+ `{elasticWebsiteUrl}/guide/en/elasticsearch/reference/{docLinkVersion}/index-lifecycle-management.html`
+ ),
+ createLink(
+ i18n.translate('xpack.monitoring.alerts.diskUsage.ui.nextSteps.addMoreNodes', {
+ defaultMessage: '#start_linkAdd more data nodes#end_link',
+ }),
+ `{elasticWebsiteUrl}/guide/en/elasticsearch/reference/{docLinkVersion}/add-elasticsearch-nodes.html`
+ ),
+ createLink(
+ i18n.translate('xpack.monitoring.alerts.diskUsage.ui.nextSteps.resizeYourDeployment', {
+ defaultMessage: '#start_linkResize your deployment (ECE)#end_link',
+ }),
+ `{elasticWebsiteUrl}/guide/en/cloud-enterprise/current/ece-resize-deployment.html`
+ ),
+ ],
+ tokens: [
+ {
+ startToken: '#absolute',
+ type: AlertMessageTokenType.Time,
+ isAbsolute: true,
+ isRelative: false,
+ timestamp: alertState.ui.triggeredMS,
+ } as AlertMessageTimeToken,
+ {
+ startToken: '#start_link',
+ endToken: '#end_link',
+ type: AlertMessageTokenType.Link,
+ url: `elasticsearch/nodes/${stat.nodeId}`,
+ } as AlertMessageLinkToken,
+ ],
+ };
+ }
+
+ protected executeActions(
+ instance: AlertInstance,
+ { alertStates }: AlertInstanceState,
+ item: AlertData | null,
+ cluster: AlertCluster
+ ) {
+ const firingNodes = alertStates.filter(
+ (alertState) => alertState.ui.isFiring
+ ) as AlertDiskUsageState[];
+ const firingCount = firingNodes.length;
+
+ if (firingCount > 0) {
+ const shortActionText = i18n.translate('xpack.monitoring.alerts.diskUsage.shortAction', {
+ defaultMessage: 'Verify disk usage levels across affected nodes.',
+ });
+ const fullActionText = i18n.translate('xpack.monitoring.alerts.diskUsage.fullAction', {
+ defaultMessage: 'View nodes',
+ });
+
+ const action = `[${fullActionText}](elasticsearch/nodes)`;
+ const internalShortMessage = i18n.translate(
+ 'xpack.monitoring.alerts.diskUsage.firing.internalShortMessage',
+ {
+ defaultMessage: `Disk usage alert is firing for {count} node(s) in cluster: {clusterName}. {shortActionText}`,
+ values: {
+ count: firingCount,
+ clusterName: cluster.clusterName,
+ shortActionText,
+ },
+ }
+ );
+ const internalFullMessage = i18n.translate(
+ 'xpack.monitoring.alerts.diskUsage.firing.internalFullMessage',
+ {
+ defaultMessage: `Disk usage alert is firing for {count} node(s) in cluster: {clusterName}. {action}`,
+ values: {
+ count: firingCount,
+ clusterName: cluster.clusterName,
+ action,
+ },
+ }
+ );
+
+ instance.scheduleActions('default', {
+ internalShortMessage,
+ internalFullMessage: this.isCloud ? internalShortMessage : internalFullMessage,
+ state: AlertingDefaults.ALERT_STATE.firing,
+ nodes: firingNodes
+ .map((state) => `${state.nodeName}:${state.diskUsage.toFixed(2)}`)
+ .join(','),
+ count: firingCount,
+ clusterName: cluster.clusterName,
+ action,
+ actionPlain: shortActionText,
+ });
+ } else {
+ const resolvedNodes = (alertStates as AlertDiskUsageState[])
+ .filter((state) => !state.ui.isFiring)
+ .map((state) => `${state.nodeName}:${state.diskUsage.toFixed(2)}`);
+ const resolvedCount = resolvedNodes.length;
+
+ if (resolvedCount > 0) {
+ const internalMessage = i18n.translate(
+ 'xpack.monitoring.alerts.diskUsage.resolved.internalMessage',
+ {
+ defaultMessage: `Disk usage alert is resolved for {count} node(s) in cluster: {clusterName}.`,
+ values: {
+ count: resolvedCount,
+ clusterName: cluster.clusterName,
+ },
+ }
+ );
+
+ instance.scheduleActions('default', {
+ internalShortMessage: internalMessage,
+ internalFullMessage: internalMessage,
+ state: AlertingDefaults.ALERT_STATE.resolved,
+ nodes: resolvedNodes.join(','),
+ count: resolvedCount,
+ clusterName: cluster.clusterName,
+ });
+ }
+ }
+ }
+
+ protected async processData(
+ data: AlertData[],
+ clusters: AlertCluster[],
+ services: AlertServices,
+ logger: Logger,
+ state: any
+ ) {
+ const currentUTC = +new Date();
+ for (const cluster of clusters) {
+ const nodes = data.filter((node) => node.clusterUuid === cluster.clusterUuid);
+ if (!nodes.length) {
+ continue;
+ }
+
+ const firingNodeUuids = nodes
+ .filter((node) => node.shouldFire)
+ .map((node) => node.meta.nodeId)
+ .join(',');
+ const instanceId = `${this.type}:${cluster.clusterUuid}:${firingNodeUuids}`;
+ const instance = services.alertInstanceFactory(instanceId);
+ const newAlertStates: AlertDiskUsageState[] = [];
+
+ for (const node of nodes) {
+ const stat = node.meta as AlertDiskUsageState;
+ const nodeState = this.getDefaultAlertState(cluster, node) as AlertDiskUsageState;
+ nodeState.diskUsage = stat.diskUsage;
+ nodeState.nodeId = stat.nodeId;
+ nodeState.nodeName = stat.nodeName;
+
+ if (node.shouldFire) {
+ nodeState.ui.triggeredMS = currentUTC;
+ nodeState.ui.isFiring = true;
+ nodeState.ui.severity = node.severity;
+ newAlertStates.push(nodeState);
+ }
+ nodeState.ui.message = this.getUiMessage(nodeState, node);
+ }
+
+ const alertInstanceState = { alertStates: newAlertStates };
+ instance.replaceState(alertInstanceState);
+ if (newAlertStates.length && !instance.hasScheduledActions()) {
+ this.executeActions(instance, alertInstanceState, null, cluster);
+ state.lastExecutedAction = currentUTC;
+ }
+ }
+
+ state.lastChecked = currentUTC;
+ return state;
+ }
+}
diff --git a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.test.ts b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.test.ts
index 1db85f915d794..3422e8a7c78ad 100644
--- a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.test.ts
+++ b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.test.ts
@@ -25,6 +25,10 @@ describe('ElasticsearchVersionMismatchAlert', () => {
expect(alert.defaultThrottle).toBe('1d');
// @ts-ignore
expect(alert.actionVariables).toStrictEqual([
+ {
+ name: 'versionList',
+ description: 'The versions of Elasticsearch running in this cluster.',
+ },
{
name: 'internalShortMessage',
description: 'The short internal message generated by Elastic.',
@@ -34,10 +38,6 @@ describe('ElasticsearchVersionMismatchAlert', () => {
description: 'The full internal message generated by Elastic.',
},
{ name: 'state', description: 'The current state of the alert.' },
- {
- name: 'versionList',
- description: 'The versions of Elasticsearch running in this cluster.',
- },
{ name: 'clusterName', description: 'The cluster to which the nodes belong.' },
{ name: 'action', description: 'The recommended action for this alert.' },
{
@@ -132,7 +132,7 @@ describe('ElasticsearchVersionMismatchAlert', () => {
alertStates: [
{
cluster: { clusterUuid: 'abc123', clusterName: 'testCluster' },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: {
@@ -148,11 +148,10 @@ describe('ElasticsearchVersionMismatchAlert', () => {
],
});
expect(scheduleActions).toHaveBeenCalledWith('default', {
- action:
- '[View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:abc123))',
+ action: '[View nodes](elasticsearch/nodes)',
actionPlain: 'Verify you have the same version across all nodes.',
internalFullMessage:
- 'Elasticsearch version mismatch alert is firing for testCluster. Elasticsearch is running [8.0.0, 7.2.1]. [View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:abc123))',
+ 'Elasticsearch version mismatch alert is firing for testCluster. Elasticsearch is running [8.0.0, 7.2.1]. [View nodes](elasticsearch/nodes)',
internalShortMessage:
'Elasticsearch version mismatch alert is firing for testCluster. Verify you have the same version across all nodes.',
versionList: '[8.0.0, 7.2.1]',
@@ -201,7 +200,7 @@ describe('ElasticsearchVersionMismatchAlert', () => {
clusterUuid,
clusterName,
},
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: null,
@@ -233,7 +232,7 @@ describe('ElasticsearchVersionMismatchAlert', () => {
alertStates: [
{
cluster: { clusterUuid, clusterName },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: false,
message: {
diff --git a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.ts b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.ts
index e3b952fbbe5d3..f26b21f0c64c5 100644
--- a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.ts
+++ b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_alert.ts
@@ -20,14 +20,9 @@ import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern';
import { AlertSeverity } from '../../common/enums';
import { CommonAlertParams } from '../../common/types';
import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts';
+import { AlertingDefaults } from './alerts_common';
const WATCH_NAME = 'elasticsearch_version_mismatch';
-const RESOLVED = i18n.translate('xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved', {
- defaultMessage: 'resolved',
-});
-const FIRING = i18n.translate('xpack.monitoring.alerts.elasticsearchVersionMismatch.firing', {
- defaultMessage: 'firing',
-});
export class ElasticsearchVersionMismatchAlert extends BaseAlert {
public type = ALERT_ELASTICSEARCH_VERSION_MISMATCH;
@@ -37,33 +32,6 @@ export class ElasticsearchVersionMismatchAlert extends BaseAlert {
public isLegacy = true;
protected actionVariables = [
- {
- name: 'internalShortMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalShortMessage',
- {
- defaultMessage: 'The short internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'internalFullMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalFullMessage',
- {
- defaultMessage: 'The full internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'state',
- description: i18n.translate(
- 'xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.state',
- {
- defaultMessage: 'The current state of the alert.',
- }
- ),
- },
{
name: 'versionList',
description: i18n.translate(
@@ -73,33 +41,7 @@ export class ElasticsearchVersionMismatchAlert extends BaseAlert {
}
),
},
- {
- name: 'clusterName',
- description: i18n.translate(
- 'xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.clusterName',
- {
- defaultMessage: 'The cluster to which the nodes belong.',
- }
- ),
- },
- {
- name: 'action',
- description: i18n.translate(
- 'xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.action',
- {
- defaultMessage: 'The recommended action for this alert.',
- }
- ),
- },
- {
- name: 'actionPlain',
- description: i18n.translate(
- 'xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.actionPlain',
- {
- defaultMessage: 'The recommended action for this alert, without any markdown.',
- }
- ),
- },
+ ...Object.values(AlertingDefaults.ALERT_TYPE.context),
];
protected async fetchData(
@@ -131,7 +73,6 @@ export class ElasticsearchVersionMismatchAlert extends BaseAlert {
shouldFire: !legacyAlert.resolved_timestamp,
severity,
meta: legacyAlert,
- ccs: null,
});
return accum;
}, []);
@@ -206,7 +147,7 @@ export class ElasticsearchVersionMismatchAlert extends BaseAlert {
},
}
),
- state: RESOLVED,
+ state: AlertingDefaults.ALERT_STATE.resolved,
clusterName: cluster.clusterName,
});
} else {
@@ -222,14 +163,7 @@ export class ElasticsearchVersionMismatchAlert extends BaseAlert {
defaultMessage: 'View nodes',
}
);
- const globalState = [`cluster_uuid:${cluster.clusterUuid}`];
- if (alertState.ccs) {
- globalState.push(`ccs:${alertState.ccs}`);
- }
- const url = `${this.kibanaUrl}/app/monitoring#elasticsearch/nodes?_g=(${globalState.join(
- ','
- )})`;
- const action = `[${fullActionText}](${url})`;
+ const action = `[${fullActionText}](elasticsearch/nodes)`;
instance.scheduleActions('default', {
internalShortMessage: i18n.translate(
'xpack.monitoring.alerts.elasticsearchVersionMismatch.firing.internalShortMessage',
@@ -252,7 +186,7 @@ export class ElasticsearchVersionMismatchAlert extends BaseAlert {
},
}
),
- state: FIRING,
+ state: AlertingDefaults.ALERT_STATE.firing,
clusterName: cluster.clusterName,
versionList: versions,
action,
diff --git a/x-pack/plugins/monitoring/server/alerts/index.ts b/x-pack/plugins/monitoring/server/alerts/index.ts
index 048e703d2222c..8fdac65514477 100644
--- a/x-pack/plugins/monitoring/server/alerts/index.ts
+++ b/x-pack/plugins/monitoring/server/alerts/index.ts
@@ -6,6 +6,7 @@
export { BaseAlert } from './base_alert';
export { CpuUsageAlert } from './cpu_usage_alert';
+export { DiskUsageAlert } from './disk_usage_alert';
export { ClusterHealthAlert } from './cluster_health_alert';
export { LicenseExpirationAlert } from './license_expiration_alert';
export { NodesChangedAlert } from './nodes_changed_alert';
diff --git a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.test.ts b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.test.ts
index 362532a995f2d..1082e9f6311a4 100644
--- a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.test.ts
+++ b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.test.ts
@@ -25,6 +25,14 @@ describe('KibanaVersionMismatchAlert', () => {
expect(alert.defaultThrottle).toBe('1d');
// @ts-ignore
expect(alert.actionVariables).toStrictEqual([
+ {
+ name: 'versionList',
+ description: 'The versions of Kibana running in this cluster.',
+ },
+ {
+ name: 'clusterName',
+ description: 'The cluster to which the instances belong.',
+ },
{
name: 'internalShortMessage',
description: 'The short internal message generated by Elastic.',
@@ -34,14 +42,6 @@ describe('KibanaVersionMismatchAlert', () => {
description: 'The full internal message generated by Elastic.',
},
{ name: 'state', description: 'The current state of the alert.' },
- {
- name: 'versionList',
- description: 'The versions of Kibana running in this cluster.',
- },
- {
- name: 'clusterName',
- description: 'The cluster to which the instances belong.',
- },
{ name: 'action', description: 'The recommended action for this alert.' },
{
name: 'actionPlain',
@@ -135,7 +135,7 @@ describe('KibanaVersionMismatchAlert', () => {
alertStates: [
{
cluster: { clusterUuid: 'abc123', clusterName: 'testCluster' },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: {
@@ -150,11 +150,10 @@ describe('KibanaVersionMismatchAlert', () => {
],
});
expect(scheduleActions).toHaveBeenCalledWith('default', {
- action:
- '[View instances](http://localhost:5601/app/monitoring#kibana/instances?_g=(cluster_uuid:abc123))',
+ action: '[View instances](kibana/instances)',
actionPlain: 'Verify you have the same version across all instances.',
internalFullMessage:
- 'Kibana version mismatch alert is firing for testCluster. Kibana is running [8.0.0, 7.2.1]. [View instances](http://localhost:5601/app/monitoring#kibana/instances?_g=(cluster_uuid:abc123))',
+ 'Kibana version mismatch alert is firing for testCluster. Kibana is running [8.0.0, 7.2.1]. [View instances](kibana/instances)',
internalShortMessage:
'Kibana version mismatch alert is firing for testCluster. Verify you have the same version across all instances.',
versionList: '[8.0.0, 7.2.1]',
@@ -203,7 +202,7 @@ describe('KibanaVersionMismatchAlert', () => {
clusterUuid,
clusterName,
},
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: null,
@@ -235,7 +234,7 @@ describe('KibanaVersionMismatchAlert', () => {
alertStates: [
{
cluster: { clusterUuid, clusterName },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: false,
message: {
diff --git a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.ts b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.ts
index 80e8701933f56..316f305603964 100644
--- a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.ts
+++ b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_alert.ts
@@ -20,14 +20,9 @@ import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern';
import { AlertSeverity } from '../../common/enums';
import { CommonAlertParams } from '../../common/types';
import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts';
+import { AlertingDefaults } from './alerts_common';
const WATCH_NAME = 'kibana_version_mismatch';
-const RESOLVED = i18n.translate('xpack.monitoring.alerts.kibanaVersionMismatch.resolved', {
- defaultMessage: 'resolved',
-});
-const FIRING = i18n.translate('xpack.monitoring.alerts.kibanaVersionMismatch.firing', {
- defaultMessage: 'firing',
-});
export class KibanaVersionMismatchAlert extends BaseAlert {
public type = ALERT_KIBANA_VERSION_MISMATCH;
@@ -37,33 +32,6 @@ export class KibanaVersionMismatchAlert extends BaseAlert {
public isLegacy = true;
protected actionVariables = [
- {
- name: 'internalShortMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalShortMessage',
- {
- defaultMessage: 'The short internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'internalFullMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalFullMessage',
- {
- defaultMessage: 'The full internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'state',
- description: i18n.translate(
- 'xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.state',
- {
- defaultMessage: 'The current state of the alert.',
- }
- ),
- },
{
name: 'versionList',
description: i18n.translate(
@@ -82,24 +50,11 @@ export class KibanaVersionMismatchAlert extends BaseAlert {
}
),
},
- {
- name: 'action',
- description: i18n.translate(
- 'xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.action',
- {
- defaultMessage: 'The recommended action for this alert.',
- }
- ),
- },
- {
- name: 'actionPlain',
- description: i18n.translate(
- 'xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.actionPlain',
- {
- defaultMessage: 'The recommended action for this alert, without any markdown.',
- }
- ),
- },
+ AlertingDefaults.ALERT_TYPE.context.internalShortMessage,
+ AlertingDefaults.ALERT_TYPE.context.internalFullMessage,
+ AlertingDefaults.ALERT_TYPE.context.state,
+ AlertingDefaults.ALERT_TYPE.context.action,
+ AlertingDefaults.ALERT_TYPE.context.actionPlain,
];
protected async fetchData(
@@ -129,7 +84,6 @@ export class KibanaVersionMismatchAlert extends BaseAlert {
shouldFire: !legacyAlert.resolved_timestamp,
severity,
meta: legacyAlert,
- ccs: null,
});
return accum;
}, []);
@@ -198,7 +152,7 @@ export class KibanaVersionMismatchAlert extends BaseAlert {
},
}
),
- state: RESOLVED,
+ state: AlertingDefaults.ALERT_STATE.resolved,
clusterName: cluster.clusterName,
});
} else {
@@ -214,12 +168,7 @@ export class KibanaVersionMismatchAlert extends BaseAlert {
defaultMessage: 'View instances',
}
);
- const globalState = [`cluster_uuid:${cluster.clusterUuid}`];
- if (alertState.ccs) {
- globalState.push(`ccs:${alertState.ccs}`);
- }
- const url = `${this.kibanaUrl}/app/monitoring#kibana/instances?_g=(${globalState.join(',')})`;
- const action = `[${fullActionText}](${url})`;
+ const action = `[${fullActionText}](kibana/instances)`;
instance.scheduleActions('default', {
internalShortMessage: i18n.translate(
'xpack.monitoring.alerts.kibanaVersionMismatch.firing.internalShortMessage',
@@ -242,7 +191,7 @@ export class KibanaVersionMismatchAlert extends BaseAlert {
},
}
),
- state: FIRING,
+ state: AlertingDefaults.ALERT_STATE.firing,
clusterName: cluster.clusterName,
versionList: versions,
action,
diff --git a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.test.ts b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.test.ts
index da94e4af83802..74c300d971898 100644
--- a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.test.ts
+++ b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.test.ts
@@ -32,6 +32,8 @@ describe('LicenseExpirationAlert', () => {
expect(alert.defaultThrottle).toBe('1d');
// @ts-ignore
expect(alert.actionVariables).toStrictEqual([
+ { name: 'expiredDate', description: 'The date when the license expires.' },
+ { name: 'clusterName', description: 'The cluster to which the license belong.' },
{
name: 'internalShortMessage',
description: 'The short internal message generated by Elastic.',
@@ -41,9 +43,6 @@ describe('LicenseExpirationAlert', () => {
description: 'The full internal message generated by Elastic.',
},
{ name: 'state', description: 'The current state of the alert.' },
- { name: 'expiredDate', description: 'The date when the license expires.' },
-
- { name: 'clusterName', description: 'The cluster to which the license belong.' },
{ name: 'action', description: 'The recommended action for this alert.' },
{
name: 'actionPlain',
@@ -139,7 +138,7 @@ describe('LicenseExpirationAlert', () => {
alertStates: [
{
cluster: { clusterUuid, clusterName },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: {
@@ -177,11 +176,10 @@ describe('LicenseExpirationAlert', () => {
],
});
expect(scheduleActions).toHaveBeenCalledWith('default', {
- action:
- '[Please update your license.](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:abc123))',
+ action: '[Please update your license.](elasticsearch/nodes)',
actionPlain: 'Please update your license.',
internalFullMessage:
- 'License expiration alert is firing for testCluster. Your license expires in THE_DATE. [Please update your license.](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:abc123))',
+ 'License expiration alert is firing for testCluster. Your license expires in THE_DATE. [Please update your license.](elasticsearch/nodes)',
internalShortMessage:
'License expiration alert is firing for testCluster. Your license expires in THE_DATE. Please update your license.',
clusterName,
@@ -230,7 +228,7 @@ describe('LicenseExpirationAlert', () => {
clusterUuid,
clusterName,
},
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: null,
@@ -262,7 +260,7 @@ describe('LicenseExpirationAlert', () => {
alertStates: [
{
cluster: { clusterUuid, clusterName },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: false,
message: {
diff --git a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts
index 7a249db28d2db..f1412ff0fc91a 100644
--- a/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts
+++ b/x-pack/plugins/monitoring/server/alerts/license_expiration_alert.ts
@@ -28,13 +28,7 @@ import { AlertMessageTokenType } from '../../common/enums';
import { CommonAlertParams } from '../../common/types';
import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts';
import { mapLegacySeverity } from '../lib/alerts/map_legacy_severity';
-
-const RESOLVED = i18n.translate('xpack.monitoring.alerts.licenseExpiration.resolved', {
- defaultMessage: 'resolved',
-});
-const FIRING = i18n.translate('xpack.monitoring.alerts.licenseExpiration.firing', {
- defaultMessage: 'firing',
-});
+import { AlertingDefaults } from './alerts_common';
const WATCH_NAME = 'xpack_license_expiration';
@@ -45,33 +39,6 @@ export class LicenseExpirationAlert extends BaseAlert {
});
public isLegacy = true;
protected actionVariables = [
- {
- name: 'internalShortMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.licenseExpiration.actionVariables.internalShortMessage',
- {
- defaultMessage: 'The short internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'internalFullMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.licenseExpiration.actionVariables.internalFullMessage',
- {
- defaultMessage: 'The full internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'state',
- description: i18n.translate(
- 'xpack.monitoring.alerts.licenseExpiration.actionVariables.state',
- {
- defaultMessage: 'The current state of the alert.',
- }
- ),
- },
{
name: 'expiredDate',
description: i18n.translate(
@@ -90,24 +57,11 @@ export class LicenseExpirationAlert extends BaseAlert {
}
),
},
- {
- name: 'action',
- description: i18n.translate(
- 'xpack.monitoring.alerts.licenseExpiration.actionVariables.action',
- {
- defaultMessage: 'The recommended action for this alert.',
- }
- ),
- },
- {
- name: 'actionPlain',
- description: i18n.translate(
- 'xpack.monitoring.alerts.licenseExpiration.actionVariables.actionPlain',
- {
- defaultMessage: 'The recommended action for this alert, without any markdown.',
- }
- ),
- },
+ AlertingDefaults.ALERT_TYPE.context.internalShortMessage,
+ AlertingDefaults.ALERT_TYPE.context.internalFullMessage,
+ AlertingDefaults.ALERT_TYPE.context.state,
+ AlertingDefaults.ALERT_TYPE.context.action,
+ AlertingDefaults.ALERT_TYPE.context.actionPlain,
];
protected async fetchData(
@@ -135,7 +89,6 @@ export class LicenseExpirationAlert extends BaseAlert {
shouldFire: !legacyAlert.resolved_timestamp,
severity: mapLegacySeverity(legacyAlert.metadata.severity),
meta: legacyAlert,
- ccs: null,
});
return accum;
}, []);
@@ -211,7 +164,7 @@ export class LicenseExpirationAlert extends BaseAlert {
},
}
),
- state: RESOLVED,
+ state: AlertingDefaults.ALERT_STATE.resolved,
expiredDate: $expiry.format(FORMAT_DURATION_TEMPLATE_SHORT).trim(),
clusterName: cluster.clusterName,
});
@@ -219,14 +172,7 @@ export class LicenseExpirationAlert extends BaseAlert {
const actionText = i18n.translate('xpack.monitoring.alerts.licenseExpiration.action', {
defaultMessage: 'Please update your license.',
});
- const globalState = [`cluster_uuid:${cluster.clusterUuid}`];
- if (alertState.ccs) {
- globalState.push(`ccs:${alertState.ccs}`);
- }
- const url = `${this.kibanaUrl}/app/monitoring#elasticsearch/nodes?_g=(${globalState.join(
- ','
- )})`;
- const action = `[${actionText}](${url})`;
+ const action = `[${actionText}](elasticsearch/nodes)`;
const expiredDate = $expiry.format(FORMAT_DURATION_TEMPLATE_SHORT).trim();
instance.scheduleActions('default', {
internalShortMessage: i18n.translate(
@@ -251,7 +197,7 @@ export class LicenseExpirationAlert extends BaseAlert {
},
}
),
- state: FIRING,
+ state: AlertingDefaults.ALERT_STATE.firing,
expiredDate,
clusterName: cluster.clusterName,
action,
diff --git a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.test.ts b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.test.ts
index 5ed189014cc6e..d3729660040d8 100644
--- a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.test.ts
+++ b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.test.ts
@@ -25,6 +25,10 @@ describe('LogstashVersionMismatchAlert', () => {
expect(alert.defaultThrottle).toBe('1d');
// @ts-ignore
expect(alert.actionVariables).toStrictEqual([
+ {
+ name: 'versionList',
+ description: 'The versions of Logstash running in this cluster.',
+ },
{
name: 'internalShortMessage',
description: 'The short internal message generated by Elastic.',
@@ -34,10 +38,6 @@ describe('LogstashVersionMismatchAlert', () => {
description: 'The full internal message generated by Elastic.',
},
{ name: 'state', description: 'The current state of the alert.' },
- {
- name: 'versionList',
- description: 'The versions of Logstash running in this cluster.',
- },
{ name: 'clusterName', description: 'The cluster to which the nodes belong.' },
{ name: 'action', description: 'The recommended action for this alert.' },
{
@@ -132,7 +132,7 @@ describe('LogstashVersionMismatchAlert', () => {
alertStates: [
{
cluster: { clusterUuid: 'abc123', clusterName: 'testCluster' },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: {
@@ -147,11 +147,10 @@ describe('LogstashVersionMismatchAlert', () => {
],
});
expect(scheduleActions).toHaveBeenCalledWith('default', {
- action:
- '[View nodes](http://localhost:5601/app/monitoring#logstash/nodes?_g=(cluster_uuid:abc123))',
+ action: '[View nodes](logstash/nodes)',
actionPlain: 'Verify you have the same version across all nodes.',
internalFullMessage:
- 'Logstash version mismatch alert is firing for testCluster. Logstash is running [8.0.0, 7.2.1]. [View nodes](http://localhost:5601/app/monitoring#logstash/nodes?_g=(cluster_uuid:abc123))',
+ 'Logstash version mismatch alert is firing for testCluster. Logstash is running [8.0.0, 7.2.1]. [View nodes](logstash/nodes)',
internalShortMessage:
'Logstash version mismatch alert is firing for testCluster. Verify you have the same version across all nodes.',
versionList: '[8.0.0, 7.2.1]',
@@ -200,7 +199,7 @@ describe('LogstashVersionMismatchAlert', () => {
clusterUuid,
clusterName,
},
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: null,
@@ -232,7 +231,7 @@ describe('LogstashVersionMismatchAlert', () => {
alertStates: [
{
cluster: { clusterUuid, clusterName },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: false,
message: {
diff --git a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.ts b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.ts
index f996e54de28ef..37515e32e591a 100644
--- a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.ts
+++ b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_alert.ts
@@ -20,14 +20,9 @@ import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern';
import { AlertSeverity } from '../../common/enums';
import { CommonAlertParams } from '../../common/types';
import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts';
+import { AlertingDefaults } from './alerts_common';
const WATCH_NAME = 'logstash_version_mismatch';
-const RESOLVED = i18n.translate('xpack.monitoring.alerts.logstashVersionMismatch.resolved', {
- defaultMessage: 'resolved',
-});
-const FIRING = i18n.translate('xpack.monitoring.alerts.logstashVersionMismatch.firing', {
- defaultMessage: 'firing',
-});
export class LogstashVersionMismatchAlert extends BaseAlert {
public type = ALERT_LOGSTASH_VERSION_MISMATCH;
@@ -37,33 +32,6 @@ export class LogstashVersionMismatchAlert extends BaseAlert {
public isLegacy = true;
protected actionVariables = [
- {
- name: 'internalShortMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalShortMessage',
- {
- defaultMessage: 'The short internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'internalFullMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalFullMessage',
- {
- defaultMessage: 'The full internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'state',
- description: i18n.translate(
- 'xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.state',
- {
- defaultMessage: 'The current state of the alert.',
- }
- ),
- },
{
name: 'versionList',
description: i18n.translate(
@@ -73,33 +41,7 @@ export class LogstashVersionMismatchAlert extends BaseAlert {
}
),
},
- {
- name: 'clusterName',
- description: i18n.translate(
- 'xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.clusterName',
- {
- defaultMessage: 'The cluster to which the nodes belong.',
- }
- ),
- },
- {
- name: 'action',
- description: i18n.translate(
- 'xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.action',
- {
- defaultMessage: 'The recommended action for this alert.',
- }
- ),
- },
- {
- name: 'actionPlain',
- description: i18n.translate(
- 'xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.actionPlain',
- {
- defaultMessage: 'The recommended action for this alert, without any markdown.',
- }
- ),
- },
+ ...Object.values(AlertingDefaults.ALERT_TYPE.context),
];
protected async fetchData(
@@ -130,7 +72,6 @@ export class LogstashVersionMismatchAlert extends BaseAlert {
shouldFire: !legacyAlert.resolved_timestamp,
severity,
meta: legacyAlert,
- ccs: null,
});
return accum;
}, []);
@@ -202,7 +143,7 @@ export class LogstashVersionMismatchAlert extends BaseAlert {
},
}
),
- state: RESOLVED,
+ state: AlertingDefaults.ALERT_STATE.resolved,
clusterName: cluster.clusterName,
});
} else {
@@ -218,12 +159,7 @@ export class LogstashVersionMismatchAlert extends BaseAlert {
defaultMessage: 'View nodes',
}
);
- const globalState = [`cluster_uuid:${cluster.clusterUuid}`];
- if (alertState.ccs) {
- globalState.push(`ccs:${alertState.ccs}`);
- }
- const url = `${this.kibanaUrl}/app/monitoring#logstash/nodes?_g=(${globalState.join(',')})`;
- const action = `[${fullActionText}](${url})`;
+ const action = `[${fullActionText}](logstash/nodes)`;
instance.scheduleActions('default', {
internalShortMessage: i18n.translate(
'xpack.monitoring.alerts.logstashVersionMismatch.firing.internalShortMessage',
@@ -246,7 +182,7 @@ export class LogstashVersionMismatchAlert extends BaseAlert {
},
}
),
- state: FIRING,
+ state: AlertingDefaults.ALERT_STATE.firing,
clusterName: cluster.clusterName,
versionList: versions,
action,
diff --git a/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.test.ts b/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.test.ts
index ec2b19eb5dfae..63b061649027a 100644
--- a/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.test.ts
+++ b/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.test.ts
@@ -32,6 +32,9 @@ describe('NodesChangedAlert', () => {
expect(alert.defaultThrottle).toBe('1d');
// @ts-ignore
expect(alert.actionVariables).toStrictEqual([
+ { name: 'added', description: 'The list of nodes added to the cluster.' },
+ { name: 'removed', description: 'The list of nodes removed from the cluster.' },
+ { name: 'restarted', description: 'The list of nodes restarted in the cluster.' },
{
name: 'internalShortMessage',
description: 'The short internal message generated by Elastic.',
@@ -42,9 +45,6 @@ describe('NodesChangedAlert', () => {
},
{ name: 'state', description: 'The current state of the alert.' },
{ name: 'clusterName', description: 'The cluster to which the nodes belong.' },
- { name: 'added', description: 'The list of nodes added to the cluster.' },
- { name: 'removed', description: 'The list of nodes removed from the cluster.' },
- { name: 'restarted', description: 'The list of nodes restarted in the cluster.' },
{ name: 'action', description: 'The recommended action for this alert.' },
{
name: 'actionPlain',
@@ -145,7 +145,7 @@ describe('NodesChangedAlert', () => {
alertStates: [
{
cluster: { clusterUuid, clusterName },
- ccs: null,
+ ccs: undefined,
ui: {
isFiring: true,
message: {
@@ -160,11 +160,10 @@ describe('NodesChangedAlert', () => {
],
});
expect(scheduleActions).toHaveBeenCalledWith('default', {
- action:
- '[View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:abc123))',
+ action: '[View nodes](elasticsearch/nodes)',
actionPlain: 'Verify that you added, removed, or restarted nodes.',
internalFullMessage:
- 'Nodes changed alert is firing for testCluster. The following Elasticsearch nodes have been added: removed: restarted:test. [View nodes](http://localhost:5601/app/monitoring#elasticsearch/nodes?_g=(cluster_uuid:abc123))',
+ 'Nodes changed alert is firing for testCluster. The following Elasticsearch nodes have been added: removed: restarted:test. [View nodes](elasticsearch/nodes)',
internalShortMessage:
'Nodes changed alert is firing for testCluster. Verify that you added, removed, or restarted nodes.',
added: '',
@@ -212,7 +211,7 @@ describe('NodesChangedAlert', () => {
// clusterUuid,
// clusterName,
// },
- // ccs: null,
+ // ccs: undefined,
// ui: {
// isFiring: true,
// message: null,
@@ -243,7 +242,7 @@ describe('NodesChangedAlert', () => {
// alertStates: [
// {
// cluster: { clusterUuid, clusterName },
- // ccs: null,
+ // ccs: undefined,
// ui: {
// isFiring: false,
// message: {
diff --git a/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.ts b/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.ts
index 73f3ee055c928..e03e6ea53ab4e 100644
--- a/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.ts
+++ b/x-pack/plugins/monitoring/server/alerts/nodes_changed_alert.ts
@@ -21,14 +21,9 @@ import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern';
import { CommonAlertParams } from '../../common/types';
import { fetchLegacyAlerts } from '../lib/alerts/fetch_legacy_alerts';
import { mapLegacySeverity } from '../lib/alerts/map_legacy_severity';
+import { AlertingDefaults } from './alerts_common';
const WATCH_NAME = 'elasticsearch_nodes';
-const RESOLVED = i18n.translate('xpack.monitoring.alerts.nodesChanged.resolved', {
- defaultMessage: 'resolved',
-});
-const FIRING = i18n.translate('xpack.monitoring.alerts.nodesChanged.firing', {
- defaultMessage: 'firing',
-});
export class NodesChangedAlert extends BaseAlert {
public type = ALERT_NODES_CHANGED;
@@ -38,39 +33,6 @@ export class NodesChangedAlert extends BaseAlert {
public isLegacy = true;
protected actionVariables = [
- {
- name: 'internalShortMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.nodesChanged.actionVariables.internalShortMessage',
- {
- defaultMessage: 'The short internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'internalFullMessage',
- description: i18n.translate(
- 'xpack.monitoring.alerts.nodesChanged.actionVariables.internalFullMessage',
- {
- defaultMessage: 'The full internal message generated by Elastic.',
- }
- ),
- },
- {
- name: 'state',
- description: i18n.translate('xpack.monitoring.alerts.nodesChanged.actionVariables.state', {
- defaultMessage: 'The current state of the alert.',
- }),
- },
- {
- name: 'clusterName',
- description: i18n.translate(
- 'xpack.monitoring.alerts.nodesChanged.actionVariables.clusterName',
- {
- defaultMessage: 'The cluster to which the nodes belong.',
- }
- ),
- },
{
name: 'added',
description: i18n.translate('xpack.monitoring.alerts.nodesChanged.actionVariables.added', {
@@ -92,21 +54,7 @@ export class NodesChangedAlert extends BaseAlert {
}
),
},
- {
- name: 'action',
- description: i18n.translate('xpack.monitoring.alerts.nodesChanged.actionVariables.action', {
- defaultMessage: 'The recommended action for this alert.',
- }),
- },
- {
- name: 'actionPlain',
- description: i18n.translate(
- 'xpack.monitoring.alerts.nodesChanged.actionVariables.actionPlain',
- {
- defaultMessage: 'The recommended action for this alert, without any markdown.',
- }
- ),
- },
+ ...Object.values(AlertingDefaults.ALERT_TYPE.context),
];
private getNodeStates(legacyAlert: LegacyAlert): LegacyAlertNodesChangedList | undefined {
@@ -138,7 +86,6 @@ export class NodesChangedAlert extends BaseAlert {
shouldFire: true, // This alert always has a resolved timestamp
severity: mapLegacySeverity(legacyAlert.metadata.severity),
meta: legacyAlert,
- ccs: null,
});
return accum;
}, []);
@@ -234,7 +181,7 @@ export class NodesChangedAlert extends BaseAlert {
},
}
),
- state: RESOLVED,
+ state: AlertingDefaults.ALERT_STATE.resolved,
clusterName: cluster.clusterName,
});
} else {
@@ -244,14 +191,7 @@ export class NodesChangedAlert extends BaseAlert {
const fullActionText = i18n.translate('xpack.monitoring.alerts.nodesChanged.fullAction', {
defaultMessage: 'View nodes',
});
- const globalState = [`cluster_uuid:${cluster.clusterUuid}`];
- if (alertState.ccs) {
- globalState.push(`ccs:${alertState.ccs}`);
- }
- const url = `${this.kibanaUrl}/app/monitoring#elasticsearch/nodes?_g=(${globalState.join(
- ','
- )})`;
- const action = `[${fullActionText}](${url})`;
+ const action = `[${fullActionText}](elasticsearch/nodes)`;
const states = this.getNodeStates(legacyAlert) || { added: {}, removed: {}, restarted: {} };
const added = Object.values(states.added).join(',');
const removed = Object.values(states.removed).join(',');
@@ -280,7 +220,7 @@ export class NodesChangedAlert extends BaseAlert {
},
}
),
- state: FIRING,
+ state: AlertingDefaults.ALERT_STATE.firing,
clusterName: cluster.clusterName,
added,
removed,
diff --git a/x-pack/plugins/monitoring/server/alerts/types.d.ts b/x-pack/plugins/monitoring/server/alerts/types.d.ts
index b6c8427375841..b685dcaed790f 100644
--- a/x-pack/plugins/monitoring/server/alerts/types.d.ts
+++ b/x-pack/plugins/monitoring/server/alerts/types.d.ts
@@ -11,13 +11,14 @@ export interface AlertEnableAction {
config: { [key: string]: any };
}
-export interface AlertInstanceState extends BaseAlertInstanceState {
- alertStates: AlertState[];
+export interface AlertInstanceState {
+ alertStates: Array;
+ [x: string]: unknown;
}
export interface AlertState {
cluster: AlertCluster;
- ccs: string | null;
+ ccs?: string;
ui: AlertUiState;
}
@@ -27,6 +28,12 @@ export interface AlertCpuUsageState extends AlertState {
nodeName: string;
}
+export interface AlertDiskUsageState extends AlertState {
+ diskUsage: number;
+ nodeId: string;
+ nodeName?: string;
+}
+
export interface AlertUiState {
isFiring: boolean;
severity: AlertSeverity;
@@ -75,13 +82,21 @@ export interface AlertCpuUsageNodeStats {
containerUsage: number;
containerPeriods: number;
containerQuota: number;
- ccs: string | null;
+ ccs?: string;
+}
+
+export interface AlertDiskUsageNodeStats {
+ clusterUuid: string;
+ nodeId: string;
+ nodeName: string;
+ diskUsage: number;
+ ccs?: string;
}
export interface AlertData {
instanceKey: string;
clusterUuid: string;
- ccs: string | null;
+ ccs?: string;
shouldFire: boolean;
severity: AlertSeverity;
meta: any;
diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.test.ts
new file mode 100644
index 0000000000000..4e221d3ebb35a
--- /dev/null
+++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.test.ts
@@ -0,0 +1,71 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { fetchDiskUsageNodeStats } from './fetch_disk_usage_node_stats';
+
+describe('fetchDiskUsageNodeStats', () => {
+ let callCluster = jest.fn();
+ const clusters = [
+ {
+ clusterUuid: 'cluster123',
+ clusterName: 'test-cluster',
+ },
+ ];
+ const index = '.monitoring-es-*';
+ const duration = '5m';
+ const size = 10;
+
+ it('fetch normal stats', async () => {
+ callCluster = jest.fn().mockImplementation(() => {
+ return {
+ aggregations: {
+ clusters: {
+ buckets: [
+ {
+ key: clusters[0].clusterUuid,
+ nodes: {
+ buckets: [
+ {
+ key: 'theNodeId',
+ index: {
+ buckets: [
+ {
+ key: '.monitoring-es-*',
+ },
+ ],
+ },
+ name: {
+ buckets: [
+ {
+ key: 'theNodeName',
+ },
+ ],
+ },
+ usage_ratio_percentile: {
+ value: 10,
+ },
+ },
+ ],
+ },
+ },
+ ],
+ },
+ },
+ };
+ });
+
+ const result = await fetchDiskUsageNodeStats(callCluster, clusters, index, duration, size);
+ expect(result).toEqual([
+ {
+ clusterUuid: clusters[0].clusterUuid,
+ nodeName: 'theNodeName',
+ nodeId: 'theNodeId',
+ diskUsage: 10,
+ ccs: null,
+ },
+ ]);
+ });
+});
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
new file mode 100644
index 0000000000000..6201204ebebe0
--- /dev/null
+++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_disk_usage_node_stats.ts
@@ -0,0 +1,125 @@
+/*
+ * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
+ * or more contributor license agreements. Licensed under the Elastic License;
+ * you may not use this file except in compliance with the Elastic License.
+ */
+
+import { get } from 'lodash';
+import { AlertCluster, AlertDiskUsageNodeStats } from '../../alerts/types';
+
+export async function fetchDiskUsageNodeStats(
+ callCluster: any,
+ clusters: AlertCluster[],
+ index: string,
+ duration: string,
+ size: number
+): Promise {
+ const clustersIds = clusters.map((cluster) => cluster.clusterUuid);
+ const params = {
+ index,
+ filterPath: ['aggregations'],
+ body: {
+ size: 0,
+ query: {
+ bool: {
+ filter: [
+ {
+ terms: {
+ cluster_uuid: clustersIds,
+ },
+ },
+ {
+ term: {
+ type: 'node_stats',
+ },
+ },
+ {
+ range: {
+ timestamp: {
+ gte: `now-${duration}`,
+ },
+ },
+ },
+ ],
+ },
+ },
+ aggs: {
+ clusters: {
+ terms: {
+ field: 'cluster_uuid',
+ size,
+ include: clustersIds,
+ },
+ aggs: {
+ nodes: {
+ terms: {
+ field: 'node_stats.node_id',
+ size,
+ },
+ aggs: {
+ index: {
+ terms: {
+ field: '_index',
+ size: 1,
+ },
+ },
+ total_in_bytes: {
+ max: {
+ field: 'node_stats.fs.total.total_in_bytes',
+ },
+ },
+ available_in_bytes: {
+ max: {
+ field: 'node_stats.fs.total.available_in_bytes',
+ },
+ },
+ usage_ratio_percentile: {
+ bucket_script: {
+ buckets_path: {
+ available_in_bytes: 'available_in_bytes',
+ total_in_bytes: 'total_in_bytes',
+ },
+ script:
+ '100 - Math.floor((params.available_in_bytes / params.total_in_bytes) * 100)',
+ },
+ },
+ name: {
+ terms: {
+ field: 'source_node.name',
+ size: 1,
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ },
+ };
+
+ const response = await callCluster('search', params);
+ const stats: AlertDiskUsageNodeStats[] = [];
+ const { buckets: clusterBuckets = [] } = response.aggregations.clusters;
+
+ if (!clusterBuckets.length) {
+ return stats;
+ }
+
+ for (const clusterBucket of clusterBuckets) {
+ for (const node of clusterBucket.nodes.buckets) {
+ const indexName = get(node, 'index.buckets[0].key', '');
+ const diskUsage = Number(get(node, 'usage_ratio_percentile.value'));
+ if (isNaN(diskUsage) || diskUsage === undefined || diskUsage === null) {
+ continue;
+ }
+ stats.push({
+ diskUsage,
+ clusterUuid: clusterBucket.key,
+ nodeId: node.key,
+ nodeName: get(node, 'name.buckets[0].key'),
+ ccs: indexName.includes(':') ? indexName.split(':')[0] : null,
+ });
+ }
+ }
+ return stats;
+}
diff --git a/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts
index ff674195f0730..fdd7253550624 100644
--- a/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts
+++ b/x-pack/plugins/monitoring/server/lib/alerts/fetch_status.test.ts
@@ -85,7 +85,6 @@ describe('fetchStatus', () => {
alertStates = [
{
cluster: defaultClusterState,
- ccs: null,
ui: {
...defaultUiState,
isFiring: true,
@@ -111,7 +110,6 @@ describe('fetchStatus', () => {
alertStates = [
{
cluster: defaultClusterState,
- ccs: null,
ui: {
...defaultUiState,
resolvedMS: 1500,
diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json
index a26daffcd88d8..40e3f73f1a885 100644
--- a/x-pack/plugins/translations/translations/ja-JP.json
+++ b/x-pack/plugins/translations/translations/ja-JP.json
@@ -12238,40 +12238,24 @@
"xpack.monitoring.alerts.callout.warningLabel": "警告アラート",
"xpack.monitoring.alerts.clusterHealth.action.danger": "見つからないプライマリおよびレプリカシャードを割り当てます。",
"xpack.monitoring.alerts.clusterHealth.action.warning": "見つからないレプリカシャードを割り当てます。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.action": "このアラートに対する推奨されるアクション。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。",
"xpack.monitoring.alerts.clusterHealth.actionVariables.clusterHealth": "クラスターの正常性。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.clusterName": "ノードが属しているクラスター。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.state": "現在のアラートの状態。",
- "xpack.monitoring.alerts.clusterHealth.firing": "実行中",
"xpack.monitoring.alerts.clusterHealth.firing.internalFullMessage": "クラスター正常性アラートが{clusterName}に対して作動しています。現在の正常性は{health}です。{action}",
"xpack.monitoring.alerts.clusterHealth.firing.internalShortMessage": "クラスター正常性アラートが{clusterName}に対して作動しています。現在の正常性は{health}です。{actionText}",
"xpack.monitoring.alerts.clusterHealth.label": "クラスターの正常性",
"xpack.monitoring.alerts.clusterHealth.redMessage": "見つからないプライマリおよびレプリカシャードを割り当て",
- "xpack.monitoring.alerts.clusterHealth.resolved": "解決済み",
"xpack.monitoring.alerts.clusterHealth.resolved.internalFullMessage": "クラスター正常性アラートが{clusterName}に対して作動しています。",
"xpack.monitoring.alerts.clusterHealth.resolved.internalShortMessage": "クラスター正常性アラートが{clusterName}に対して作動しています。",
"xpack.monitoring.alerts.clusterHealth.ui.firingMessage": "Elasticsearchクラスターの正常性は{health}です。",
"xpack.monitoring.alerts.clusterHealth.ui.nextSteps.message1": "{message}. #start_linkView now#end_link",
"xpack.monitoring.alerts.clusterHealth.yellowMessage": "見つからないレプリカシャードを割り当て",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.action": "このアラートに対する推奨されるアクション。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.clusterName": "ノードが属しているクラスター。",
"xpack.monitoring.alerts.cpuUsage.actionVariables.count": "高CPU使用率を報告しているノード数。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。",
"xpack.monitoring.alerts.cpuUsage.actionVariables.nodes": "高CPU使用率を報告しているノードのリスト。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.state": "現在のアラートの状態。",
- "xpack.monitoring.alerts.cpuUsage.firing": "実行中",
"xpack.monitoring.alerts.cpuUsage.firing.internalFullMessage": "CPU使用状況アラートはCPU使用状況アラートは、クラスター{clusterName}の{count}個のノードで実行されています。{action}",
"xpack.monitoring.alerts.cpuUsage.firing.internalShortMessage": "CPU使用状況アラートは、クラスター{clusterName}の{count}個のノードで実行されています。{shortActionText}",
"xpack.monitoring.alerts.cpuUsage.fullAction": "ノードの表示",
"xpack.monitoring.alerts.cpuUsage.label": "CPU使用状況",
"xpack.monitoring.alerts.cpuUsage.paramDetails.duration.label": "平均を確認",
"xpack.monitoring.alerts.cpuUsage.paramDetails.threshold.label": "CPUが終了したときに通知",
- "xpack.monitoring.alerts.cpuUsage.resolved": "解決済み",
"xpack.monitoring.alerts.cpuUsage.resolved.internalFullMessage": "CPU使用状況アラートは、クラスター{clusterName}の{count}個のノードで解決されました。",
"xpack.monitoring.alerts.cpuUsage.resolved.internalShortMessage": "CPU使用状況アラートは、クラスター{clusterName}の{count}個のノードで解決されました。",
"xpack.monitoring.alerts.cpuUsage.shortAction": "影響を受けるノード全体のCPUレベルを検証します。",
@@ -12279,21 +12263,13 @@
"xpack.monitoring.alerts.cpuUsage.ui.nextSteps.hotThreads": "#start_linkCheck hot threads#end_link",
"xpack.monitoring.alerts.cpuUsage.ui.nextSteps.runningTasks": "#start_linkCheck long running tasks#end_link",
"xpack.monitoring.alerts.cpuUsage.ui.resolvedMessage": "ノード{nodeName}でのCPU使用状況は現在しきい値を下回っています。現在、#resolved時点で、{cpuUsage}%と報告されています。",
- "xpack.monitoring.alerts.cpuUsage.validation.duration": "有効な期間が必要です。",
- "xpack.monitoring.alerts.cpuUsage.validation.threshold": "有効な数字が必要です。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.action": "このアラートに対する推奨されるアクション。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。",
+ "xpack.monitoring.alerts.validation.duration": "有効な期間が必要です。",
+ "xpack.monitoring.alerts.validation.threshold": "有効な数字が必要です。",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.clusterHealth": "このクラスターを実行しているElasticsearchのバージョン。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.clusterName": "ノードが属しているクラスター。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.state": "現在のアラートの状態。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.firing": "実行中",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.firing.internalFullMessage": "{clusterName}に対してElasticsearchバージョン不一致アラートが実行されています。Elasticsearchは{versions}を実行しています。{action}",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.firing.internalShortMessage": "{clusterName}に対してElasticsearchバージョン不一致アラートが実行されています。{shortActionText}",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.fullAction": "ノードの表示",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.label": "Elasticsearchバージョン不一致",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved": "解決済み",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved.internalFullMessage": "{clusterName}のElasticsearchバージョン不一致アラートが解決されました。",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved.internalShortMessage": "{clusterName}のElasticsearchバージョン不一致アラートが解決されました。",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.shortAction": "すべてのノードのバージョンが同じことを確認してください。",
@@ -12303,19 +12279,12 @@
"xpack.monitoring.alerts.flyoutExpressions.timeUnits.hourLabel": "{timeValue, plural, one {時間} other {時間}}",
"xpack.monitoring.alerts.flyoutExpressions.timeUnits.minuteLabel": "{timeValue, plural, one {分} other {分}}",
"xpack.monitoring.alerts.flyoutExpressions.timeUnits.secondLabel": "{timeValue, plural, one {秒} other {秒}}",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.action": "このアラートに対する推奨されるアクション。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。",
"xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.clusterHealth": "このクラスターを実行しているKibanaのバージョン。",
"xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.clusterName": "インスタンスが属しているクラスター。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.state": "現在のアラートの状態。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.firing": "実行中",
"xpack.monitoring.alerts.kibanaVersionMismatch.firing.internalFullMessage": "{clusterName}に対してKibanaバージョン不一致アラートが実行されています。Kibanaは{versions}を実行しています。{action}",
"xpack.monitoring.alerts.kibanaVersionMismatch.firing.internalShortMessage": "{clusterName}に対してKibanaバージョン不一致アラートが実行されています。{shortActionText}",
"xpack.monitoring.alerts.kibanaVersionMismatch.fullAction": "インスタンスを表示",
"xpack.monitoring.alerts.kibanaVersionMismatch.label": "Kibanaバージョン不一致",
- "xpack.monitoring.alerts.kibanaVersionMismatch.resolved": "解決済み",
"xpack.monitoring.alerts.kibanaVersionMismatch.resolved.internalFullMessage": "{clusterName}のKibanaバージョン不一致アラートが解決されました。",
"xpack.monitoring.alerts.kibanaVersionMismatch.resolved.internalShortMessage": "{clusterName}のKibanaバージョン不一致アラートが解決されました。",
"xpack.monitoring.alerts.kibanaVersionMismatch.shortAction": "すべてのインスタンスのバージョンが同じことを確認してください。",
@@ -12323,56 +12292,33 @@
"xpack.monitoring.alerts.kibanaVersionMismatch.ui.resolvedMessage": "このクラスターではすべてのKibanaのバージョンが同じです。",
"xpack.monitoring.alerts.legacyAlert.expressionText": "構成するものがありません。",
"xpack.monitoring.alerts.licenseExpiration.action": "ライセンスを更新してください。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.action": "このアラートに対する推奨されるアクション。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。",
"xpack.monitoring.alerts.licenseExpiration.actionVariables.clusterName": "ライセンスが属しているクラスター。",
"xpack.monitoring.alerts.licenseExpiration.actionVariables.expiredDate": "ライセンスの有効期限。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.state": "現在のアラートの状態。",
- "xpack.monitoring.alerts.licenseExpiration.firing": "実行中",
"xpack.monitoring.alerts.licenseExpiration.firing.internalFullMessage": "ライセンス有効期限アラートが{clusterName}に対して実行されています。ライセンスは{expiredDate}に期限切れになります。{action}",
"xpack.monitoring.alerts.licenseExpiration.firing.internalShortMessage": "{clusterName}に対してライセンス有効期限アラートが実行されています。ライセンスは{expiredDate}に期限切れになります。{actionText}",
"xpack.monitoring.alerts.licenseExpiration.label": "ライセンス期限",
- "xpack.monitoring.alerts.licenseExpiration.resolved": "解決済み",
"xpack.monitoring.alerts.licenseExpiration.resolved.internalFullMessage": "{clusterName}のライセンス有効期限アラートが解決されました。",
"xpack.monitoring.alerts.licenseExpiration.resolved.internalShortMessage": "{clusterName}のライセンス有効期限アラートが解決されました。",
"xpack.monitoring.alerts.licenseExpiration.ui.firingMessage": "このクラスターのライセンスは#absoluteの#relativeに期限切れになります。#start_linkライセンスを更新してください。#end_link",
"xpack.monitoring.alerts.licenseExpiration.ui.resolvedMessage": "このクラスターのライセンスは有効です。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.action": "このアラートに対する推奨されるアクション。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。",
"xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.clusterHealth": "このクラスターを実行しているLogstashのバージョン。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.clusterName": "ノードが属しているクラスター。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.state": "現在のアラートの状態。",
- "xpack.monitoring.alerts.logstashVersionMismatch.firing": "実行中",
"xpack.monitoring.alerts.logstashVersionMismatch.firing.internalFullMessage": "{clusterName}に対してLogstashバージョン不一致アラートが実行されています。Logstashは{versions}を実行しています。{action}",
"xpack.monitoring.alerts.logstashVersionMismatch.firing.internalShortMessage": "{clusterName}に対してLogstashバージョン不一致アラートが実行されています。{shortActionText}",
"xpack.monitoring.alerts.logstashVersionMismatch.fullAction": "ノードの表示",
"xpack.monitoring.alerts.logstashVersionMismatch.label": "Logstashバージョン不一致",
- "xpack.monitoring.alerts.logstashVersionMismatch.resolved": "解決済み",
"xpack.monitoring.alerts.logstashVersionMismatch.resolved.internalFullMessage": "{clusterName}のLogstashバージョン不一致アラートが解決されました。",
"xpack.monitoring.alerts.logstashVersionMismatch.resolved.internalShortMessage": "{clusterName}のLogstashバージョン不一致アラートが解決されました。",
"xpack.monitoring.alerts.logstashVersionMismatch.shortAction": "すべてのノードのバージョンが同じことを確認してください。",
"xpack.monitoring.alerts.logstashVersionMismatch.ui.firingMessage": "このクラスターでは、複数のバージョンのLogstash({versions})が実行されています。",
"xpack.monitoring.alerts.logstashVersionMismatch.ui.resolvedMessage": "このクラスターではすべてのLogstashのバージョンが同じです。",
"xpack.monitoring.alerts.migrate.manageAction.requiredFieldError": "{field} は必須フィールドです。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.action": "このアラートに対する推奨されるアクション。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.actionPlain": "このアラートに推奨されるアクション(Markdownなし)。",
"xpack.monitoring.alerts.nodesChanged.actionVariables.added": "ノードのリストがクラスターに追加されました。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.clusterName": "ノードが属しているクラスター。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.internalFullMessage": "詳細な内部メッセージはElasticで生成されました。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.internalShortMessage": "内部メッセージ(省略あり)はElasticで生成されました。",
"xpack.monitoring.alerts.nodesChanged.actionVariables.removed": "ノードのリストがクラスターから削除されました。",
"xpack.monitoring.alerts.nodesChanged.actionVariables.restarted": "ノードのリストがクラスターで再起動しました。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.state": "現在のアラートの状態。",
- "xpack.monitoring.alerts.nodesChanged.firing": "実行中",
"xpack.monitoring.alerts.nodesChanged.firing.internalFullMessage": "{clusterName}に対してノード変更アラートが実行されています。次のElasticsearchノードが追加されました:{added}、削除:{removed}、再起動:{restarted}。{action}",
"xpack.monitoring.alerts.nodesChanged.firing.internalShortMessage": "{clusterName}に対してノード変更アラートが実行されています。{shortActionText}",
"xpack.monitoring.alerts.nodesChanged.fullAction": "ノードの表示",
"xpack.monitoring.alerts.nodesChanged.label": "ノードが変更されました",
- "xpack.monitoring.alerts.nodesChanged.resolved": "解決済み",
"xpack.monitoring.alerts.nodesChanged.resolved.internalFullMessage": "{clusterName}のElasticsearchノード変更アラートが解決されました。",
"xpack.monitoring.alerts.nodesChanged.resolved.internalShortMessage": "{clusterName}のElasticsearchノード変更アラートが解決されました。",
"xpack.monitoring.alerts.nodesChanged.shortAction": "ノードを追加、削除、または再起動したことを確認してください。",
diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json
index 444fff9efa8b7..31cb0e5f96719 100644
--- a/x-pack/plugins/translations/translations/zh-CN.json
+++ b/x-pack/plugins/translations/translations/zh-CN.json
@@ -12246,41 +12246,25 @@
"xpack.monitoring.alerts.callout.warningLabel": "警告告警",
"xpack.monitoring.alerts.clusterHealth.action.danger": "分配缺失的主分片和副本分片。",
"xpack.monitoring.alerts.clusterHealth.action.warning": "分配缺失的副本分片。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.action": "此告警的建议操作。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。",
"xpack.monitoring.alerts.clusterHealth.actionVariables.clusterHealth": "集群的运行状况。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.clusterName": "节点所属的集群。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。",
- "xpack.monitoring.alerts.clusterHealth.actionVariables.state": "告警的当前状态。",
- "xpack.monitoring.alerts.clusterHealth.firing": "触发",
"xpack.monitoring.alerts.clusterHealth.firing.internalFullMessage": "为 {clusterName} 触发了集群运行状况告警。当前运行状况为 {health}。{action}",
"xpack.monitoring.alerts.clusterHealth.firing.internalShortMessage": "为 {clusterName} 触发了集群运行状况告警。当前运行状况为 {health}。{actionText}",
"xpack.monitoring.alerts.clusterHealth.label": "集群运行状况",
"xpack.monitoring.alerts.clusterHealth.redMessage": "分配缺失的主分片和副本分片",
- "xpack.monitoring.alerts.clusterHealth.resolved": "已解决",
"xpack.monitoring.alerts.clusterHealth.resolved.internalFullMessage": "已为 {clusterName} 解决集群运行状况告警。",
"xpack.monitoring.alerts.clusterHealth.resolved.internalShortMessage": "已为 {clusterName} 解决集群运行状况告警。",
"xpack.monitoring.alerts.clusterHealth.ui.firingMessage": "Elasticsearch 集群运行状况为 {health}。",
"xpack.monitoring.alerts.clusterHealth.ui.nextSteps.message1": "{message}。#start_linkView now#end_link",
"xpack.monitoring.alerts.clusterHealth.ui.resolvedMessage": "Elasticsearch 集群运行状况为绿色。",
"xpack.monitoring.alerts.clusterHealth.yellowMessage": "分配缺失的副本分片",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.action": "此告警的建议操作。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.clusterName": "节点所属的集群。",
"xpack.monitoring.alerts.cpuUsage.actionVariables.count": "报告高 CPU 使用率的节点数目。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。",
"xpack.monitoring.alerts.cpuUsage.actionVariables.nodes": "报告高 CPU 使用率的节点列表。",
- "xpack.monitoring.alerts.cpuUsage.actionVariables.state": "告警的当前状态。",
- "xpack.monitoring.alerts.cpuUsage.firing": "触发",
"xpack.monitoring.alerts.cpuUsage.firing.internalFullMessage": "为集群 {clusterName} 中 {count} 个节点触发了 CPU 使用率告警。{action}",
"xpack.monitoring.alerts.cpuUsage.firing.internalShortMessage": "为集群 {clusterName} 中 {count} 个节点触发了 CPU 使用率告警。{shortActionText}",
"xpack.monitoring.alerts.cpuUsage.fullAction": "查看节点",
"xpack.monitoring.alerts.cpuUsage.label": "CPU 使用率",
"xpack.monitoring.alerts.cpuUsage.paramDetails.duration.label": "查看以下范围的平均值:",
"xpack.monitoring.alerts.cpuUsage.paramDetails.threshold.label": "CPU 超过以下值时通知:",
- "xpack.monitoring.alerts.cpuUsage.resolved": "已解决",
"xpack.monitoring.alerts.cpuUsage.resolved.internalFullMessage": "已为集群 {clusterName} 中的 {count} 个节点解决 CPU 使用率告警。",
"xpack.monitoring.alerts.cpuUsage.resolved.internalShortMessage": "已为集群 {clusterName} 中的 {count} 个节点解决 CPU 使用率告警。",
"xpack.monitoring.alerts.cpuUsage.shortAction": "跨受影响节点验证 CPU 级别。",
@@ -12288,21 +12272,13 @@
"xpack.monitoring.alerts.cpuUsage.ui.nextSteps.hotThreads": "#start_link检查热线程#end_link",
"xpack.monitoring.alerts.cpuUsage.ui.nextSteps.runningTasks": "#start_link检查长时间运行的任务#end_link",
"xpack.monitoring.alerts.cpuUsage.ui.resolvedMessage": "节点 {nodeName} 上的 cpu 使用率现在低于阈值,当前报告截止到 #resolved 为 {cpuUsage}%",
- "xpack.monitoring.alerts.cpuUsage.validation.duration": "必须指定有效的持续时间。",
- "xpack.monitoring.alerts.cpuUsage.validation.threshold": "必须指定有效数字。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.action": "此告警的建议操作。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。",
+ "xpack.monitoring.alerts.validation.duration": "必须指定有效的持续时间。",
+ "xpack.monitoring.alerts.validation.threshold": "必须指定有效数字。",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.clusterHealth": "在此集群中运行的 Elasticsearch 版本。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.clusterName": "节点所属的集群。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.actionVariables.state": "告警的当前状态。",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.firing": "触发",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.firing.internalFullMessage": "为 {clusterName} 触发了 Elasticsearch 版本不匹配告警。Elasticsearch 正在运行 {versions}。{action}",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.firing.internalShortMessage": "为 {clusterName} 触发了 Elasticsearch 版本不匹配告警。{shortActionText}",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.fullAction": "查看节点",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.label": "Elasticsearch 版本不匹配",
- "xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved": "已解决",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved.internalFullMessage": "为 {clusterName} 解决了 Elasticsearch 版本不匹配告警。",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.resolved.internalShortMessage": "为 {clusterName} 解决了 Elasticsearch 版本不匹配告警。",
"xpack.monitoring.alerts.elasticsearchVersionMismatch.shortAction": "确认所有节点具有相同的版本。",
@@ -12312,19 +12288,12 @@
"xpack.monitoring.alerts.flyoutExpressions.timeUnits.hourLabel": "{timeValue, plural, one {小时} other {小时}}",
"xpack.monitoring.alerts.flyoutExpressions.timeUnits.minuteLabel": "{timeValue, plural, one {分钟} other {分钟}}",
"xpack.monitoring.alerts.flyoutExpressions.timeUnits.secondLabel": "{timeValue, plural, one {秒} other {秒}}",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.action": "此告警的建议操作。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。",
"xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.clusterHealth": "此集群中运行的 Kibana 版本。",
"xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.clusterName": "实例所属的集群。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.actionVariables.state": "告警的当前状态。",
- "xpack.monitoring.alerts.kibanaVersionMismatch.firing": "触发",
"xpack.monitoring.alerts.kibanaVersionMismatch.firing.internalFullMessage": "为 {clusterName} 触发了 Kibana 版本不匹配告警。Kibana 正在运行 {versions}。{action}",
"xpack.monitoring.alerts.kibanaVersionMismatch.firing.internalShortMessage": "为 {clusterName} 触发了 Kibana 版本不匹配告警。{shortActionText}",
"xpack.monitoring.alerts.kibanaVersionMismatch.fullAction": "查看实例",
"xpack.monitoring.alerts.kibanaVersionMismatch.label": "Kibana 版本不匹配",
- "xpack.monitoring.alerts.kibanaVersionMismatch.resolved": "已解决",
"xpack.monitoring.alerts.kibanaVersionMismatch.resolved.internalFullMessage": "为 {clusterName} 解决了 Kibana 版本不匹配告警。",
"xpack.monitoring.alerts.kibanaVersionMismatch.resolved.internalShortMessage": "为 {clusterName} 解决了 Kibana 版本不匹配告警。",
"xpack.monitoring.alerts.kibanaVersionMismatch.shortAction": "确认所有实例具有相同的版本。",
@@ -12332,56 +12301,33 @@
"xpack.monitoring.alerts.kibanaVersionMismatch.ui.resolvedMessage": "在此集群中所有 Kibana 版本都相同。",
"xpack.monitoring.alerts.legacyAlert.expressionText": "没有可配置的内容。",
"xpack.monitoring.alerts.licenseExpiration.action": "请更新您的许可证。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.action": "此告警的建议操作。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。",
"xpack.monitoring.alerts.licenseExpiration.actionVariables.clusterName": "许可证所属的集群。",
"xpack.monitoring.alerts.licenseExpiration.actionVariables.expiredDate": "许可证过期日期。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。",
- "xpack.monitoring.alerts.licenseExpiration.actionVariables.state": "告警的当前状态。",
- "xpack.monitoring.alerts.licenseExpiration.firing": "触发",
"xpack.monitoring.alerts.licenseExpiration.firing.internalFullMessage": "为 {clusterName} 触发了许可证到期告警。您的许可证将于 {expiredDate}到期。{action}",
"xpack.monitoring.alerts.licenseExpiration.firing.internalShortMessage": "为 {clusterName} 触发了许可证到期告警。您的许可证将于 {expiredDate}到期。{actionText}",
"xpack.monitoring.alerts.licenseExpiration.label": "许可证到期",
- "xpack.monitoring.alerts.licenseExpiration.resolved": "已解决",
"xpack.monitoring.alerts.licenseExpiration.resolved.internalFullMessage": "为 {clusterName} 解决了许可证到期告警。",
"xpack.monitoring.alerts.licenseExpiration.resolved.internalShortMessage": "为 {clusterName} 解决了许可证到期告警。",
"xpack.monitoring.alerts.licenseExpiration.ui.firingMessage": "此集群的许可证将于 #relative后,即 #absolute到期。 #start_link请更新您的许可证。#end_link",
"xpack.monitoring.alerts.licenseExpiration.ui.resolvedMessage": "此集群的许可证处于活动状态。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.action": "此告警的建议操作。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。",
"xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.clusterHealth": "此集群中运行的 Logstash 版本。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.clusterName": "节点所属的集群。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。",
- "xpack.monitoring.alerts.logstashVersionMismatch.actionVariables.state": "告警的当前状态。",
- "xpack.monitoring.alerts.logstashVersionMismatch.firing": "触发",
"xpack.monitoring.alerts.logstashVersionMismatch.firing.internalFullMessage": "为 {clusterName} 触发了 Logstash 版本不匹配告警。Logstash 正在运行 {versions}。{action}",
"xpack.monitoring.alerts.logstashVersionMismatch.firing.internalShortMessage": "为 {clusterName} 触发了 Logstash 版本不匹配告警。{shortActionText}",
"xpack.monitoring.alerts.logstashVersionMismatch.fullAction": "查看节点",
"xpack.monitoring.alerts.logstashVersionMismatch.label": "Logstash 版本不匹配",
- "xpack.monitoring.alerts.logstashVersionMismatch.resolved": "已解决",
"xpack.monitoring.alerts.logstashVersionMismatch.resolved.internalFullMessage": "为 {clusterName} 解决了 Logstash 版本不匹配告警。",
"xpack.monitoring.alerts.logstashVersionMismatch.resolved.internalShortMessage": "为 {clusterName} 解决了 Logstash 版本不匹配告警。",
"xpack.monitoring.alerts.logstashVersionMismatch.shortAction": "确认所有节点具有相同的版本。",
"xpack.monitoring.alerts.logstashVersionMismatch.ui.firingMessage": "在此集群中运行着多个 Logstash ({versions}) 版本。",
"xpack.monitoring.alerts.logstashVersionMismatch.ui.resolvedMessage": "在此集群中所有 Logstash 版本都相同。",
"xpack.monitoring.alerts.migrate.manageAction.requiredFieldError": "{field} 是必填字段。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.action": "此告警的建议操作。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.actionPlain": "此告警的建议操作,无任何 Markdown。",
"xpack.monitoring.alerts.nodesChanged.actionVariables.added": "添加到集群的节点列表。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.clusterName": "节点所属的集群。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.internalFullMessage": "Elastic 生成的完整内部消息。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.internalShortMessage": "Elastic 生成的简短内部消息。",
"xpack.monitoring.alerts.nodesChanged.actionVariables.removed": "从集群中移除的节点列表。",
"xpack.monitoring.alerts.nodesChanged.actionVariables.restarted": "在集群中重新启动的节点列表。",
- "xpack.monitoring.alerts.nodesChanged.actionVariables.state": "告警的当前状态。",
- "xpack.monitoring.alerts.nodesChanged.firing": "触发",
"xpack.monitoring.alerts.nodesChanged.firing.internalFullMessage": "为 {clusterName} 触发了节点已更改告警。以下 Elasticsearch 节点已添加:{added},以下已移除:{removed},以下已重新启动:{restarted}。{action}",
"xpack.monitoring.alerts.nodesChanged.firing.internalShortMessage": "为 {clusterName} 触发了节点已更改告警。{shortActionText}",
"xpack.monitoring.alerts.nodesChanged.fullAction": "查看节点",
"xpack.monitoring.alerts.nodesChanged.label": "已更改节点",
- "xpack.monitoring.alerts.nodesChanged.resolved": "已解决",
"xpack.monitoring.alerts.nodesChanged.resolved.internalFullMessage": "已为 {clusterName} 解决 Elasticsearch 节点已更改告警。",
"xpack.monitoring.alerts.nodesChanged.resolved.internalShortMessage": "已为 {clusterName} 解决 Elasticsearch 节点已更改告警。",
"xpack.monitoring.alerts.nodesChanged.shortAction": "确认您已添加、移除或重新启动节点。",