[Monitoring] Protect against these fields not existing in Logstash Nodes listing (#34939)

* Protect against these fields not existing

* Add basic unit tests to ensure this behavior does not regress

* Expand this test to ensure we don't break on other pieces of data missing

* Use N/A if there is no value (rather than 0)
This commit is contained in:
Chris Roberson 2019-04-11 12:46:23 -04:00 committed by GitHub
parent 08273e58a0
commit 8b480f3b55
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 314 additions and 6 deletions

View file

@ -0,0 +1,219 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Listing should render with certain data pieces missing 1`] = `
<EuiMonitoringTable
className="logstashNodesTable"
columns={
Array [
Object {
"field": "name",
"name": "Name",
"render": [Function],
"sortable": true,
},
Object {
"field": "cpu_usage",
"name": "CPU Usage",
"render": [Function],
"sortable": true,
},
Object {
"field": "load_average",
"name": "Load Average",
"render": [Function],
"sortable": true,
},
Object {
"field": "jvm_heap_used",
"name": "JVM Heap Used",
"render": [Function],
"sortable": true,
},
Object {
"field": "events_out",
"name": "Events Ingested",
"render": [Function],
"sortable": true,
},
Object {
"name": "Config Reloads",
"render": [Function],
"sortable": true,
},
Object {
"field": "version",
"name": "Version",
"render": [Function],
"sortable": true,
},
]
}
executeQueryOptions={
Object {
"defaultFields": Array [
"name",
],
}
}
rows={
Array [
Object {
"availability": true,
"cpu_usage": "N/A",
"events_ingested": "N/A",
"jvm_heap_used": "N/A",
"load_average": "N/A",
"name": "N/A",
"reloads": Object {
"failures": 0,
"successes": 0,
},
"version": "N/A",
},
]
}
search={
Object {
"box": Object {
"incremental": true,
"placeholder": "Filter Nodes…",
},
}
}
sorting={
Object {
"sort": Object {
"0": "a",
"1": "s",
"2": "c",
"field": "name",
},
}
}
/>
`;
exports[`Listing should render with expected props 1`] = `
<EuiMonitoringTable
className="logstashNodesTable"
columns={
Array [
Object {
"field": "name",
"name": "Name",
"render": [Function],
"sortable": true,
},
Object {
"field": "cpu_usage",
"name": "CPU Usage",
"render": [Function],
"sortable": true,
},
Object {
"field": "load_average",
"name": "Load Average",
"render": [Function],
"sortable": true,
},
Object {
"field": "jvm_heap_used",
"name": "JVM Heap Used",
"render": [Function],
"sortable": true,
},
Object {
"field": "events_out",
"name": "Events Ingested",
"render": [Function],
"sortable": true,
},
Object {
"name": "Config Reloads",
"render": [Function],
"sortable": true,
},
Object {
"field": "version",
"name": "Version",
"render": [Function],
"sortable": true,
},
]
}
executeQueryOptions={
Object {
"defaultFields": Array [
"name",
],
}
}
rows={
Array [
Object {
"availability": true,
"cpu_usage": 0,
"events": Object {
"out": 3505,
},
"events_ingested": 3505,
"jvm": Object {
"mem": Object {
"heap_used_percent": 27,
},
},
"jvm_heap_used": 27,
"load_average": 2.54248046875,
"logstash": Object {
"host": "Elastic-MBP.local",
"http_address": "127.0.0.1:9600",
"name": "Elastic-MBP.local",
"pipeline": Object {
"batch_size": 125,
"workers": 4,
},
"status": "green",
"uuid": "4134a00e-89e4-4896-a3d4-c3a9aa03a594",
"version": "8.0.0",
},
"name": "Elastic-MBP.local",
"os": Object {
"cpu": Object {
"load_average": Object {
"1m": 2.54248046875,
},
},
},
"process": Object {
"cpu": Object {
"percent": 0,
},
},
"reloads": Object {
"failures": 0,
"successes": 0,
},
"version": "8.0.0",
},
]
}
search={
Object {
"box": Object {
"incremental": true,
"placeholder": "Filter Nodes…",
},
}
}
sorting={
Object {
"sort": Object {
"0": "a",
"1": "s",
"2": "c",
"field": "name",
},
}
}
/>
`;

View file

@ -5,6 +5,7 @@
*/
import React, { PureComponent } from 'react';
import { get } from 'lodash';
import { EuiPage, EuiLink, EuiPageBody, EuiPageContent, EuiPanel, EuiSpacer } from '@elastic/eui';
import { formatPercentageUsage, formatNumber } from '../../../lib/format_number';
import { ClusterStatus } from '..//cluster_status';
@ -114,12 +115,12 @@ class ListingUI extends PureComponent {
const columns = this.getColumns();
const flattenedData = data.map(item => ({
...item,
name: item.logstash.name,
cpu_usage: item.process.cpu.percent,
load_average: item.os.cpu.load_average['1m'],
jvm_heap_used: item.jvm.mem.heap_used_percent,
events_ingested: item.events.out,
version: item.logstash.version,
name: get(item, 'logstash.name', 'N/A'),
cpu_usage: get(item, 'process.cpu.percent', 'N/A'),
load_average: get(item, 'os.cpu.load_average.1m', 'N/A'),
jvm_heap_used: get(item, 'jvm.mem.heap_used_percent', 'N/A'),
events_ingested: get(item, 'events.out', 'N/A'),
version: get(item, 'logstash.version', 'N/A'),
}));
return (

View file

@ -0,0 +1,88 @@
/*
* 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 { shallowWithIntl } from 'test_utils/enzyme_helpers';
import { Listing } from './listing';
const expectedData = [
{
'jvm': {
'mem': {
'heap_used_percent': 27
}
},
'logstash': {
'pipeline': {
'batch_size': 125,
'workers': 4
},
'http_address': '127.0.0.1:9600',
'name': 'Elastic-MBP.local',
'host': 'Elastic-MBP.local',
'version': '8.0.0',
'uuid': '4134a00e-89e4-4896-a3d4-c3a9aa03a594',
'status': 'green'
},
'process': {
'cpu': {
'percent': 0
}
},
'os': {
'cpu': {
'load_average': {
'1m': 2.54248046875
}
}
},
'events': {
'out': 3505
},
'reloads': {
'failures': 0,
'successes': 0
},
'availability': true
}
];
describe('Listing', () => {
it('should render with expected props', () => {
const props = {
data: expectedData,
angular: {
scope: null,
kbnUrl: null
},
sorting: {
sort: 'asc'
}
};
const component = shallowWithIntl(<Listing.WrappedComponent {...props} />);
expect(component.find('EuiMonitoringTable')).toMatchSnapshot();
});
it('should render with certain data pieces missing', () => {
const props = {
data: expectedData.map(item => {
const { os, process, logstash, jvm, events, ...rest } = item; // eslint-disable-line no-unused-vars
return rest;
}),
angular: {
scope: null,
kbnUrl: null
},
sorting: {
sort: 'asc'
}
};
const component = shallowWithIntl(<Listing.WrappedComponent {...props} />);
expect(component.find('EuiMonitoringTable')).toMatchSnapshot();
});
});