[Monitoring] change errors dir to typescript (#108297)
* change errors dir to ts * fix internationalization * fix internationalization * change test name
This commit is contained in:
parent
febcfa6ee3
commit
7ce9d07746
14 changed files with 218 additions and 157 deletions
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
import { forbidden, unauthorized } from '@hapi/boom';
|
||||
import { ResponseError } from '@elastic/elasticsearch/lib/errors';
|
||||
import { isAuthError, handleAuthError } from './auth_errors';
|
||||
|
||||
describe('Error handling for 401/403 errors', () => {
|
||||
|
@ -58,7 +59,19 @@ describe('Error handling for 401/403 errors', () => {
|
|||
|
||||
describe('Elasticsearch errors', () => {
|
||||
it('handles Forbidden error defined by ElasticsearchJS', () => {
|
||||
const err = { statusCode: 401 };
|
||||
const err = new ResponseError({
|
||||
statusCode: 401,
|
||||
body: {
|
||||
error: {
|
||||
type: 'Forbidden',
|
||||
},
|
||||
},
|
||||
warnings: [],
|
||||
headers: {
|
||||
'WWW-Authenticate': 'content',
|
||||
},
|
||||
meta: {} as any,
|
||||
});
|
||||
expect(isAuthError(err)).toBe(true);
|
||||
|
||||
const wrappedErr = handleAuthError(err);
|
||||
|
@ -78,7 +91,19 @@ describe('Error handling for 401/403 errors', () => {
|
|||
});
|
||||
|
||||
it('handles Unauthorized error defined by ElasticsearchJS', () => {
|
||||
const err = { statusCode: 403 };
|
||||
const err = new ResponseError({
|
||||
statusCode: 403,
|
||||
body: {
|
||||
error: {
|
||||
type: 'Unauthorized',
|
||||
},
|
||||
},
|
||||
warnings: [],
|
||||
headers: {
|
||||
'WWW-Authenticate': 'content',
|
||||
},
|
||||
meta: {} as any,
|
||||
});
|
||||
expect(isAuthError(err)).toBe(true);
|
||||
|
||||
const wrappedErr = handleAuthError(err);
|
|
@ -7,17 +7,15 @@
|
|||
|
||||
import { forbidden } from '@hapi/boom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { getStatusCode } from './handle_error';
|
||||
import { ErrorTypes } from '../../types';
|
||||
|
||||
const getStatusCode = (err) => {
|
||||
return err.isBoom ? err.output.statusCode : err.statusCode;
|
||||
};
|
||||
|
||||
export function isAuthError(err) {
|
||||
export function isAuthError(err: ErrorTypes) {
|
||||
const statusCode = getStatusCode(err);
|
||||
return statusCode === 401 || statusCode === 403;
|
||||
}
|
||||
|
||||
export function handleAuthError(err) {
|
||||
export function handleAuthError(err: ErrorTypes) {
|
||||
const statusCode = getStatusCode(err);
|
||||
|
||||
let message;
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { handleCustomError, isCustomError, MonitoringLicenseError } from './custom_errors';
|
||||
|
||||
describe('Error handling for custom monitoring errors', () => {
|
||||
it('handles the custom MonitoringLicenseError error', () => {
|
||||
const clusterName = 'main';
|
||||
const err = new MonitoringLicenseError(clusterName);
|
||||
expect(isCustomError(err)).toBe(true);
|
||||
|
||||
const wrappedErr = handleCustomError(err);
|
||||
expect(wrappedErr.message).toBe(
|
||||
'Monitoring License Error: ' +
|
||||
`Could not find license information for cluster = '${clusterName}'. ` +
|
||||
`Please check the cluster's master node server logs for errors or warnings.`
|
||||
);
|
||||
expect(wrappedErr.isBoom).toBe(true);
|
||||
expect(wrappedErr.isServer).toBe(true);
|
||||
expect(wrappedErr.data).toBe(null);
|
||||
expect(wrappedErr.output).toEqual({
|
||||
statusCode: 503,
|
||||
payload: {
|
||||
statusCode: 503,
|
||||
error: 'Service Unavailable',
|
||||
message:
|
||||
`Monitoring License Error: Could not find license information for cluster = '${clusterName}'. ` +
|
||||
`Please check the cluster's master node server logs for errors or warnings.`,
|
||||
},
|
||||
headers: {},
|
||||
});
|
||||
});
|
||||
});
|
|
@ -5,10 +5,21 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { boomify } from '@hapi/boom';
|
||||
import { ErrorTypes } from '../../types';
|
||||
|
||||
export class MonitoringLicenseError extends Error {
|
||||
constructor(clusterId) {
|
||||
export class MonitoringCustomError extends Error {
|
||||
readonly description?: string;
|
||||
constructor(message?: string) {
|
||||
super(message);
|
||||
this.name = this.constructor.name; // for stack traces
|
||||
}
|
||||
}
|
||||
export class MonitoringLicenseError extends MonitoringCustomError {
|
||||
readonly description: string;
|
||||
constructor(clusterId: string) {
|
||||
super();
|
||||
this.message = i18n.translate('xpack.monitoring.errors.monitoringLicenseErrorTitle', {
|
||||
defaultMessage: 'Monitoring License Error',
|
||||
|
@ -23,3 +34,14 @@ export class MonitoringLicenseError extends Error {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function isCustomError(err: ErrorTypes) {
|
||||
if (err instanceof MonitoringCustomError) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
export function handleCustomError(err: MonitoringCustomError) {
|
||||
err.message = err.message + ': ' + err.description;
|
||||
return boomify(err, { statusCode: 503 });
|
||||
}
|
|
@ -6,23 +6,21 @@
|
|||
*/
|
||||
|
||||
import { errors } from '@elastic/elasticsearch';
|
||||
import { isKnownError, handleKnownError } from './known_errors';
|
||||
import { MonitoringLicenseError } from './custom_errors';
|
||||
import { isESClientError, handleESClientError } from './esclient_errors';
|
||||
|
||||
// TODO: tests were not running and are not up to date
|
||||
describe.skip('Error handling for 503 errors', () => {
|
||||
describe('Error handling for ESClient errors', () => {
|
||||
it('ignores an unknown type', () => {
|
||||
const err = new Error();
|
||||
expect(isKnownError(err)).toBe(false);
|
||||
expect(isESClientError(err)).toBe(false);
|
||||
});
|
||||
|
||||
it('handles ConnectionError', () => {
|
||||
const err = new errors.ConnectionError();
|
||||
expect(isKnownError(err)).toBe(true);
|
||||
const err = new errors.ConnectionError('test 123', {} as any);
|
||||
expect(isESClientError(err)).toBe(true);
|
||||
|
||||
const wrappedErr = handleKnownError(err);
|
||||
const wrappedErr = handleESClientError(err);
|
||||
expect(wrappedErr.message).toBe(
|
||||
'Connection Failure: ' +
|
||||
'Connection error: ' +
|
||||
'Check the Elasticsearch Monitoring cluster network connection and refer to the Kibana logs for more information.'
|
||||
);
|
||||
expect(wrappedErr.isBoom).toBe(true);
|
||||
|
@ -34,7 +32,7 @@ describe.skip('Error handling for 503 errors', () => {
|
|||
statusCode: 503,
|
||||
error: 'Service Unavailable',
|
||||
message:
|
||||
'Connection Failure: ' +
|
||||
'Connection error: ' +
|
||||
'Check the Elasticsearch Monitoring cluster network connection and refer to the Kibana logs for more information.',
|
||||
},
|
||||
headers: {},
|
||||
|
@ -42,12 +40,12 @@ describe.skip('Error handling for 503 errors', () => {
|
|||
});
|
||||
|
||||
it('handles NoLivingConnectionsError', () => {
|
||||
const err = new errors.NoLivingConnectionsError();
|
||||
expect(isKnownError(err)).toBe(true);
|
||||
const err = new errors.NoLivingConnectionsError('test 123', {} as any);
|
||||
expect(isESClientError(err)).toBe(true);
|
||||
|
||||
const wrappedErr = handleKnownError(err);
|
||||
const wrappedErr = handleESClientError(err);
|
||||
expect(wrappedErr.message).toBe(
|
||||
'No Living connections: ' +
|
||||
'No living connections: ' +
|
||||
'Check the Elasticsearch Monitoring cluster network connection and refer to the Kibana logs for more information.'
|
||||
);
|
||||
expect(wrappedErr.isBoom).toBe(true);
|
||||
|
@ -59,7 +57,7 @@ describe.skip('Error handling for 503 errors', () => {
|
|||
statusCode: 503,
|
||||
error: 'Service Unavailable',
|
||||
message:
|
||||
'No Living connections: ' +
|
||||
'No living connections: ' +
|
||||
'Check the Elasticsearch Monitoring cluster network connection and refer to the Kibana logs for more information.',
|
||||
},
|
||||
headers: {},
|
||||
|
@ -67,12 +65,12 @@ describe.skip('Error handling for 503 errors', () => {
|
|||
});
|
||||
|
||||
it('handles TimeoutError', () => {
|
||||
const err = new errors.TimeoutError();
|
||||
expect(isKnownError(err)).toBe(true);
|
||||
const err = new errors.TimeoutError('test 123', {} as any);
|
||||
expect(isESClientError(err)).toBe(true);
|
||||
|
||||
const wrappedErr = handleKnownError(err);
|
||||
const wrappedErr = handleESClientError(err);
|
||||
expect(wrappedErr.message).toBe(
|
||||
'Request Timeout: ' +
|
||||
'Request timeout: ' +
|
||||
'Check the Elasticsearch Monitoring cluster network connection or the load level of the nodes.'
|
||||
);
|
||||
expect(wrappedErr.isBoom).toBe(true);
|
||||
|
@ -84,34 +82,7 @@ describe.skip('Error handling for 503 errors', () => {
|
|||
statusCode: 503,
|
||||
error: 'Service Unavailable',
|
||||
message:
|
||||
'Request Timeout: Check the Elasticsearch Monitoring cluster network connection or the load level of the nodes.',
|
||||
},
|
||||
headers: {},
|
||||
});
|
||||
});
|
||||
|
||||
it('handles the custom MonitoringLicenseError error', () => {
|
||||
const clusterName = 'main';
|
||||
const err = new MonitoringLicenseError(clusterName);
|
||||
expect(isKnownError(err)).toBe(true);
|
||||
|
||||
const wrappedErr = handleKnownError(err);
|
||||
expect(wrappedErr.message).toBe(
|
||||
'Monitoring License Error: ' +
|
||||
`Could not find license information for cluster = '${clusterName}'. ` +
|
||||
`Please check the cluster's master node server logs for errors or warnings.`
|
||||
);
|
||||
expect(wrappedErr.isBoom).toBe(true);
|
||||
expect(wrappedErr.isServer).toBe(true);
|
||||
expect(wrappedErr.data).toBe(null);
|
||||
expect(wrappedErr.output).toEqual({
|
||||
statusCode: 503,
|
||||
payload: {
|
||||
statusCode: 503,
|
||||
error: 'Service Unavailable',
|
||||
message:
|
||||
`Monitoring License Error: Could not find license information for cluster = '${clusterName}'. ` +
|
||||
`Please check the cluster's master node server logs for errors or warnings.`,
|
||||
'Request timeout: Check the Elasticsearch Monitoring cluster network connection or the load level of the nodes.',
|
||||
},
|
||||
headers: {},
|
||||
});
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ElasticsearchClientError } from '@elastic/elasticsearch/lib/errors';
|
||||
import { boomify } from '@hapi/boom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { ErrorTypes } from '../../types';
|
||||
|
||||
/*
|
||||
* Check if the given error message is a known "safe" type of error
|
||||
* in which case we want to give the status as 503 and show the error message.
|
||||
*
|
||||
* This is necessary because Boom's default status code is 500, and has
|
||||
* behavior to suppress the original message to the client for security
|
||||
* reasons.
|
||||
*/
|
||||
|
||||
const mapTypeMessage: { [key: string]: string } = {
|
||||
ConnectionError: i18n.translate('xpack.monitoring.errors.connectionErrorMessage', {
|
||||
defaultMessage:
|
||||
'Connection error: Check the Elasticsearch Monitoring cluster network connection and refer to the Kibana logs for more information.',
|
||||
}),
|
||||
NoLivingConnectionsError: i18n.translate(
|
||||
'xpack.monitoring.errors.noLivingConnectionsErrorMessage',
|
||||
{
|
||||
defaultMessage:
|
||||
'No living connections: Check the Elasticsearch Monitoring cluster network connection and refer to the Kibana logs for more information.',
|
||||
}
|
||||
),
|
||||
TimeoutError: i18n.translate('xpack.monitoring.errors.TimeoutErrorMessage', {
|
||||
defaultMessage:
|
||||
'Request timeout: Check the Elasticsearch Monitoring cluster network connection or the load level of the nodes.',
|
||||
}),
|
||||
};
|
||||
|
||||
export function isESClientError(err: ErrorTypes) {
|
||||
if (err instanceof ElasticsearchClientError === false) return false;
|
||||
const knownTypes = Object.keys(mapTypeMessage);
|
||||
return knownTypes.includes(err.constructor.name);
|
||||
}
|
||||
|
||||
export function handleESClientError(err: ElasticsearchClientError) {
|
||||
err.message = mapTypeMessage[err.constructor.name];
|
||||
return boomify(err, { statusCode: 503 });
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { boomify } from '@hapi/boom';
|
||||
import { isKnownError, handleKnownError } from './known_errors';
|
||||
import { isAuthError, handleAuthError } from './auth_errors';
|
||||
|
||||
export function handleError(err, req) {
|
||||
req && req.logger && req.logger.error(err);
|
||||
|
||||
// specially handle auth errors
|
||||
if (isAuthError(err)) {
|
||||
return handleAuthError(err);
|
||||
}
|
||||
|
||||
// specially "service unavailable" errors
|
||||
if (isKnownError(err)) {
|
||||
return handleKnownError(err);
|
||||
}
|
||||
|
||||
if (err.isBoom) {
|
||||
return err;
|
||||
}
|
||||
|
||||
// boom expects err.message, not err.msg
|
||||
if (err.msg) {
|
||||
err.message = err.msg;
|
||||
delete err.msg;
|
||||
}
|
||||
|
||||
const statusCode = err.isBoom ? err.output.statusCode : err.statusCode;
|
||||
// wrap the error; defaults to statusCode = 500 if statusCode is undefined
|
||||
return boomify(err, { statusCode, message: err.message });
|
||||
}
|
50
x-pack/plugins/monitoring/server/lib/errors/handle_error.ts
Normal file
50
x-pack/plugins/monitoring/server/lib/errors/handle_error.ts
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { boomify, isBoom } from '@hapi/boom';
|
||||
import { ResponseError } from '@elastic/elasticsearch/lib/errors';
|
||||
import { isCustomError, handleCustomError } from './custom_errors';
|
||||
import { isAuthError, handleAuthError } from './auth_errors';
|
||||
import { ErrorTypes, LegacyRequest } from '../../types';
|
||||
import { handleESClientError, isESClientError } from './esclient_errors';
|
||||
|
||||
export const getStatusCode = (err: ErrorTypes) => {
|
||||
return isBoom(err)
|
||||
? err.output.statusCode
|
||||
: err instanceof ResponseError
|
||||
? err.statusCode
|
||||
: undefined;
|
||||
};
|
||||
|
||||
export function handleError(err: ErrorTypes, req?: LegacyRequest) {
|
||||
if (req) {
|
||||
req.logger.error(err);
|
||||
}
|
||||
|
||||
// handle auth errors
|
||||
if (isAuthError(err)) {
|
||||
return handleAuthError(err);
|
||||
}
|
||||
|
||||
// handle custom Monitoring errors
|
||||
if (isCustomError(err)) {
|
||||
return handleCustomError(err);
|
||||
}
|
||||
|
||||
// handle certain EsClientError errors
|
||||
if (isESClientError(err)) {
|
||||
return handleESClientError(err);
|
||||
}
|
||||
|
||||
if (isBoom(err)) {
|
||||
return err;
|
||||
}
|
||||
|
||||
const statusCode = getStatusCode(err);
|
||||
// wrap the error; defaults to statusCode = 500 if statusCode is undefined
|
||||
return boomify(err, { statusCode, message: err.message });
|
||||
}
|
|
@ -6,7 +6,10 @@
|
|||
*/
|
||||
|
||||
import { boomify } from '@hapi/boom';
|
||||
import { ErrorTypes } from '../../types';
|
||||
import { getStatusCode } from './handle_error';
|
||||
|
||||
export function handleSettingsError(err) {
|
||||
return boomify(err, { statusCode: err.statusCode });
|
||||
export function handleSettingsError(err: ErrorTypes) {
|
||||
const statusCode = getStatusCode(err);
|
||||
return boomify(err, { statusCode });
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { boomify } from '@hapi/boom';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { MonitoringLicenseError } from './custom_errors';
|
||||
|
||||
/*
|
||||
* Check if the given error message is a known "safe" type of error
|
||||
* in which case we want to give the status as 503 and show the error message.
|
||||
*
|
||||
* This is necessary because Boom's default status code is 500, and has
|
||||
* behavior to suppress the original message to the client for security
|
||||
* reasons.
|
||||
*/
|
||||
const KNOWN_ERROR_STATUS_CODE = 503;
|
||||
|
||||
const mapTypeMessage = {
|
||||
ConnectionFault: i18n.translate('xpack.monitoring.errors.connectionFaultErrorMessage', {
|
||||
defaultMessage:
|
||||
'Check the Elasticsearch Monitoring cluster network connection and refer to the Kibana logs for more information.',
|
||||
}),
|
||||
NoConnections: i18n.translate('xpack.monitoring.errors.noConnectionsErrorMessage', {
|
||||
defaultMessage:
|
||||
'Check the Elasticsearch Monitoring cluster network connection and refer to the Kibana logs for more information.',
|
||||
}),
|
||||
StatusCodeError: i18n.translate('xpack.monitoring.errors.statusCodeErrorMessage', {
|
||||
defaultMessage:
|
||||
'Check the Elasticsearch Monitoring cluster network connection or the load level of the nodes.',
|
||||
}),
|
||||
};
|
||||
|
||||
const customErrors = [MonitoringLicenseError];
|
||||
|
||||
export function isKnownError(err) {
|
||||
for (const customError of customErrors) {
|
||||
if (err instanceof customError) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
const knownTypes = Object.keys(mapTypeMessage);
|
||||
return knownTypes.includes(err.constructor.name);
|
||||
}
|
||||
|
||||
export function handleKnownError(err) {
|
||||
err.message = err.message + ': ' + (err.description || mapTypeMessage[err.constructor.name]);
|
||||
let statusCode = err.statusCode || err.status;
|
||||
statusCode = statusCode !== 500 ? statusCode : KNOWN_ERROR_STATUS_CODE;
|
||||
return boomify(err, { statusCode });
|
||||
}
|
|
@ -13,6 +13,8 @@ import type {
|
|||
RequestHandlerContext,
|
||||
ElasticsearchClient,
|
||||
} from 'kibana/server';
|
||||
import type Boom from '@hapi/boom';
|
||||
import { ElasticsearchClientError, ResponseError } from '@elastic/elasticsearch/lib/errors';
|
||||
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
|
||||
import { LicenseFeature, ILicense } from '../../licensing/server';
|
||||
import type {
|
||||
|
@ -179,3 +181,5 @@ export interface ClusterSettingsReasonResponse {
|
|||
data?: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type ErrorTypes = Error | Boom.Boom | ResponseError | ElasticsearchClientError;
|
||||
|
|
|
@ -17385,13 +17385,10 @@
|
|||
"xpack.monitoring.elasticsearch.shardAllocation.unassignedDisplayName": "割り当てなし",
|
||||
"xpack.monitoring.elasticsearch.shardAllocation.unassignedPrimaryLabel": "未割り当てプライマリ",
|
||||
"xpack.monitoring.elasticsearch.shardAllocation.unassignedReplicaLabel": "未割り当てレプリカ",
|
||||
"xpack.monitoring.errors.connectionFaultErrorMessage": "Elasticsearch 監視クラスターのネットワーク接続を確認し、詳細は Kibana のログをご覧ください。",
|
||||
"xpack.monitoring.errors.insufficientUserErrorMessage": "データの監視に必要なユーザーパーミッションがありません",
|
||||
"xpack.monitoring.errors.invalidAuthErrorMessage": "クラスターの監視に無効な認証です",
|
||||
"xpack.monitoring.errors.monitoringLicenseErrorDescription": "クラスター = 「{clusterId}」のライセンス情報が見つかりませんでした。クラスターのマスターノードサーバーログにエラーや警告がないか確認してください。",
|
||||
"xpack.monitoring.errors.monitoringLicenseErrorTitle": "監視ライセンスエラー",
|
||||
"xpack.monitoring.errors.noConnectionsErrorMessage": "Elasticsearch 監視クラスターのネットワーク接続を確認し、詳細は Kibana のログをご覧ください。",
|
||||
"xpack.monitoring.errors.statusCodeErrorMessage": "Elasticsearch 監視クラスターのネットワーク接続、またはノードの負荷レベルを確認してください。",
|
||||
"xpack.monitoring.es.indices.deletedClosedStatusLabel": "削除済み / クローズ済み",
|
||||
"xpack.monitoring.es.indices.notAvailableStatusLabel": "利用不可",
|
||||
"xpack.monitoring.es.indices.unknownStatusLabel": "不明",
|
||||
|
|
|
@ -17796,13 +17796,10 @@
|
|||
"xpack.monitoring.elasticsearch.shardAllocation.unassignedDisplayName": "未分配",
|
||||
"xpack.monitoring.elasticsearch.shardAllocation.unassignedPrimaryLabel": "未分配主分片",
|
||||
"xpack.monitoring.elasticsearch.shardAllocation.unassignedReplicaLabel": "未分配副本分片",
|
||||
"xpack.monitoring.errors.connectionFaultErrorMessage": "检查 Elasticsearch Monitoring 集群网络连接,并参考 Kibana 日志以了解详情。",
|
||||
"xpack.monitoring.errors.insufficientUserErrorMessage": "对监测数据没有足够的用户权限",
|
||||
"xpack.monitoring.errors.invalidAuthErrorMessage": "监测集群的身份验证无效",
|
||||
"xpack.monitoring.errors.monitoringLicenseErrorDescription": "无法找到集群“{clusterId}”的许可信息。请在集群的主节点服务器日志中查看相关错误或警告。",
|
||||
"xpack.monitoring.errors.monitoringLicenseErrorTitle": "监测许可错误",
|
||||
"xpack.monitoring.errors.noConnectionsErrorMessage": "检查 Elasticsearch Monitoring 集群网络连接,并参考 Kibana 日志以了解详情。",
|
||||
"xpack.monitoring.errors.statusCodeErrorMessage": "检查 Elasticsearch Monitoring 集群网络连接或节点的负载水平。",
|
||||
"xpack.monitoring.es.indices.deletedClosedStatusLabel": "已删除 / 已关闭",
|
||||
"xpack.monitoring.es.indices.notAvailableStatusLabel": "不可用",
|
||||
"xpack.monitoring.es.indices.unknownStatusLabel": "未知",
|
||||
|
|
Loading…
Reference in a new issue