[Monitoring] Fetch shard data more efficiently (#54028)
* For the nodes listing page, do not fetch shard data for indices * Optimize our shard queries for the index and node listing pages * This change isn't necessary * Rename file and function * Use optimized query for ml jobs and es overview * Apply to node/index detail page, and more renaming * Unnecessary change * Fix tests * Add basic tests Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
934d6b3eeb
commit
bf7c25332e
|
@ -58,7 +58,7 @@ describe('getPaginatedNodes', () => {
|
|||
},
|
||||
},
|
||||
};
|
||||
const shardStats = {
|
||||
const nodesShardCount = {
|
||||
nodes: {
|
||||
1: {
|
||||
shardCount: 10,
|
||||
|
@ -78,7 +78,7 @@ describe('getPaginatedNodes', () => {
|
|||
pagination,
|
||||
sort,
|
||||
queryText,
|
||||
{ clusterStats, shardStats }
|
||||
{ clusterStats, nodesShardCount }
|
||||
);
|
||||
expect(nodes).toEqual({
|
||||
pageOfNodes: [
|
||||
|
@ -98,7 +98,7 @@ describe('getPaginatedNodes', () => {
|
|||
pagination,
|
||||
{ ...sort, field: 'foo', direction: 'desc' },
|
||||
queryText,
|
||||
{ clusterStats, shardStats }
|
||||
{ clusterStats, nodesShardCount }
|
||||
);
|
||||
expect(nodes).toEqual({
|
||||
pageOfNodes: [
|
||||
|
@ -118,7 +118,7 @@ describe('getPaginatedNodes', () => {
|
|||
pagination,
|
||||
sort,
|
||||
'tw',
|
||||
{ clusterStats, shardStats }
|
||||
{ clusterStats, nodesShardCount }
|
||||
);
|
||||
expect(nodes).toEqual({
|
||||
pageOfNodes: [{ name: 'two', uuid: 2, isOnline: false, shardCount: 5, foo: 12 }],
|
||||
|
|
|
@ -29,7 +29,7 @@ import { LISTING_METRICS_NAMES, LISTING_METRICS_PATHS } from './nodes_listing_me
|
|||
* @param {Object} shardStats: per-node information about shards
|
||||
* @return {Array} node info combined with metrics for each node from handle_response
|
||||
*/
|
||||
export async function getNodes(req, esIndexPattern, pageOfNodes, clusterStats, shardStats) {
|
||||
export async function getNodes(req, esIndexPattern, pageOfNodes, clusterStats, nodesShardCount) {
|
||||
checkParam(esIndexPattern, 'esIndexPattern in getNodes');
|
||||
|
||||
const start = moment.utc(req.payload.timeRange.min).valueOf();
|
||||
|
@ -104,5 +104,9 @@ export async function getNodes(req, esIndexPattern, pageOfNodes, clusterStats, s
|
|||
const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring');
|
||||
const response = await callWithRequest(req, 'search', params);
|
||||
|
||||
return handleResponse(response, clusterStats, shardStats, pageOfNodes, { min, max, bucketSize });
|
||||
return handleResponse(response, clusterStats, nodesShardCount, pageOfNodes, {
|
||||
min,
|
||||
max,
|
||||
bucketSize,
|
||||
});
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ export async function getPaginatedNodes(
|
|||
pagination,
|
||||
sort,
|
||||
queryText,
|
||||
{ clusterStats, shardStats }
|
||||
{ clusterStats, nodesShardCount }
|
||||
) {
|
||||
const config = req.server.config();
|
||||
const size = config.get('xpack.monitoring.max_bucket_size');
|
||||
|
@ -45,7 +45,7 @@ export async function getPaginatedNodes(
|
|||
const clusterState = get(clusterStats, 'cluster_state', { nodes: {} });
|
||||
for (const node of nodes) {
|
||||
node.isOnline = !isUndefined(get(clusterState, ['nodes', node.uuid]));
|
||||
node.shardCount = get(shardStats, `nodes[${node.uuid}].shardCount`, 0);
|
||||
node.shardCount = get(nodesShardCount, `nodes[${node.uuid}].shardCount`, 0);
|
||||
}
|
||||
|
||||
// `metricSet` defines a list of metrics that are sortable in the UI
|
||||
|
|
|
@ -13,17 +13,23 @@ import { uncovertMetricNames } from '../../convert_metric_names';
|
|||
* Process the response from the get_nodes query
|
||||
* @param {Object} response: response data from get_nodes
|
||||
* @param {Object} clusterStats: cluster stats from cluster state document
|
||||
* @param {Object} shardStats: per-node information about shards
|
||||
* @param {Object} nodesShardCount: per-node information about shards
|
||||
* @param {Object} timeOptions: min, max, and bucketSize needed for date histogram creation
|
||||
* @return {Array} node info combined with metrics for each node
|
||||
*/
|
||||
export function handleResponse(response, clusterStats, shardStats, pageOfNodes, timeOptions = {}) {
|
||||
export function handleResponse(
|
||||
response,
|
||||
clusterStats,
|
||||
nodesShardCount,
|
||||
pageOfNodes,
|
||||
timeOptions = {}
|
||||
) {
|
||||
if (!get(response, 'hits.hits')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const nodeHits = get(response, 'hits.hits', []);
|
||||
const nodesInfo = mapNodesInfo(nodeHits, clusterStats, shardStats);
|
||||
const nodesInfo = mapNodesInfo(nodeHits, clusterStats, nodesShardCount);
|
||||
|
||||
/*
|
||||
* Every node bucket is an object with a field for nodeId and fields for
|
||||
|
|
|
@ -10,10 +10,10 @@ import { calculateNodeType, getNodeTypeClassLabel } from '../';
|
|||
/**
|
||||
* @param {Array} nodeHits: info about each node from the hits in the get_nodes query
|
||||
* @param {Object} clusterStats: cluster stats from cluster state document
|
||||
* @param {Object} shardStats: per-node information about shards
|
||||
* @param {Object} nodesShardCount: per-node information about shards
|
||||
* @return {Object} summarized info about each node keyed by nodeId
|
||||
*/
|
||||
export function mapNodesInfo(nodeHits, clusterStats, shardStats) {
|
||||
export function mapNodesInfo(nodeHits, clusterStats, nodesShardCount) {
|
||||
const clusterState = get(clusterStats, 'cluster_state', { nodes: {} });
|
||||
|
||||
return nodeHits.reduce((prev, node) => {
|
||||
|
@ -35,7 +35,7 @@ export function mapNodesInfo(nodeHits, clusterStats, shardStats) {
|
|||
isOnline,
|
||||
nodeTypeLabel: nodeTypeLabel,
|
||||
nodeTypeClass: nodeTypeClass,
|
||||
shardCount: get(shardStats, `nodes[${sourceNode.uuid}].shardCount`, 0),
|
||||
shardCount: get(nodesShardCount, `nodes[${sourceNode.uuid}].shardCount`, 0),
|
||||
},
|
||||
};
|
||||
}, {});
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* 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 { checkParam } from '../../error_missing_required';
|
||||
import { createQuery } from '../../create_query';
|
||||
import { ElasticsearchMetric } from '../../metrics';
|
||||
import { calculateIndicesTotals } from './calculate_shard_stat_indices_totals';
|
||||
|
||||
async function getUnassignedShardData(req, esIndexPattern, cluster) {
|
||||
const config = req.server.config();
|
||||
const maxBucketSize = config.get('xpack.monitoring.max_bucket_size');
|
||||
const metric = ElasticsearchMetric.getMetricFields();
|
||||
|
||||
const params = {
|
||||
index: esIndexPattern,
|
||||
size: 0,
|
||||
ignoreUnavailable: true,
|
||||
body: {
|
||||
sort: { timestamp: { order: 'desc' } },
|
||||
query: createQuery({
|
||||
type: 'shards',
|
||||
clusterUuid: cluster.cluster_uuid,
|
||||
metric,
|
||||
filters: [{ term: { state_uuid: get(cluster, 'cluster_state.state_uuid') } }],
|
||||
}),
|
||||
aggs: {
|
||||
indices: {
|
||||
terms: {
|
||||
field: 'shard.index',
|
||||
size: maxBucketSize,
|
||||
},
|
||||
aggs: {
|
||||
state: {
|
||||
filter: {
|
||||
terms: {
|
||||
'shard.state': ['UNASSIGNED', 'INITIALIZING'],
|
||||
},
|
||||
},
|
||||
aggs: {
|
||||
primary: {
|
||||
terms: {
|
||||
field: 'shard.primary',
|
||||
size: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring');
|
||||
return await callWithRequest(req, 'search', params);
|
||||
}
|
||||
|
||||
export async function getIndicesUnassignedShardStats(req, esIndexPattern, cluster) {
|
||||
checkParam(esIndexPattern, 'esIndexPattern in elasticsearch/getShardStats');
|
||||
|
||||
const response = await getUnassignedShardData(req, esIndexPattern, cluster);
|
||||
const indices = get(response, 'aggregations.indices.buckets', []).reduce((accum, bucket) => {
|
||||
const index = bucket.key;
|
||||
const states = get(bucket, 'state.primary.buckets', []);
|
||||
const unassignedReplica = states
|
||||
.filter(state => state.key_as_string === 'false')
|
||||
.reduce((total, state) => total + state.doc_count, 0);
|
||||
const unassignedPrimary = states
|
||||
.filter(state => state.key_as_string === 'true')
|
||||
.reduce((total, state) => total + state.doc_count, 0);
|
||||
|
||||
let status = 'green';
|
||||
if (unassignedReplica > 0) {
|
||||
status = 'yellow';
|
||||
}
|
||||
if (unassignedPrimary > 0) {
|
||||
status = 'red';
|
||||
}
|
||||
|
||||
accum[index] = {
|
||||
unassigned: { primary: unassignedPrimary, replica: unassignedReplica },
|
||||
status,
|
||||
};
|
||||
return accum;
|
||||
}, {});
|
||||
|
||||
const indicesTotals = calculateIndicesTotals(indices);
|
||||
return { indices, indicesTotals };
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* 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 { getIndicesUnassignedShardStats } from './get_indices_unassigned_shard_stats';
|
||||
|
||||
describe('getIndicesUnassignedShardStats', () => {
|
||||
it('should return the unassigned shard stats for indices', async () => {
|
||||
const indices = {
|
||||
12345: { status: 'red', unassigned: { primary: 1, replica: 0 } },
|
||||
6789: { status: 'yellow', unassigned: { primary: 0, replica: 1 } },
|
||||
absdf82: { status: 'green', unassigned: { primary: 0, replica: 0 } },
|
||||
};
|
||||
|
||||
const req = {
|
||||
server: {
|
||||
config: () => ({
|
||||
get: () => {},
|
||||
}),
|
||||
plugins: {
|
||||
elasticsearch: {
|
||||
getCluster: () => ({
|
||||
callWithRequest: () => ({
|
||||
aggregations: {
|
||||
indices: {
|
||||
buckets: Object.keys(indices).map(id => ({
|
||||
key: id,
|
||||
state: {
|
||||
primary: {
|
||||
buckets:
|
||||
indices[id].unassigned.primary || indices[id].unassigned.replica
|
||||
? [
|
||||
{
|
||||
key_as_string: indices[id].unassigned.primary
|
||||
? 'true'
|
||||
: 'false',
|
||||
doc_count: 1,
|
||||
},
|
||||
]
|
||||
: [],
|
||||
},
|
||||
},
|
||||
})),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const esIndexPattern = '*';
|
||||
const cluster = {};
|
||||
const stats = await getIndicesUnassignedShardStats(req, esIndexPattern, cluster);
|
||||
expect(stats.indices).toEqual(indices);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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 { checkParam } from '../../error_missing_required';
|
||||
import { createQuery } from '../../create_query';
|
||||
import { ElasticsearchMetric } from '../../metrics';
|
||||
|
||||
async function getShardCountPerNode(req, esIndexPattern, cluster) {
|
||||
const config = req.server.config();
|
||||
const maxBucketSize = config.get('xpack.monitoring.max_bucket_size');
|
||||
const metric = ElasticsearchMetric.getMetricFields();
|
||||
|
||||
const params = {
|
||||
index: esIndexPattern,
|
||||
size: 0,
|
||||
ignoreUnavailable: true,
|
||||
body: {
|
||||
sort: { timestamp: { order: 'desc' } },
|
||||
query: createQuery({
|
||||
type: 'shards',
|
||||
clusterUuid: cluster.cluster_uuid,
|
||||
metric,
|
||||
filters: [{ term: { state_uuid: get(cluster, 'cluster_state.state_uuid') } }],
|
||||
}),
|
||||
aggs: {
|
||||
nodes: {
|
||||
terms: {
|
||||
field: 'shard.node',
|
||||
size: maxBucketSize,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring');
|
||||
return await callWithRequest(req, 'search', params);
|
||||
}
|
||||
|
||||
export async function getNodesShardCount(req, esIndexPattern, cluster) {
|
||||
checkParam(esIndexPattern, 'esIndexPattern in elasticsearch/getShardStats');
|
||||
|
||||
const response = await getShardCountPerNode(req, esIndexPattern, cluster);
|
||||
const nodes = get(response, 'aggregations.nodes.buckets', []).reduce((accum, bucket) => {
|
||||
accum[bucket.key] = { shardCount: bucket.doc_count };
|
||||
return accum;
|
||||
}, {});
|
||||
return { nodes };
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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 { getNodesShardCount } from './get_nodes_shard_count';
|
||||
|
||||
describe('getNodeShardCount', () => {
|
||||
it('should return the shard count per node', async () => {
|
||||
const nodes = {
|
||||
12345: { shardCount: 10 },
|
||||
6789: { shardCount: 1 },
|
||||
absdf82: { shardCount: 20 },
|
||||
};
|
||||
|
||||
const req = {
|
||||
server: {
|
||||
config: () => ({
|
||||
get: () => {},
|
||||
}),
|
||||
plugins: {
|
||||
elasticsearch: {
|
||||
getCluster: () => ({
|
||||
callWithRequest: () => ({
|
||||
aggregations: {
|
||||
nodes: {
|
||||
buckets: Object.keys(nodes).map(id => ({
|
||||
key: id,
|
||||
doc_count: nodes[id].shardCount,
|
||||
})),
|
||||
},
|
||||
},
|
||||
}),
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const esIndexPattern = '*';
|
||||
const cluster = {};
|
||||
const counts = await getNodesShardCount(req, esIndexPattern, cluster);
|
||||
expect(counts.nodes).toEqual(nodes);
|
||||
});
|
||||
});
|
|
@ -8,7 +8,7 @@
|
|||
* @param {Object} config - Kibana config service
|
||||
* @param {Boolean} includeNodes - whether to add the aggs for node shards
|
||||
*/
|
||||
export function getShardAggs(config, includeNodes) {
|
||||
export function getShardAggs(config, includeNodes, includeIndices) {
|
||||
const maxBucketSize = config.get('xpack.monitoring.max_bucket_size');
|
||||
const aggSize = 10;
|
||||
const indicesAgg = {
|
||||
|
@ -40,7 +40,7 @@ export function getShardAggs(config, includeNodes) {
|
|||
};
|
||||
|
||||
return {
|
||||
...{ indices: indicesAgg },
|
||||
...{ indices: includeIndices ? indicesAgg : undefined },
|
||||
...{ nodes: includeNodes ? nodesAgg : undefined },
|
||||
};
|
||||
}
|
||||
|
|
|
@ -21,11 +21,11 @@ export function handleResponse(resp, includeNodes, includeIndices, cluster) {
|
|||
if (buckets && buckets.length !== 0) {
|
||||
indices = buckets.reduce(normalizeIndexShards, {});
|
||||
indicesTotals = calculateIndicesTotals(indices);
|
||||
}
|
||||
|
||||
if (includeNodes) {
|
||||
const masterNode = get(cluster, 'cluster_state.master_node');
|
||||
nodes = resp.aggregations.nodes.buckets.reduce(normalizeNodeShards(masterNode), {});
|
||||
}
|
||||
if (includeNodes) {
|
||||
const masterNode = get(cluster, 'cluster_state.master_node');
|
||||
nodes = resp.aggregations.nodes.buckets.reduce(normalizeNodeShards(masterNode), {});
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -39,12 +39,19 @@ export function getShardStats(
|
|||
req,
|
||||
esIndexPattern,
|
||||
cluster,
|
||||
{ includeNodes = false, includeIndices = false } = {}
|
||||
{ includeNodes = false, includeIndices = false, indexName = null, nodeUuid = null } = {}
|
||||
) {
|
||||
checkParam(esIndexPattern, 'esIndexPattern in elasticsearch/getShardStats');
|
||||
|
||||
const config = req.server.config();
|
||||
const metric = ElasticsearchMetric.getMetricFields();
|
||||
const filters = [{ term: { state_uuid: get(cluster, 'cluster_state.state_uuid') } }];
|
||||
if (indexName) {
|
||||
filters.push({ term: { 'shard.index': indexName } });
|
||||
}
|
||||
if (nodeUuid) {
|
||||
filters.push({ term: { 'shard.node': nodeUuid } });
|
||||
}
|
||||
const params = {
|
||||
index: esIndexPattern,
|
||||
size: 0,
|
||||
|
@ -55,10 +62,10 @@ export function getShardStats(
|
|||
type: 'shards',
|
||||
clusterUuid: cluster.cluster_uuid,
|
||||
metric,
|
||||
filters: [{ term: { state_uuid: get(cluster, 'cluster_state.state_uuid') } }],
|
||||
filters,
|
||||
}),
|
||||
aggs: {
|
||||
...getShardAggs(config, includeNodes),
|
||||
...getShardAggs(config, includeNodes, includeIndices),
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -60,6 +60,7 @@ export function esIndexRoute(server) {
|
|||
const shardStats = await getShardStats(req, esIndexPattern, cluster, {
|
||||
includeNodes: true,
|
||||
includeIndices: true,
|
||||
indexName: indexUuid,
|
||||
});
|
||||
const indexSummary = await getIndexSummary(req, esIndexPattern, shardStats, {
|
||||
clusterUuid,
|
||||
|
|
|
@ -8,10 +8,10 @@ import Joi from 'joi';
|
|||
import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats';
|
||||
import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status';
|
||||
import { getIndices } from '../../../../lib/elasticsearch/indices';
|
||||
import { getShardStats } from '../../../../lib/elasticsearch/shards';
|
||||
import { handleError } from '../../../../lib/errors/handle_error';
|
||||
import { prefixIndexPattern } from '../../../../lib/ccs_utils';
|
||||
import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants';
|
||||
import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats';
|
||||
|
||||
export function esIndicesRoute(server) {
|
||||
server.route({
|
||||
|
@ -43,13 +43,20 @@ export function esIndicesRoute(server) {
|
|||
|
||||
try {
|
||||
const clusterStats = await getClusterStats(req, esIndexPattern, clusterUuid);
|
||||
const shardStats = await getShardStats(req, esIndexPattern, clusterStats, {
|
||||
includeIndices: true,
|
||||
});
|
||||
const indices = await getIndices(req, esIndexPattern, showSystemIndices, shardStats);
|
||||
const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(
|
||||
req,
|
||||
esIndexPattern,
|
||||
clusterStats
|
||||
);
|
||||
const indices = await getIndices(
|
||||
req,
|
||||
esIndexPattern,
|
||||
showSystemIndices,
|
||||
indicesUnassignedShardStats
|
||||
);
|
||||
|
||||
return {
|
||||
clusterStatus: getClusterStatus(clusterStats, shardStats),
|
||||
clusterStatus: getClusterStatus(clusterStats, indicesUnassignedShardStats),
|
||||
indices,
|
||||
};
|
||||
} catch (err) {
|
||||
|
|
|
@ -8,10 +8,10 @@ import Joi from 'joi';
|
|||
import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats';
|
||||
import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status';
|
||||
import { getMlJobs } from '../../../../lib/elasticsearch/get_ml_jobs';
|
||||
import { getShardStats } from '../../../../lib/elasticsearch/shards';
|
||||
import { handleError } from '../../../../lib/errors/handle_error';
|
||||
import { prefixIndexPattern } from '../../../../lib/ccs_utils';
|
||||
import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants';
|
||||
import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats';
|
||||
|
||||
export function mlJobRoute(server) {
|
||||
server.route({
|
||||
|
@ -39,11 +39,15 @@ export function mlJobRoute(server) {
|
|||
|
||||
try {
|
||||
const clusterStats = await getClusterStats(req, esIndexPattern, clusterUuid);
|
||||
const shardStats = await getShardStats(req, esIndexPattern, clusterStats);
|
||||
const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(
|
||||
req,
|
||||
esIndexPattern,
|
||||
clusterStats
|
||||
);
|
||||
const rows = await getMlJobs(req, esIndexPattern);
|
||||
|
||||
return {
|
||||
clusterStatus: getClusterStatus(clusterStats, shardStats),
|
||||
clusterStatus: getClusterStatus(clusterStats, indicesUnassignedShardStats),
|
||||
rows,
|
||||
};
|
||||
} catch (err) {
|
||||
|
|
|
@ -78,6 +78,7 @@ export function esNodeRoute(server) {
|
|||
const shardStats = await getShardStats(req, esIndexPattern, cluster, {
|
||||
includeIndices: true,
|
||||
includeNodes: true,
|
||||
nodeUuid,
|
||||
});
|
||||
const nodeSummary = await getNodeSummary(req, esIndexPattern, clusterState, shardStats, {
|
||||
clusterUuid,
|
||||
|
|
|
@ -8,12 +8,13 @@ import Joi from 'joi';
|
|||
import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats';
|
||||
import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status';
|
||||
import { getNodes } from '../../../../lib/elasticsearch/nodes';
|
||||
import { getShardStats } from '../../../../lib/elasticsearch/shards';
|
||||
import { getNodesShardCount } from '../../../../lib/elasticsearch/shards/get_nodes_shard_count';
|
||||
import { handleError } from '../../../../lib/errors/handle_error';
|
||||
import { prefixIndexPattern } from '../../../../lib/ccs_utils';
|
||||
import { INDEX_PATTERN_ELASTICSEARCH } from '../../../../../common/constants';
|
||||
import { getPaginatedNodes } from '../../../../lib/elasticsearch/nodes/get_nodes/get_paginated_nodes';
|
||||
import { LISTING_METRICS_NAMES } from '../../../../lib/elasticsearch/nodes/get_nodes/nodes_listing_metrics';
|
||||
import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats';
|
||||
|
||||
export function esNodesRoute(server) {
|
||||
server.route({
|
||||
|
@ -53,10 +54,13 @@ export function esNodesRoute(server) {
|
|||
|
||||
try {
|
||||
const clusterStats = await getClusterStats(req, esIndexPattern, clusterUuid);
|
||||
const shardStats = await getShardStats(req, esIndexPattern, clusterStats, {
|
||||
includeNodes: true,
|
||||
});
|
||||
const clusterStatus = getClusterStatus(clusterStats, shardStats);
|
||||
const nodesShardCount = await getNodesShardCount(req, esIndexPattern, clusterStats);
|
||||
const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(
|
||||
req,
|
||||
esIndexPattern,
|
||||
clusterStats
|
||||
);
|
||||
const clusterStatus = getClusterStatus(clusterStats, indicesUnassignedShardStats);
|
||||
|
||||
const metricSet = LISTING_METRICS_NAMES;
|
||||
const { pageOfNodes, totalNodeCount } = await getPaginatedNodes(
|
||||
|
@ -69,11 +73,17 @@ export function esNodesRoute(server) {
|
|||
queryText,
|
||||
{
|
||||
clusterStats,
|
||||
shardStats,
|
||||
nodesShardCount,
|
||||
}
|
||||
);
|
||||
|
||||
const nodes = await getNodes(req, esIndexPattern, pageOfNodes, clusterStats, shardStats);
|
||||
const nodes = await getNodes(
|
||||
req,
|
||||
esIndexPattern,
|
||||
pageOfNodes,
|
||||
clusterStats,
|
||||
nodesShardCount
|
||||
);
|
||||
return { clusterStatus, nodes, totalNodeCount };
|
||||
} catch (err) {
|
||||
throw handleError(err, req);
|
||||
|
|
|
@ -9,7 +9,6 @@ import { getClusterStats } from '../../../../lib/cluster/get_cluster_stats';
|
|||
import { getClusterStatus } from '../../../../lib/cluster/get_cluster_status';
|
||||
import { getLastRecovery } from '../../../../lib/elasticsearch/get_last_recovery';
|
||||
import { getMetrics } from '../../../../lib/details/get_metrics';
|
||||
import { getShardStats } from '../../../../lib/elasticsearch/shards';
|
||||
import { handleError } from '../../../../lib/errors/handle_error';
|
||||
import { prefixIndexPattern } from '../../../../lib/ccs_utils';
|
||||
import { metricSet } from './metric_set_overview';
|
||||
|
@ -18,6 +17,7 @@ import {
|
|||
INDEX_PATTERN_FILEBEAT,
|
||||
} from '../../../../../common/constants';
|
||||
import { getLogs } from '../../../../lib/logs';
|
||||
import { getIndicesUnassignedShardStats } from '../../../../lib/elasticsearch/shards/get_indices_unassigned_shard_stats';
|
||||
|
||||
export function esOverviewRoute(server) {
|
||||
server.route({
|
||||
|
@ -54,10 +54,14 @@ export function esOverviewRoute(server) {
|
|||
getLastRecovery(req, esIndexPattern),
|
||||
getLogs(config, req, filebeatIndexPattern, { clusterUuid, start, end }),
|
||||
]);
|
||||
const shardStats = await getShardStats(req, esIndexPattern, clusterStats);
|
||||
const indicesUnassignedShardStats = await getIndicesUnassignedShardStats(
|
||||
req,
|
||||
esIndexPattern,
|
||||
clusterStats
|
||||
);
|
||||
|
||||
return {
|
||||
clusterStatus: getClusterStatus(clusterStats, shardStats),
|
||||
clusterStatus: getClusterStatus(clusterStats, indicesUnassignedShardStats),
|
||||
metrics,
|
||||
logs,
|
||||
shardActivity,
|
||||
|
|
|
@ -9,21 +9,6 @@
|
|||
"totalShards": 10,
|
||||
"status": "green"
|
||||
},
|
||||
"logs": {
|
||||
"enabled": false,
|
||||
"limit": 10,
|
||||
"reason": {
|
||||
"clusterExists": false,
|
||||
"indexPatternExists": false,
|
||||
"indexPatternInTimeRangeExists": false,
|
||||
"typeExistsAtAnyTime": false,
|
||||
"usingStructuredLogs": false,
|
||||
"nodeExists": null,
|
||||
"indexExists": false,
|
||||
"typeExists": false
|
||||
},
|
||||
"logs": []
|
||||
},
|
||||
"metrics": {
|
||||
"index_search_request_rate": [
|
||||
{
|
||||
|
@ -1104,93 +1089,108 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"logs": {
|
||||
"enabled": false,
|
||||
"logs": [],
|
||||
"reason": {
|
||||
"indexPatternExists": false,
|
||||
"indexPatternInTimeRangeExists": false,
|
||||
"typeExistsAtAnyTime": false,
|
||||
"typeExists": false,
|
||||
"usingStructuredLogs": false,
|
||||
"clusterExists": false,
|
||||
"nodeExists": null,
|
||||
"indexExists": false
|
||||
},
|
||||
"limit": 10
|
||||
},
|
||||
"shards": [
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": false,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "xcP6ue7eRCieNNitFTT0EA",
|
||||
"primary": false,
|
||||
"relocating_node": null,
|
||||
"shard": 4,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
},
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": true,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "jUT5KdxfRbORSCWkb5zjmA",
|
||||
"primary": true,
|
||||
"relocating_node": null,
|
||||
"shard": 4,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
},
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": true,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "xcP6ue7eRCieNNitFTT0EA",
|
||||
"primary": true,
|
||||
"relocating_node": null,
|
||||
"shard": 1,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
},
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": false,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "jUT5KdxfRbORSCWkb5zjmA",
|
||||
"primary": false,
|
||||
"relocating_node": null,
|
||||
"shard": 1,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
},
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": true,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "xcP6ue7eRCieNNitFTT0EA",
|
||||
"primary": true,
|
||||
"relocating_node": null,
|
||||
"shard": 2,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
},
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": false,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "jUT5KdxfRbORSCWkb5zjmA",
|
||||
"primary": false,
|
||||
"relocating_node": null,
|
||||
"shard": 2,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
},
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": false,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "xcP6ue7eRCieNNitFTT0EA",
|
||||
"primary": false,
|
||||
"relocating_node": null,
|
||||
"shard": 3,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
},
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": true,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "jUT5KdxfRbORSCWkb5zjmA",
|
||||
"primary": true,
|
||||
"relocating_node": null,
|
||||
"shard": 3,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
},
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": false,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "xcP6ue7eRCieNNitFTT0EA",
|
||||
"primary": false,
|
||||
"relocating_node": null,
|
||||
"shard": 0,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
},
|
||||
{
|
||||
"state": "STARTED",
|
||||
"primary": true,
|
||||
"index": "avocado-tweets-2017.10.02",
|
||||
"node": "jUT5KdxfRbORSCWkb5zjmA",
|
||||
"primary": true,
|
||||
"relocating_node": null,
|
||||
"shard": 0,
|
||||
"index": "avocado-tweets-2017.10.02"
|
||||
"state": "STARTED"
|
||||
}
|
||||
],
|
||||
"shardStats": {
|
||||
"nodes": {
|
||||
"jUT5KdxfRbORSCWkb5zjmA": {
|
||||
"shardCount": 38,
|
||||
"indexCount": 20,
|
||||
"shardCount": 5,
|
||||
"indexCount": 1,
|
||||
"name": "whatever-01",
|
||||
"node_ids": [
|
||||
"jUT5KdxfRbORSCWkb5zjmA"
|
||||
|
@ -1198,29 +1198,20 @@
|
|||
"type": "master"
|
||||
},
|
||||
"xcP6ue7eRCieNNitFTT0EA": {
|
||||
"shardCount": 36,
|
||||
"indexCount": 19,
|
||||
"shardCount": 5,
|
||||
"indexCount": 1,
|
||||
"name": "whatever-02",
|
||||
"node_ids": [
|
||||
"xcP6ue7eRCieNNitFTT0EA"
|
||||
],
|
||||
"type": "node"
|
||||
},
|
||||
"bwQWH-7IQY-mFPpfoaoFXQ": {
|
||||
"shardCount": 4,
|
||||
"indexCount": 4,
|
||||
"name": "whatever-03",
|
||||
"node_ids": [
|
||||
"bwQWH-7IQY-mFPpfoaoFXQ"
|
||||
],
|
||||
"type": "node"
|
||||
}
|
||||
}
|
||||
},
|
||||
"nodes": {
|
||||
"jUT5KdxfRbORSCWkb5zjmA": {
|
||||
"shardCount": 38,
|
||||
"indexCount": 20,
|
||||
"shardCount": 5,
|
||||
"indexCount": 1,
|
||||
"name": "whatever-01",
|
||||
"node_ids": [
|
||||
"jUT5KdxfRbORSCWkb5zjmA"
|
||||
|
@ -1228,22 +1219,13 @@
|
|||
"type": "master"
|
||||
},
|
||||
"xcP6ue7eRCieNNitFTT0EA": {
|
||||
"shardCount": 36,
|
||||
"indexCount": 19,
|
||||
"shardCount": 5,
|
||||
"indexCount": 1,
|
||||
"name": "whatever-02",
|
||||
"node_ids": [
|
||||
"xcP6ue7eRCieNNitFTT0EA"
|
||||
],
|
||||
"type": "node"
|
||||
},
|
||||
"bwQWH-7IQY-mFPpfoaoFXQ": {
|
||||
"shardCount": 4,
|
||||
"indexCount": 4,
|
||||
"name": "whatever-03",
|
||||
"node_ids": [
|
||||
"bwQWH-7IQY-mFPpfoaoFXQ"
|
||||
],
|
||||
"type": "node"
|
||||
}
|
||||
},
|
||||
"stateUuid": "6wwwErXyTfaa4uHBHG5Pbg"
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -32,7 +32,7 @@ export default function({ getService }) {
|
|||
it('should summarize node with metrics', async () => {
|
||||
const { body } = await supertest
|
||||
.post(
|
||||
'/api/monitoring/v1/clusters/YCxj-RAgSZCP6GuOQ8M1EQ/elasticsearch/nodes/jxcP6ue7eRCieNNitFTT0EA'
|
||||
'/api/monitoring/v1/clusters/YCxj-RAgSZCP6GuOQ8M1EQ/elasticsearch/nodes/jUT5KdxfRbORSCWkb5zjmA'
|
||||
)
|
||||
.set('kbn-xsrf', 'xxx')
|
||||
.send({
|
||||
|
|
Loading…
Reference in a new issue