[Monitoring] Add flag to enable/disable CCR monitoring UI (#28840)

* Add flag to enable/disable CCR monitoring UI

* Use the cluster setting instead of a new config

* Remove debug

* Update based on PR feedback

* Ensure the CCR tab shows up on the CCR page

* Rework this so we remove the janky UX

* Update tests

* Handle both string and boolean

* Remove debug

* Fix tests

* Refactor this to use the stack_stats part of the cluster_stats document

* Update the api integration tests

* Fix this test

* Remove debug
This commit is contained in:
Chris Roberson 2019-02-04 16:15:14 -05:00 committed by GitHub
parent fba727b2c0
commit 4dab26ab58
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 267 additions and 3072 deletions

View file

@ -64,7 +64,7 @@
i18n-default-message="Jobs"
></a>
<a
ng-if="!monitoringMain.instance"
ng-if="(monitoringMain.isCcrEnabled || monitoringMain.isActiveTab('ccr')) && !monitoringMain.instance"
kbn-href="#/elasticsearch/ccr"
class="kuiLocalTab"
ng-class="{'kuiLocalTab-isSelected': monitoringMain.isActiveTab('ccr')}"

View file

@ -97,7 +97,8 @@ uiModule.directive('monitoringMain', (breadcrumbs, license, kbnUrl, config) => {
tabIconLabel: attributes.tabIconLabel,
pipelineId: attributes.pipelineId,
pipelineHash: attributes.pipelineHash,
pipelineVersions: get(scope, 'pageData.versions')
pipelineVersions: get(scope, 'pageData.versions'),
isCcrEnabled: attributes.isCcrEnabled
},
clusterName: get(scope, 'cluster.cluster_name')
};

View file

@ -1,6 +1,7 @@
<monitoring-main
product="elasticsearch"
name="indices"
is-ccr-enabled="{{ elasticsearchIndices.isCcrEnabled }}"
data-test-subj="elasticsearchIndicesListingPage"
>
<div id="elasticsearchIndicesReact"></div>

View file

@ -47,6 +47,8 @@ uiRoutes.when('/elasticsearch/indices', {
$injector
});
this.isCcrEnabled = $scope.cluster.isCcrEnabled;
// for binding
const toggleShowSystemIndices = isChecked => {
// flip the boolean

View file

@ -1,6 +1,7 @@
<monitoring-main
product="elasticsearch"
name="nodes"
is-ccr-enabled="{{ elasticsearchNodes.isCcrEnabled }}"
data-test-subj="elasticsearchNodesListingPage"
>
<div id="elasticsearchNodesReact"></div>

View file

@ -44,6 +44,8 @@ uiRoutes.when('/elasticsearch/nodes', {
$injector
});
this.isCcrEnabled = $scope.cluster.isCcrEnabled;
$scope.$watch(() => this.data, data => {
this.renderReact(data);
});

View file

@ -32,6 +32,7 @@ export class ElasticsearchOverviewController extends MonitoringViewBaseControlle
$injector
});
this.isCcrEnabled = $scope.cluster.isCcrEnabled;
this.showShardActivityHistory = false;
this.toggleShardActivityHistory = () => {
this.showShardActivityHistory = !this.showShardActivityHistory;

View file

@ -1,6 +1,7 @@
<monitoring-main
product="elasticsearch"
name="overview"
is-ccr-enabled="{{ elasticsearchOverview.isCcrEnabled }}"
data-test-subj="elasticsearchOverviewPage"
>
<div id="elasticsearchOverviewReact"></div>

View file

@ -74,6 +74,7 @@ Array [
"status": "green",
},
},
"isCcrEnabled": undefined,
"isPrimary": true,
"isSupported": true,
"kibana": Object {
@ -176,6 +177,7 @@ Array [
"status": "green",
},
},
"isCcrEnabled": undefined,
"isPrimary": false,
"isSupported": true,
"kibana": Object {
@ -283,6 +285,7 @@ Array [
"status": "green",
},
},
"isCcrEnabled": undefined,
"isPrimary": false,
"isSupported": true,
"kibana": Object {
@ -385,6 +388,7 @@ Array [
"status": "green",
},
},
"isCcrEnabled": undefined,
"isPrimary": false,
"isSupported": true,
"kibana": Object {

View file

@ -20,6 +20,7 @@ import { getClustersSummary } from './get_clusters_summary';
import { CLUSTER_ALERTS_SEARCH_SIZE, STANDALONE_CLUSTER_CLUSTER_UUID } from '../../../common/constants';
import { getApmsForClusters } from '../apm/get_apms_for_clusters';
import { i18n } from '@kbn/i18n';
import { checkCcrEnabled } from '../elasticsearch/ccr';
import { standaloneClusterDefinition, hasStandaloneClusters } from '../standalone_clusters';
/**
@ -149,7 +150,10 @@ export async function getClustersFromRequest(req, indexPatterns, { clusterUuid,
set(clusters[clusterIndex], 'apm', apm.stats);
});
// check ccr configuration
const isCcrEnabled = await checkCcrEnabled(req, esIndexPattern);
const config = req.server.config();
const kibanaUuid = config.get('server.uuid');
return getClustersSummary(clusters, kibanaUuid);
return getClustersSummary(clusters, kibanaUuid, isCcrEnabled);
}

View file

@ -7,7 +7,7 @@
import { pick, omit, get } from 'lodash';
import { calculateOverallStatus } from '../calculate_overall_status';
export function getClustersSummary(clusters, kibanaUuid) {
export function getClustersSummary(clusters, kibanaUuid, isCcrEnabled) {
return clusters.map(cluster => {
const {
isSupported,
@ -78,6 +78,7 @@ export function getClustersSummary(clusters, kibanaUuid) {
status,
kibana && kibana.status || null
]),
isCcrEnabled
};
});
}

View file

@ -0,0 +1,51 @@
/*
* 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 moment from 'moment';
import { checkParam } from '../error_missing_required';
import { ElasticsearchMetric } from '../metrics';
import { createQuery } from '../create_query';
export function handleResponse(response) {
const isEnabled = get(response, 'hits.hits[0]._source.stack_stats.xpack.ccr.enabled');
const isAvailable = get(response, 'hits.hits[0]._source.stack_stats.xpack.ccr.available');
return isEnabled && isAvailable;
}
export async function checkCcrEnabled(req, esIndexPattern) {
checkParam(esIndexPattern, 'esIndexPattern in getNodes');
const start = moment.utc(req.payload.timeRange.min).valueOf();
const end = moment.utc(req.payload.timeRange.max).valueOf();
const clusterUuid = req.params.clusterUuid;
const metricFields = ElasticsearchMetric.getMetricFields();
const params = {
index: esIndexPattern,
size: 1,
terminate_after: 1,
ignoreUnavailable: true,
body: {
query: createQuery({
type: 'cluster_stats',
start,
end,
clusterUuid,
metric: metricFields
}),
sort: [ { timestamp: { order: 'desc' } } ]
},
filterPath: [
'hits.hits._source.stack_stats.xpack.ccr',
]
};
const { callWithRequest } = req.server.plugins.elasticsearch.getCluster('monitoring');
const response = await callWithRequest(req, 'search', params);
return handleResponse(response);
}

View file

@ -48,7 +48,7 @@ export function esIndicesRoute(server) {
return {
clusterStatus: getClusterStatus(clusterStats, shardStats),
indices
indices,
};
} catch(err) {
throw handleError(err, req);

View file

@ -43,7 +43,7 @@ export function esNodesRoute(server) {
const clusterStatus = getClusterStatus(clusterStats, shardStats);
const nodes = await getNodes(req, esIndexPattern, clusterStats, shardStats);
return { clusterStatus, nodes, };
return { clusterStatus, nodes };
} catch(err) {
throw handleError(err, req);
}

View file

@ -50,7 +50,7 @@ export function esOverviewRoute(server) {
return {
clusterStatus: getClusterStatus(clusterStats, shardStats),
metrics,
shardActivity
shardActivity,
};
} catch (err) {
throw handleError(err, req);

View file

@ -110,6 +110,7 @@
"message": "Cluster [clustertwo] license type [basic] does not support Cluster Alerts"
}
},
"isCcrEnabled": true,
"isPrimary": false,
"status": "green"
},
@ -225,6 +226,7 @@
"medium": 1,
"high": 0
},
"isCcrEnabled": true,
"isPrimary": false,
"status": "yellow"
},
@ -338,6 +340,7 @@
"enabled": true
}
},
"isCcrEnabled": true,
"isPrimary": false,
"status": "green"
}

View file

@ -121,6 +121,7 @@
"timestamp": "2017-08-23T21:28:25.639Z"
}
],
"isCcrEnabled": true,
"isPrimary": true,
"status": "green"
}

View file

@ -14,8 +14,8 @@ export default function ({ getService }) {
describe('cluster', () => {
const archive = 'monitoring/standalone_cluster';
const timeRange = {
min: '2019-01-15T19:00:49.104Z',
max: '2019-01-15T19:59:49.104Z'
min: '2019-02-04T16:52:11.741Z',
max: '2019-02-04T17:52:11.741Z'
};
before('load archive', () => {

View file

@ -14,8 +14,8 @@ export default function ({ getService }) {
describe('clusters', () => {
const archive = 'monitoring/standalone_cluster';
const timeRange = {
min: '2019-01-15T19:00:49.104Z',
max: '2019-01-15T19:59:49.104Z'
min: '2019-02-04T16:52:11.741Z',
max: '2019-02-04T17:52:11.741Z'
};
before('load archive', () => {
@ -32,7 +32,6 @@ export default function ({ getService }) {
.set('kbn-xsrf', 'xxx')
.send({ timeRange })
.expect(200);
expect(body).to.eql(clustersFixture);
});
});

View file

@ -1 +1 @@
[{"isSupported":true,"cluster_uuid":"__standalone_cluster__","license":{},"elasticsearch":{"cluster_stats":{"indices":{},"nodes":{"count":{},"jvm":{}}}},"logstash":{},"kibana":{"status":null,"requests_total":0,"concurrent_connections":0,"response_time_max":0,"memory_size":0,"memory_limit":0,"count":0},"beats":{"totalEvents":6963,"bytesSent":6283358,"beats":{"total":1,"types":[{"type":"Packetbeat","count":1}]}},"apm":{"totalEvents":0,"memRss":0,"memTotal":0,"apms":{"total":0}},"alerts":{"message":"Cluster Alerts are not displayed because the [production] cluster's license could not be determined."},"isPrimary":false}]
[{"isSupported":true,"cluster_uuid":"__standalone_cluster__","license":{},"elasticsearch":{"cluster_stats":{"indices":{},"nodes":{"count":{},"jvm":{}}}},"logstash":{},"kibana":{"status":null,"requests_total":0,"concurrent_connections":0,"response_time_max":0,"memory_size":0,"memory_limit":0,"count":0},"beats":{"totalEvents":348,"bytesSent":319913,"beats":{"total":1,"types":[{"type":"Packetbeat","count":1}]}},"apm":{"totalEvents":0,"memRss":0,"memTotal":0,"apms":{"total":0}},"alerts":{"message":"Cluster Alerts are not displayed because the [production] cluster's license could not be determined."},"isPrimary":false}]

View file

@ -1 +1,181 @@
[{"cluster_uuid":"BsqrVriJSu21Q-MkOr6vTA","cluster_name":"monitoring","version":"7.0.0","license":{"status":"active","type":"basic"},"elasticsearch":{"cluster_stats":{"indices":{"count":5,"docs":{"count":7814,"deleted":169},"shards":{"total":7,"primaries":7,"replication":0,"index":{"shards":{"min":1,"max":3,"avg":1.4},"primaries":{"min":1,"max":3,"avg":1.4},"replication":{"min":0,"max":0,"avg":0}}},"store":{"size_in_bytes":9230231}},"nodes":{"fs":{"total_in_bytes":499963174912,"free_in_bytes":83429146624,"available_in_bytes":70893522944},"count":{"total":1},"jvm":{"max_uptime_in_millis":190074,"mem":{"heap_used_in_bytes":114044640,"heap_max_in_bytes":1038876672}}},"status":"yellow"}},"logstash":{"node_count":0,"events_in_total":0,"events_out_total":0,"avg_memory":0,"avg_memory_used":0,"max_uptime":0,"pipeline_count":0,"queue_types":{"memory":0,"persisted":0},"versions":[]},"kibana":{"status":"green","requests_total":3,"concurrent_connections":2,"response_time_max":58,"memory_size":255426560,"memory_limit":8564343808,"count":1},"beats":{"totalEvents":0,"bytesSent":0,"beats":{"total":0,"types":[]}},"apm":{"totalEvents":0,"memRss":0,"memTotal":0,"apms":{"total":0}},"alerts":{"alertsMeta":{"enabled":true},"clusterMeta":{"enabled":false,"message":"Cluster [monitoring] license type [basic] does not support Cluster Alerts"}},"isPrimary":true,"isSupported": true,"status":"yellow"},{"isSupported":true,"cluster_uuid":"__standalone_cluster__","license":{},"elasticsearch":{"cluster_stats":{"indices":{},"nodes":{"count":{},"jvm":{}}}},"logstash":{"node_count":0,"events_in_total":0,"events_out_total":0,"avg_memory":0,"avg_memory_used":0,"max_uptime":0,"pipeline_count":0,"queue_types":{"memory":0,"persisted":0},"versions":[]},"kibana":{"status":null,"requests_total":0,"concurrent_connections":0,"response_time_max":0,"memory_size":0,"memory_limit":0,"count":0},"beats":{"totalEvents":6963,"bytesSent":6283358,"beats":{"total":1,"types":[{"type":"Packetbeat","count":1}]}},"apm":{"totalEvents":0,"memRss":0,"memTotal":0,"apms":{"total":0}},"alerts":{"alertsMeta":{"enabled":true},"clusterMeta":{"enabled":false,"message":"Cluster [] license type [undefined] does not support Cluster Alerts"}},"isPrimary":false}]
[{
"isSupported": true,
"cluster_uuid": "lfhHkgqfTy2Vy3SvlPSvXg",
"cluster_name": "monitoring",
"version": "7.0.0",
"license": {
"status": "active",
"type": "basic"
},
"elasticsearch": {
"cluster_stats": {
"indices": {
"count": 5,
"docs": {
"count": 522,
"deleted": 122
},
"shards": {
"total": 7,
"primaries": 7,
"replication": 0,
"index": {
"shards": {
"min": 1,
"max": 3,
"avg": 1.4
},
"primaries": {
"min": 1,
"max": 3,
"avg": 1.4
},
"replication": {
"min": 0,
"max": 0,
"avg": 0
}
}
},
"store": {
"size_in_bytes": 1245010
}
},
"nodes": {
"fs": {
"total_in_bytes": 499963174912,
"free_in_bytes": 107874111488,
"available_in_bytes": 101780008960
},
"count": {
"total": 1
},
"jvm": {
"max_uptime_in_millis": 190457,
"mem": {
"heap_used_in_bytes": 341382816,
"heap_max_in_bytes": 1038876672
}
}
},
"status": "yellow"
}
},
"logstash": {
"node_count": 0,
"events_in_total": 0,
"events_out_total": 0,
"avg_memory": 0,
"avg_memory_used": 0,
"max_uptime": 0,
"pipeline_count": 0,
"queue_types": {
"memory": 0,
"persisted": 0
},
"versions": []
},
"kibana": {
"status": "green",
"requests_total": 42,
"concurrent_connections": 0,
"response_time_max": 864,
"memory_size": 127283200,
"memory_limit": 8564343808,
"count": 1
},
"beats": {
"totalEvents": 0,
"bytesSent": 0,
"beats": {
"total": 0,
"types": []
}
},
"apm": {
"totalEvents": 0,
"memRss": 0,
"memTotal": 0,
"apms": {
"total": 0
}
},
"alerts": {
"alertsMeta": {
"enabled": true
},
"clusterMeta": {
"enabled": false,
"message": "Cluster [monitoring] license type [basic] does not support Cluster Alerts"
}
},
"isPrimary": true,
"status": "yellow",
"isCcrEnabled": false
}, {
"isSupported": true,
"cluster_uuid": "__standalone_cluster__",
"license": {},
"elasticsearch": {
"cluster_stats": {
"indices": {},
"nodes": {
"count": {},
"jvm": {}
}
}
},
"logstash": {
"node_count": 0,
"events_in_total": 0,
"events_out_total": 0,
"avg_memory": 0,
"avg_memory_used": 0,
"max_uptime": 0,
"pipeline_count": 0,
"queue_types": {
"memory": 0,
"persisted": 0
},
"versions": []
},
"kibana": {
"status": null,
"requests_total": 0,
"concurrent_connections": 0,
"response_time_max": 0,
"memory_size": 0,
"memory_limit": 0,
"count": 0
},
"beats": {
"totalEvents": 348,
"bytesSent": 319913,
"beats": {
"total": 1,
"types": [{
"type": "Packetbeat",
"count": 1
}]
}
},
"apm": {
"totalEvents": 0,
"memRss": 0,
"memTotal": 0,
"apms": {
"total": 0
}
},
"alerts": {
"alertsMeta": {
"enabled": true
},
"clusterMeta": {
"enabled": false,
"message": "Cluster [] license type [undefined] does not support Cluster Alerts"
}
},
"isPrimary": false,
"isCcrEnabled": false
}]

File diff suppressed because one or more lines are too long

View file

@ -1,59 +0,0 @@
{
"type": "index",
"value": {
"index": ".monitoring-logstash-6-2017.08.15",
"settings": {
"index": {
"codec": "best_compression",
"number_of_shards": "1",
"format": "6",
"number_of_replicas": "1"
}
}
}
}
{
"type": "index",
"value": {
"index": ".monitoring-alerts-6",
"settings": {
"index": {
"codec": "best_compression",
"number_of_shards": "1",
"format": "6",
"number_of_replicas": "1"
}
}
}
}
{
"type": "index",
"value": {
"index": ".monitoring-es-6-2017.08.15",
"settings": {
"index": {
"codec": "best_compression",
"number_of_shards": "1",
"format": "6",
"number_of_replicas": "1"
}
}
}
}
{
"type": "index",
"value": {
"index": ".monitoring-kibana-6-2017.08.15",
"settings": {
"index": {
"codec": "best_compression",
"number_of_shards": "1",
"format": "6",
"number_of_replicas": "1"
}
}
}
}