mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
* [Monitoring/React] Make Elasticsearch directives use React component internally * fix more functional tests * remove TODO * lessen loc change
This commit is contained in:
parent
5830f9b9a5
commit
cbad3cbe4a
17 changed files with 197 additions and 130 deletions
|
@ -71,7 +71,7 @@ export function ClusterStatus({ stats }) {
|
|||
children={children}
|
||||
status={status}
|
||||
IconComponent={IconComponent}
|
||||
data-test-subj="elasticsearchSummaryStatus"
|
||||
data-test-subj="elasticsearchClusterStatus"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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, { Fragment } from 'react';
|
||||
import { SummaryStatus } from '../../summary_status';
|
||||
import { ElasticsearchStatusIcon } from '../status_icon';
|
||||
import { formatMetric } from '../../../lib/format_number';
|
||||
|
||||
export function IndexDetailStatus({ stats }) {
|
||||
const {
|
||||
dataSize,
|
||||
documents: documentCount,
|
||||
totalShards,
|
||||
unassignedShards,
|
||||
status
|
||||
} = stats;
|
||||
|
||||
const children = [
|
||||
{
|
||||
label: 'Total',
|
||||
value: formatMetric(dataSize.total, '0.0 b'),
|
||||
dataTestSubj: 'dataSize'
|
||||
},
|
||||
{
|
||||
label: 'Primaries',
|
||||
value: formatMetric(dataSize.primaries, '0.0 b'),
|
||||
dataTestSubj: 'dataSizePrimaries'
|
||||
},
|
||||
{
|
||||
label: 'Documents',
|
||||
value: formatMetric(documentCount, '0.[0]a'),
|
||||
dataTestSubj: 'documentCount'
|
||||
},
|
||||
{
|
||||
label: 'Total Shards',
|
||||
value: formatMetric(totalShards, 'int_commas'),
|
||||
dataTestSubj: 'totalShards'
|
||||
},
|
||||
{
|
||||
label: 'Unassigned Shards',
|
||||
value: formatMetric(unassignedShards, 'int_commas'),
|
||||
dataTestSubj: 'unassignedShards'
|
||||
}
|
||||
];
|
||||
|
||||
const IconComponent = ({ status }) => (
|
||||
<Fragment>
|
||||
Health: <ElasticsearchStatusIcon status={status} />
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
return (
|
||||
<SummaryStatus
|
||||
children={children}
|
||||
status={status}
|
||||
IconComponent={IconComponent}
|
||||
data-test-subj="elasticsearchIndexDetailStatus"
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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, { Fragment } from 'react';
|
||||
import { SummaryStatus } from '../../summary_status';
|
||||
import { NodeStatusIcon } from '../node';
|
||||
import { formatMetric } from '../../../lib/format_number';
|
||||
|
||||
export function NodeDetailStatus({ stats }) {
|
||||
const {
|
||||
transport_address: transportAddress,
|
||||
usedHeap,
|
||||
freeSpace,
|
||||
documents,
|
||||
dataSize,
|
||||
indexCount,
|
||||
totalShards,
|
||||
nodeTypeLabel,
|
||||
status,
|
||||
isOnline,
|
||||
} = stats;
|
||||
|
||||
const children = [
|
||||
{
|
||||
value: transportAddress,
|
||||
dataTestSubj: 'transportAddress'
|
||||
},
|
||||
{
|
||||
label: 'JVM Heap',
|
||||
value: formatMetric(usedHeap, '0,0.[00]', '%', { prependSpace: false }),
|
||||
dataTestSubj: 'jvmHeap'
|
||||
},
|
||||
{
|
||||
label: 'Free Disk Space',
|
||||
value: formatMetric(freeSpace, '0.0 b'),
|
||||
dataTestSubj: 'freeDiskSpace'
|
||||
},
|
||||
{
|
||||
label: 'Documents',
|
||||
value: formatMetric(documents, '0.[0]a'),
|
||||
dataTestSubj: 'documentCount'
|
||||
},
|
||||
{
|
||||
label: 'Data',
|
||||
value: formatMetric(dataSize, '0.0 b'),
|
||||
dataTestSubj: 'dataSize'
|
||||
},
|
||||
{
|
||||
label: 'Indices',
|
||||
value: formatMetric(indexCount, 'int_commas'),
|
||||
dataTestSubj: 'indicesCount'
|
||||
},
|
||||
{
|
||||
label: 'Shards',
|
||||
value: formatMetric(totalShards, 'int_commas'),
|
||||
dataTestSubj: 'shardsCount'
|
||||
},
|
||||
{
|
||||
label: 'Type',
|
||||
value: nodeTypeLabel,
|
||||
dataTestSubj: 'nodeType'
|
||||
}
|
||||
];
|
||||
|
||||
const IconComponent = ({ status, isOnline }) => (
|
||||
<Fragment>
|
||||
Status: <NodeStatusIcon status={status} isOnline={isOnline} />
|
||||
</Fragment>
|
||||
);
|
||||
|
||||
return (
|
||||
<SummaryStatus
|
||||
children={children}
|
||||
status={status}
|
||||
isOnline={isOnline}
|
||||
IconComponent={IconComponent}
|
||||
data-test-subj="elasticsearchNodeDetailStatus"
|
||||
/>
|
||||
);
|
||||
}
|
|
@ -16,7 +16,8 @@ const wrapChild = ({ label, value, dataTestSubj }, index) => (
|
|||
className="monitoring-summary-status__eui-content"
|
||||
data-test-subj={dataTestSubj}
|
||||
>
|
||||
{label}: <strong>{value}</strong>
|
||||
{label ? label + ': ' : null}
|
||||
<strong>{value}</strong>
|
||||
</EuiFlexItem>
|
||||
);
|
||||
|
||||
|
@ -28,20 +29,20 @@ const DefaultIconComponent = ({ status }) => (
|
|||
</Fragment>
|
||||
);
|
||||
|
||||
const StatusIndicator = ({ status, IconComponent }) => {
|
||||
const StatusIndicator = ({ status, isOnline, IconComponent }) => {
|
||||
if (isEmpty(status)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="monitoring-summary-status__status-indicator">
|
||||
<IconComponent status={status} />{' '}
|
||||
<IconComponent status={status} isOnline={isOnline} />{' '}
|
||||
{capitalize(status)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export function SummaryStatus({ children, status, IconComponent = DefaultIconComponent, ...props }) {
|
||||
export function SummaryStatus({ children, status, isOnline, IconComponent = DefaultIconComponent, ...props }) {
|
||||
return (
|
||||
<div className="monitoring-summary-status" role="status">
|
||||
<div className="monitoring-summary-status__content" {...props}>
|
||||
|
@ -52,7 +53,7 @@ export function SummaryStatus({ children, status, IconComponent = DefaultIconCom
|
|||
grow={true}
|
||||
className="monitoring-summary-status__eui-content"
|
||||
>
|
||||
<StatusIndicator status={status} IconComponent={IconComponent} />
|
||||
<StatusIndicator status={status} IconComponent={IconComponent} isOnline={isOnline} />
|
||||
</EuiFlexItem>
|
||||
</EuiFlexGroup>
|
||||
</div>
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
<div class="monitoring-summary-status" role="status">
|
||||
<div class="monitoring-summary-status__content" data-test-subj="elasticsearchSummaryStatus">
|
||||
<div>Nodes:
|
||||
<strong data-test-subj="nodesCount">{{ status.nodesCount }}</strong>
|
||||
</div>
|
||||
<div>Indices:
|
||||
<strong data-test-subj="indicesCount">{{ status.indicesCount }}</strong>
|
||||
</div>
|
||||
<div>Memory:
|
||||
<strong data-test-subj="memory">{{ status.memUsed|formatNumber:'byte' }} / {{ status.memMax|formatNumber:'byte' }}</strong>
|
||||
</div>
|
||||
<div>Total Shards:
|
||||
<strong data-test-subj="totalShards">{{ status.totalShards }}</strong>
|
||||
</div>
|
||||
<div>Unassigned Shards:
|
||||
<strong data-test-subj="unassignedShards">{{ status.unassignedShards }}</strong>
|
||||
</div>
|
||||
<div>Documents:
|
||||
<strong data-test-subj="documentCount">{{ status.documentCount|formatNumber:'int_commas' }}</strong>
|
||||
</div>
|
||||
<div>Data:
|
||||
<strong data-test-subj="dataSize">{{ status.dataSize|formatNumber:'byte' }}</strong>
|
||||
</div>
|
||||
<div class="monitoring-summary-status__status-indicator">
|
||||
Health:
|
||||
<monitoring-elasticsearch-status-icon
|
||||
status="status.status"
|
||||
title="Status of the Elasticsearch cluster: {{ status.status }}"
|
||||
></monitoring-elasticsearch-status-icon>
|
||||
{{ status.status|capitalize }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -4,16 +4,22 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import template from './index.html';
|
||||
import { ClusterStatus } from 'plugins/monitoring/components/elasticsearch/cluster_status';
|
||||
|
||||
const uiModule = uiModules.get('monitoring/directives', []);
|
||||
uiModule.directive('monitoringClusterStatusElasticsearch', () => {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template,
|
||||
scope: {
|
||||
status: '='
|
||||
},
|
||||
link(scope, $el) {
|
||||
scope.$watch('status', status => {
|
||||
render(<ClusterStatus stats={status} />, $el[0]);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
<div class="monitoring-summary-status" role="status">
|
||||
<div class="monitoring-summary-status__content" data-test-subj="elasticsearchIndexSummaryStatus">
|
||||
<div data-test-subj="dataSize">
|
||||
Total:
|
||||
<strong>{{ summary.dataSize.total|formatMetric:'0.0 b' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="dataSizePrimaries">
|
||||
Primaries:
|
||||
<strong>{{ summary.dataSize.primaries|formatMetric:'0.0 b' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="documentCount">
|
||||
Documents:
|
||||
<strong>{{ summary.documents|formatMetric:'0.[0]a' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="totalShards">
|
||||
Total Shards:
|
||||
<strong>{{ summary.totalShards|formatMetric:'0,0' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="unassignedShards">
|
||||
Unassigned Shards:
|
||||
<strong>{{ summary.unassignedShards|formatMetric:'0,0' }}</strong>
|
||||
</div>
|
||||
<div class="monitoring-summary-status__status-indicator">
|
||||
Health:
|
||||
<monitoring-elasticsearch-status-icon
|
||||
status="summary.status"
|
||||
title="Status of this index: {{ summary.status }}"
|
||||
></monitoring-elasticsearch-status-icon>
|
||||
{{ summary.status|capitalize }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -4,15 +4,21 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import template from './index.html';
|
||||
import { IndexDetailStatus } from 'plugins/monitoring/components/elasticsearch/index_detail_status';
|
||||
|
||||
const uiModule = uiModules.get('monitoring/directives', []);
|
||||
uiModule.directive('monitoringIndexSummary', () => {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: template,
|
||||
scope: { summary: '=' }
|
||||
scope: { summary: '=' },
|
||||
link(scope, $el) {
|
||||
scope.$watch('summary', summary => {
|
||||
render(<IndexDetailStatus stats={summary} />, $el[0]);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
<div class="monitoring-summary-status" role="status">
|
||||
<div class="monitoring-summary-status__content" data-test-subj="elasticsearchNodeSummaryStatus">
|
||||
<div data-test-subj="transportAddress">
|
||||
<strong>{{ node.transport_address|extractIp }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="jvmHeap">
|
||||
JVM Heap:
|
||||
<strong>{{ node.usedHeap|formatMetric:'0,0.[00]':'%' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="freeDiskSpace">
|
||||
Free Disk Space:
|
||||
<strong>{{ node.freeSpace|formatMetric:'0.0 b' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="documentCount">
|
||||
Documents:
|
||||
<strong>{{ node.documents|formatMetric:'0.[0]a' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="dataSize">
|
||||
Data: <strong>{{ node.dataSize|formatMetric:'0.0 b' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="indicesCount">
|
||||
Indices:
|
||||
<strong>{{ node.indexCount|formatMetric:'0,0' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="shardsCount">
|
||||
Shards:
|
||||
<strong>{{ node.totalShards|formatMetric:'0,0' }}</strong>
|
||||
</div>
|
||||
<div data-test-subj="nodeType">
|
||||
Type:
|
||||
<strong>{{ node.nodeTypeLabel }}</strong>
|
||||
</div>
|
||||
<div class="monitoring-summary-status__status-indicator">
|
||||
Health:
|
||||
<monitoring-elasticsearch-node-status-icon
|
||||
status="node.status"
|
||||
title="Status of this Elasticsearch node: {{ node.status }}"
|
||||
></monitoring-elasticsearch-node-status-icon>
|
||||
{{ node.status|capitalize }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -4,16 +4,22 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { render } from 'react-dom';
|
||||
import { uiModules } from 'ui/modules';
|
||||
import template from './index.html';
|
||||
import { NodeDetailStatus } from 'plugins/monitoring/components/elasticsearch/node_detail_status';
|
||||
|
||||
const uiModule = uiModules.get('monitoring/directives', []);
|
||||
uiModule.directive('monitoringNodeSummary', () => {
|
||||
return {
|
||||
restrict: 'E',
|
||||
template: template,
|
||||
scope: {
|
||||
node: '='
|
||||
},
|
||||
link(scope, $el) {
|
||||
scope.$watch('node', node => {
|
||||
render(<NodeDetailStatus stats={node} />, $el[0]);
|
||||
});
|
||||
}
|
||||
};
|
||||
});
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
import expect from 'expect.js';
|
||||
import { handleResponse } from '../get_node_summary';
|
||||
|
||||
describe('get_node_summary handleResponse', () => {
|
||||
it('default undefined fields in result for empty response', () => {
|
||||
describe('Elasticsearch Node Summary get_node_summary handleResponse', () => {
|
||||
it('should return undefined fields in result for empty response', () => {
|
||||
const clusterState = {};
|
||||
const shardStats = {};
|
||||
const resolver = null;
|
||||
|
@ -24,13 +24,14 @@ describe('get_node_summary handleResponse', () => {
|
|||
nodeTypeLabel: 'Offline Node',
|
||||
node_ids: [],
|
||||
status: 'Offline',
|
||||
isOnline: false,
|
||||
transport_address: '',
|
||||
type: 'node',
|
||||
});
|
||||
});
|
||||
|
||||
describe('With node_stats hits', () => {
|
||||
it('incomplete shardStats data', () => {
|
||||
it('should handle incomplete shardStats data', () => {
|
||||
const clusterState = {
|
||||
nodes: {
|
||||
fooNode: {}
|
||||
|
@ -63,10 +64,11 @@ describe('get_node_summary handleResponse', () => {
|
|||
nodeTypeClass: 'fa-server',
|
||||
node_ids: [],
|
||||
status: 'Online',
|
||||
isOnline: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('incomplete shardStats data, master node', () => {
|
||||
it('should handle incomplete shardStats data, master node', () => {
|
||||
const clusterState = {
|
||||
nodes: {
|
||||
'fooNode-Uuid': {}
|
||||
|
@ -140,6 +142,7 @@ describe('get_node_summary handleResponse', () => {
|
|||
'fooNode-Uuid'
|
||||
],
|
||||
status: 'Online',
|
||||
isOnline: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -45,9 +45,14 @@ export function handleResponse(clusterState, shardStats, resolver) {
|
|||
freeSpace: get(sourceStats, 'fs.total.available_in_bytes'),
|
||||
usedHeap: get(sourceStats, 'jvm.mem.heap_used_percent'),
|
||||
status: 'Online',
|
||||
isOnline: true,
|
||||
};
|
||||
} else {
|
||||
nodeSummary = { nodeTypeLabel: 'Offline Node', status: 'Offline', };
|
||||
nodeSummary = {
|
||||
nodeTypeLabel: 'Offline Node',
|
||||
status: 'Offline',
|
||||
isOnline: false,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
|
|
|
@ -990,6 +990,7 @@
|
|||
"documents": 24830,
|
||||
"freeSpace": 186755088384,
|
||||
"indexCount": 20,
|
||||
"isOnline": true,
|
||||
"name": "whatever-01",
|
||||
"nodeTypeClass": "fa-star",
|
||||
"nodeTypeLabel": "Master Node",
|
||||
|
|
|
@ -41,7 +41,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
|
||||
expect(await nodeDetail.getSummary()).to.eql({
|
||||
transportAddress: '127.0.0.1:9300',
|
||||
jvmHeap: 'JVM Heap: 29 %',
|
||||
jvmHeap: 'JVM Heap: 29%',
|
||||
freeDiskSpace: 'Free Disk Space: 173.9 GB',
|
||||
documentCount: 'Documents: 24.8k',
|
||||
dataSize: 'Data: 50.4 MB',
|
||||
|
@ -57,7 +57,7 @@ export default function ({ getService, getPageObjects }) {
|
|||
|
||||
expect(await nodeDetail.getSummary()).to.eql({
|
||||
transportAddress: '127.0.0.1:9302',
|
||||
jvmHeap: 'JVM Heap: 17 %',
|
||||
jvmHeap: 'JVM Heap: 17%',
|
||||
freeDiskSpace: 'Free Disk Space: 173.9 GB',
|
||||
documentCount: 'Documents: 240',
|
||||
dataSize: 'Data: 1.4 MB',
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
export function MonitoringElasticsearchIndexDetailProvider({ getService }) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
const SUBJ_SUMMARY = 'elasticsearchIndexSummaryStatus';
|
||||
const SUBJ_SUMMARY = 'elasticsearchIndexDetailStatus';
|
||||
const SUBJ_SUMMARY_DATA_SIZE = `${SUBJ_SUMMARY} dataSize`;
|
||||
const SUBJ_SUMMARY_DATA_SIZE_PRIMARIES = `${SUBJ_SUMMARY} dataSizePrimaries`;
|
||||
const SUBJ_SUMMARY_DOCUMENT_COUNT = `${SUBJ_SUMMARY} documentCount`;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
export function MonitoringElasticsearchNodeDetailProvider({ getService }) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
const SUBJ_SUMMARY = 'elasticsearchNodeSummaryStatus';
|
||||
const SUBJ_SUMMARY = 'elasticsearchNodeDetailStatus';
|
||||
const SUBJ_SUMMARY_TRANSPORT_ADDRESS = `${SUBJ_SUMMARY} transportAddress`;
|
||||
const SUBJ_SUMMARY_JVM_HEAP = `${SUBJ_SUMMARY} jvmHeap`;
|
||||
const SUBJ_SUMMARY_FREE_DISK_SPACE = `${SUBJ_SUMMARY} freeDiskSpace`;
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
export function MonitoringElasticsearchSummaryStatusProvider({ getService }) {
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
const SUBJ_SUMMARY = 'elasticsearchSummaryStatus';
|
||||
const SUBJ_SUMMARY = 'elasticsearchClusterStatus';
|
||||
const SUBJ_SUMMARY_NODES_COUNT = `${SUBJ_SUMMARY} nodesCount`;
|
||||
const SUBJ_SUMMARY_INDICES_COUNT = `${SUBJ_SUMMARY} indicesCount`;
|
||||
const SUBJ_SUMMARY_MEMORY = `${SUBJ_SUMMARY} memory`;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue