[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:
parent
08273e58a0
commit
8b480f3b55
219
x-pack/plugins/monitoring/public/components/logstash/listing/__snapshots__/listing.test.js.snap
generated
Normal file
219
x-pack/plugins/monitoring/public/components/logstash/listing/__snapshots__/listing.test.js.snap
generated
Normal 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",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
`;
|
|
@ -5,6 +5,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
|
import { get } from 'lodash';
|
||||||
import { EuiPage, EuiLink, EuiPageBody, EuiPageContent, EuiPanel, EuiSpacer } from '@elastic/eui';
|
import { EuiPage, EuiLink, EuiPageBody, EuiPageContent, EuiPanel, EuiSpacer } from '@elastic/eui';
|
||||||
import { formatPercentageUsage, formatNumber } from '../../../lib/format_number';
|
import { formatPercentageUsage, formatNumber } from '../../../lib/format_number';
|
||||||
import { ClusterStatus } from '..//cluster_status';
|
import { ClusterStatus } from '..//cluster_status';
|
||||||
|
@ -114,12 +115,12 @@ class ListingUI extends PureComponent {
|
||||||
const columns = this.getColumns();
|
const columns = this.getColumns();
|
||||||
const flattenedData = data.map(item => ({
|
const flattenedData = data.map(item => ({
|
||||||
...item,
|
...item,
|
||||||
name: item.logstash.name,
|
name: get(item, 'logstash.name', 'N/A'),
|
||||||
cpu_usage: item.process.cpu.percent,
|
cpu_usage: get(item, 'process.cpu.percent', 'N/A'),
|
||||||
load_average: item.os.cpu.load_average['1m'],
|
load_average: get(item, 'os.cpu.load_average.1m', 'N/A'),
|
||||||
jvm_heap_used: item.jvm.mem.heap_used_percent,
|
jvm_heap_used: get(item, 'jvm.mem.heap_used_percent', 'N/A'),
|
||||||
events_ingested: item.events.out,
|
events_ingested: get(item, 'events.out', 'N/A'),
|
||||||
version: item.logstash.version,
|
version: get(item, 'logstash.version', 'N/A'),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -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();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in a new issue