diff --git a/x-pack/plugins/monitoring/public/components/apm/instance/instance.js b/x-pack/plugins/monitoring/public/components/apm/instance/instance.js index c40d19d384a0d..0e44490ba2281 100644 --- a/x-pack/plugins/monitoring/public/components/apm/instance/instance.js +++ b/x-pack/plugins/monitoring/public/components/apm/instance/instance.js @@ -12,7 +12,8 @@ import { EuiSpacer, EuiPage, EuiPageBody, - EuiFlexGroup + EuiFlexGroup, + EuiPageContent } from '@elastic/eui'; import { Status } from './status'; @@ -46,13 +47,15 @@ export function ApmServerInstance({ summary, metrics, ...props }) { )); return ( - + - - - - {charts} - + + + + + {charts} + + ); diff --git a/x-pack/plugins/monitoring/public/components/apm/instances/instances.js b/x-pack/plugins/monitoring/public/components/apm/instances/instances.js index 14c2fcb762e11..59ea744622e82 100644 --- a/x-pack/plugins/monitoring/public/components/apm/instances/instances.js +++ b/x-pack/plugins/monitoring/public/components/apm/instances/instances.js @@ -6,150 +6,126 @@ import React from 'react'; import moment from 'moment'; -import { MonitoringTable } from '../../table'; -import { - KuiTableRowCell, - KuiTableRow -} from '@kbn/ui-framework/components'; -import { EuiLink } from '@elastic/eui'; +import { uniq } from 'lodash'; +import { EuiMonitoringTable } from '../../table'; +import { EuiLink, EuiPage, EuiPageBody, EuiPageContent, EuiSpacer } from '@elastic/eui'; import { Status } from './status'; -import { SORT_ASCENDING, SORT_DESCENDING, TABLE_ACTION_UPDATE_FILTER } from '../../../../common/constants'; import { formatMetric } from '../../../lib/format_number'; import { formatTimestampToDuration } from '../../../../common'; import { i18n } from '@kbn/i18n'; import { injectI18n } from '@kbn/i18n/react'; - -const filterFields = [ 'name', 'type', 'version', 'output' ]; const columns = [ { - title: i18n.translate('xpack.monitoring.apm.instances.nameTitle', { + name: i18n.translate('xpack.monitoring.apm.instances.nameTitle', { defaultMessage: 'Name' }), - sortKey: 'name', - sortOrder: SORT_ASCENDING + field: 'name', + render: (name, instance) => ( + + {name} + + ) }, { - title: i18n.translate('xpack.monitoring.apm.instances.outputEnabledTitle', { + name: i18n.translate('xpack.monitoring.apm.instances.outputEnabledTitle', { defaultMessage: 'Output Enabled' }), - sortKey: 'output' + field: 'output' }, { - title: i18n.translate('xpack.monitoring.apm.instances.totalEventsRateTitle', { + name: i18n.translate('xpack.monitoring.apm.instances.totalEventsRateTitle', { defaultMessage: 'Total Events Rate' }), - sortKey: 'total_events_rate', - secondarySortOrder: SORT_DESCENDING + field: 'total_events_rate', + render: value => formatMetric(value, '', '/s') }, { - title: i18n.translate('xpack.monitoring.apm.instances.bytesSentRateTitle', { + name: i18n.translate('xpack.monitoring.apm.instances.bytesSentRateTitle', { defaultMessage: 'Bytes Sent Rate' }), - sortKey: 'bytes_sent_rate' + field: 'bytes_sent_rate', + render: value => formatMetric(value, 'byte', '/s') }, { - title: i18n.translate('xpack.monitoring.apm.instances.outputErrorsTitle', { + name: i18n.translate('xpack.monitoring.apm.instances.outputErrorsTitle', { defaultMessage: 'Output Errors' }), - sortKey: 'errors' + field: 'errors', + render: value => formatMetric(value, '0') }, { - title: i18n.translate('xpack.monitoring.apm.instances.lastEventTitle', { + name: i18n.translate('xpack.monitoring.apm.instances.lastEventTitle', { defaultMessage: 'Last Event' }), - sortKey: 'time_of_last_event' + field: 'time_of_last_event', + render: value => formatTimestampToDuration(+moment(value), 'since') + ' ago' }, { - title: i18n.translate('xpack.monitoring.apm.instances.allocatedMemoryTitle', { + name: i18n.translate('xpack.monitoring.apm.instances.allocatedMemoryTitle', { defaultMessage: 'Allocated Memory' }), - sortKey: 'memory' + field: 'memory', + render: value => formatMetric(value, 'byte') }, { - title: i18n.translate('xpack.monitoring.apm.instances.versionTitle', { + name: i18n.translate('xpack.monitoring.apm.instances.versionTitle', { defaultMessage: 'Version' }), - sortKey: 'version' + field: 'version' }, ]; -const instanceRowFactory = () => { - return function KibanaRow(props) { - const applyFiltering = filterText => () => { - props.dispatchTableAction(TABLE_ACTION_UPDATE_FILTER, filterText); - }; - - return ( - - -
- - {props.name} - -
-
- - {props.output} - - - {formatMetric(props.total_events_rate, '', '/s')} - - - {formatMetric(props.bytes_sent_rate, 'byte', '/s')} - - - {formatMetric(props.errors, '0')} - - - {formatTimestampToDuration(+moment(props.time_of_last_event), 'since') + ' ago'} - - - {formatMetric(props.memory, 'byte')} - - - - {props.version} - - -
- ); - }; -}; -function ApmServerInstancesUI({ apms, intl }) { +export function ApmServerInstancesUI({ apms, intl }) { const { - pageIndex, - filterText, - sortKey, - sortOrder, - onNewState, + pagination, + sorting, + onTableChange, + data } = apms; + const versions = uniq(data.apms.map(item => item.version)).map(version => { + return { value: version }; + }); + return ( -
- - -
+ + + + + + + + + ); } diff --git a/x-pack/plugins/monitoring/public/components/apm/overview/index.js b/x-pack/plugins/monitoring/public/components/apm/overview/index.js index 634a5e78127c0..eb7236d5eea66 100644 --- a/x-pack/plugins/monitoring/public/components/apm/overview/index.js +++ b/x-pack/plugins/monitoring/public/components/apm/overview/index.js @@ -12,7 +12,8 @@ import { EuiFlexGroup, EuiFlexItem, EuiPageBody, - EuiPanel + EuiPanel, + EuiPageContent } from '@elastic/eui'; import { Status } from '../instances/status'; @@ -50,13 +51,15 @@ export function ApmOverview({ )); return ( - + - - - - {charts} - + + + + + {charts} + + ); diff --git a/x-pack/plugins/monitoring/public/components/beats/listing/index.js b/x-pack/plugins/monitoring/public/components/beats/listing/index.js new file mode 100644 index 0000000000000..6c97a85719b4c --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/beats/listing/index.js @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { Listing } from './listing'; diff --git a/x-pack/plugins/monitoring/public/components/beats/listing/listing.js b/x-pack/plugins/monitoring/public/components/beats/listing/listing.js new file mode 100644 index 0000000000000..45be036e5bb3b --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/beats/listing/listing.js @@ -0,0 +1,133 @@ +/* + * 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, { PureComponent } from 'react'; +import { uniq } from 'lodash'; +import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiLink } from '@elastic/eui'; +import { Stats } from 'plugins/monitoring/components/beats'; +import { formatMetric } from 'plugins/monitoring/lib/format_number'; +import { EuiMonitoringTable } from 'plugins/monitoring/components/table'; +import { i18n } from '@kbn/i18n'; +import { injectI18n } from '@kbn/i18n/react'; + +class ListingUI extends PureComponent { + getColumns() { + const { kbnUrl, scope } = this.props.angular; + + return [ + { + name: i18n.translate('xpack.monitoring.beats.instances.nameTitle', { defaultMessage: 'Name' }), + field: 'name', + render: (name, beat) => ( + { + scope.$evalAsync(() => { + kbnUrl.changePath(`/beats/beat/${beat.uuid}`); + }); + }} + data-test-subj={`beatLink-${name}`} + > + {name} + + ) + }, + { + name: i18n.translate('xpack.monitoring.beats.instances.typeTitle', { defaultMessage: 'Type' }), + field: 'type', + }, + { + name: i18n.translate('xpack.monitoring.beats.instances.outputEnabledTitle', { defaultMessage: 'Output Enabled' }), + field: 'output' + }, + { + name: i18n.translate('xpack.monitoring.beats.instances.totalEventsRateTitle', { defaultMessage: 'Total Events Rate' }), + field: 'total_events_rate', + render: value => formatMetric(value, '', '/s') + }, + { + name: i18n.translate('xpack.monitoring.beats.instances.bytesSentRateTitle', { defaultMessage: 'Bytes Sent Rate' }), + field: 'bytes_sent_rate', + render: value => formatMetric(value, 'byte', '/s') + }, + { + name: i18n.translate('xpack.monitoring.beats.instances.outputErrorsTitle', { defaultMessage: 'Output Errors' }), + field: 'errors', + render: value => formatMetric(value, '0') + }, + { + name: i18n.translate('xpack.monitoring.beats.instances.allocatedMemoryTitle', { defaultMessage: 'Allocated Memory' }), + field: 'memory', + render: value => formatMetric(value, 'byte') + }, + { + name: i18n.translate('xpack.monitoring.beats.instances.versionTitle', { defaultMessage: 'Version' }), + field: 'version', + }, + ]; + } + + render() { + const { + stats, + data, + sorting, + pagination, + onTableChange + } = this.props; + + + const types = uniq(data.map(item => item.type)).map(type => { + return { value: type }; + }); + + const versions = uniq(data.map(item => item.version)).map(version => { + return { value: version }; + }); + + return ( + + + + + + + + + + ); + } +} + +export const Listing = injectI18n(ListingUI); diff --git a/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/overview.test.js.snap b/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/overview.test.js.snap index 8e3491a8689f1..f1202a53266ff 100644 --- a/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/overview.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/beats/overview/__snapshots__/overview.test.js.snap @@ -3,260 +3,256 @@ exports[`Overview that overview page renders normally 1`] = ` - - + - - -

- -

-
- - -
-
- - +

+ +

+ + + +
+
+ - -

- -

-
- - - -
- - +

+ +

+ + + +
+
+ - -

- -

-
- - - -
-
- - - - - +

+ +

+ + + + +
+
+ + - - - - - - - - - - - + + + + - - - - + + + + - + + + + + - - - - + + + + + +
`; @@ -264,121 +260,117 @@ exports[`Overview that overview page renders normally 1`] = ` exports[`Overview that overview page shows a message if there is no beats data 1`] = ` - - - - - - + + + - - - - - - - - - - - + + + + - - - - + + + + - + + + + + - - - - + + + + + + `; diff --git a/x-pack/plugins/monitoring/public/components/beats/overview/overview.js b/x-pack/plugins/monitoring/public/components/beats/overview/overview.js index 2fa946e1def35..88b801f657570 100644 --- a/x-pack/plugins/monitoring/public/components/beats/overview/overview.js +++ b/x-pack/plugins/monitoring/public/components/beats/overview/overview.js @@ -10,7 +10,6 @@ import { LatestVersions } from './latest_versions'; import { LatestTypes } from './latest_types'; import { Stats } from '../'; import { MonitoringTimeseriesContainer } from '../../chart'; -import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; import { EuiCallOut, EuiTitle, @@ -19,8 +18,10 @@ import { EuiFlexGroup, EuiFlexItem, EuiPageBody, - EuiPanel + EuiPanel, + EuiPageContent } from '@elastic/eui'; +import { FormattedMessage, injectI18n } from '@kbn/i18n/react'; function renderLatestActive(latestActive, latestTypes, latestVersions, intl) { if (latestTypes && latestTypes.length > 0) { @@ -78,6 +79,7 @@ function renderLatestActive(latestActive, latestTypes, latestVersions, intl) { defaultMessage: `Hi there! This area is where your latest Beats activity would show up, but you don't seem to have any activity within the last day.` }); + return ( + - {renderLatestActive(latestActive, latestTypes, latestVersions, intl)} - - - - - {charts} - + + + {renderLatestActive(latestActive, latestTypes, latestVersions, intl)} + + + {charts} + + ); } -export const BeatsOverview = injectI18n(BeatsOverviewUi); +export const BeatsOverview = injectI18n(BeatsOverviewUI); diff --git a/x-pack/plugins/monitoring/public/components/logstash/listing/index.js b/x-pack/plugins/monitoring/public/components/logstash/listing/index.js new file mode 100644 index 0000000000000..6c97a85719b4c --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/logstash/listing/index.js @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { Listing } from './listing'; diff --git a/x-pack/plugins/monitoring/public/components/logstash/listing/listing.js b/x-pack/plugins/monitoring/public/components/logstash/listing/listing.js new file mode 100644 index 0000000000000..16602a30b042b --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/logstash/listing/listing.js @@ -0,0 +1,111 @@ +/* + * 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, { PureComponent } from 'react'; +import { EuiPage, EuiLink, EuiPageBody, EuiPageContent, EuiSpacer } from '@elastic/eui'; +import { formatPercentageUsage, formatNumber } from '../../../lib/format_number'; +import { ClusterStatus } from '..//cluster_status'; +import { EuiMonitoringTable } from '../../table'; + +export class Listing extends PureComponent { + getColumns() { + const { kbnUrl, scope } = this.props.angular; + + return [ + { + name: 'Name', + field: 'logstash.name', + render: (name, node) => ( +
+
+ { + scope.$evalAsync(() => { + kbnUrl.changePath(`/logstash/node/${node.logstash.uuid}`); + }); + }} + > + {name} + +
+
+ {node.logstash.http_address} +
+
+ ) + }, + { + name: 'CPU Usage', + field: 'process.cpu.percent', + render: value => formatPercentageUsage(value, 100) + }, + { + name: 'Load Average', + field: 'os.cpu.load_average.1m', + render: value => formatNumber(value, '0.00') + }, + { + name: 'JVM Heap Used', + field: 'jvm.mem.heap_used_percent', + render: value => formatPercentageUsage(value, 100) + }, + { + name: 'Events Ingested', + field: 'events.out', + render: value => formatNumber(value, '0.[0]a') + }, + { + name: 'Config Reloads', + render: node => ( +
+
{ node.reloads.successes } successes
+
{ node.reloads.failures } failures
+
+ ) + }, + { + name: 'Version', + field: 'logstash.version', + render: value => formatNumber(value) + } + ]; + } + render() { + const { data, stats, sorting, pagination, onTableChange } = this.props; + const columns = this.getColumns(); + + return ( + + + + + + + + + + ); + } +} diff --git a/x-pack/plugins/monitoring/public/components/logstash/node/index.js b/x-pack/plugins/monitoring/public/components/logstash/node/index.js new file mode 100644 index 0000000000000..b219992287408 --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/logstash/node/index.js @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { Node } from './node'; diff --git a/x-pack/plugins/monitoring/public/components/logstash/node/node.js b/x-pack/plugins/monitoring/public/components/logstash/node/node.js new file mode 100644 index 0000000000000..2d747949eb453 --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/logstash/node/node.js @@ -0,0 +1,47 @@ +/* + * 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, { PureComponent } from 'react'; +import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGrid, EuiFlexItem } from '@elastic/eui'; +import { DetailStatus } from '../detail_status'; +import { MonitoringTimeseriesContainer } from '../../chart'; + +export class Node extends PureComponent { + render() { + const { stats, metrics, ...rest } = this.props; + + const metricsToShow = [ + metrics.logstash_events_input_rate, + metrics.logstash_jvm_usage, + metrics.logstash_events_output_rate, + metrics.logstash_node_cpu_metric, + metrics.logstash_events_latency, + metrics.logstash_os_load, + ]; + + return ( + + + + + + + {metricsToShow.map((metric, index) => ( + + + + + ))} + + + + + ); + } +} diff --git a/x-pack/plugins/monitoring/public/components/logstash/overview/index.js b/x-pack/plugins/monitoring/public/components/logstash/overview/index.js new file mode 100644 index 0000000000000..9ee1b444ee817 --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/logstash/overview/index.js @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { Overview } from './overview'; diff --git a/x-pack/plugins/monitoring/public/components/logstash/overview/overview.js b/x-pack/plugins/monitoring/public/components/logstash/overview/overview.js new file mode 100644 index 0000000000000..b669f83803c10 --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/logstash/overview/overview.js @@ -0,0 +1,42 @@ +/* + * 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, { PureComponent } from 'react'; +import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGrid, EuiFlexItem } from '@elastic/eui'; +import { ClusterStatus } from '../cluster_status'; +import { MonitoringTimeseriesContainer } from '../../chart'; + +export class Overview extends PureComponent { + render() { + const { stats, metrics } = this.props; + const metricsToShow = [ + metrics.logstash_cluster_events_input_rate, + metrics.logstash_cluster_events_output_rate, + metrics.logstash_cluster_events_latency + ]; + + return ( + + + + + + + {metricsToShow.map((metric, index) => ( + + + + + ))} + + + + + ); + } +} diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/index.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/index.js new file mode 100644 index 0000000000000..0de77d851a011 --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/index.js @@ -0,0 +1,7 @@ +/* + * 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. + */ + +export { PipelineListing } from './pipeline_listing'; diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js new file mode 100644 index 0000000000000..21f2ed6b724a6 --- /dev/null +++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js @@ -0,0 +1,171 @@ +/* + * 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, { Component } from 'react'; +import moment from 'moment'; +import { partialRight } from 'lodash'; +import { EuiPage, EuiLink, EuiPageBody, EuiPageContent, EuiSpacer, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import { formatMetric } from '../../../lib/format_number'; +import { ClusterStatus } from '../cluster_status'; +import { Sparkline } from 'plugins/monitoring/components/sparkline'; +import { EuiMonitoringTable } from '../../table'; + +export class PipelineListing extends Component { + tooltipXValueFormatter(xValue) { + return moment(xValue).format(this.props.dateFormat); + } + + tooltipYValueFormatter(yValue, format, units) { + return formatMetric(yValue, format, units); + } + + getColumns() { + const { onBrush } = this.props; + const { kbnUrl, scope } = this.props.angular; + + return [ + { + name: 'ID', + field: 'id', + sortable: true, + render: (id) => ( + { + scope.$evalAsync(() => { + kbnUrl.changePath(`/logstash/pipelines/${id}`); + }); + }} + > + {id} + + ) + }, + { + name: 'Events Emitted Rate', + field: 'latestThroughput', + sortable: true, + render: (value, pipeline) => { + const throughput = pipeline.metrics.throughput; + return ( + + + this.tooltipXValueFormatter(value), + yValueFormatter: partialRight(this.tooltipYValueFormatter, throughput.metric.format, throughput.metric.units) + }} + options={{ xaxis: throughput.timeRange }} + /> + + + { formatMetric(value, '0.[0]a', throughput.metric.units) } + + + ); + } + }, + { + name: 'Number of Nodes', + field: 'latestNodesCount', + sortable: true, + render: (value, pipeline) => { + const nodesCount = pipeline.metrics.nodesCount; + return ( + + + + + + { formatMetric(value, '0a') } + + + ); + } + }, + ]; + } + + renderStats() { + if (this.props.statusComponent) { + const Component = this.props.statusComponent; + return ( + + ); + } + + return ( + + ); + } + + render() { + const { + data, + sorting, + pagination, + onTableChange, + upgradeMessage, + className + } = this.props; + + const columns = this.getColumns(); + + return ( + + + + {this.renderStats()} + + + + + + ); + } +} diff --git a/x-pack/plugins/monitoring/public/directives/beats/listing/index.js b/x-pack/plugins/monitoring/public/directives/beats/listing/index.js index 779dffaf2309a..b2964a28574f9 100644 --- a/x-pack/plugins/monitoring/public/directives/beats/listing/index.js +++ b/x-pack/plugins/monitoring/public/directives/beats/listing/index.js @@ -7,160 +7,40 @@ import React from 'react'; import { render } from 'react-dom'; import { uiModules } from 'ui/modules'; -import { Stats } from 'plugins/monitoring/components/beats'; -import { formatMetric } from 'plugins/monitoring/lib/format_number'; import { I18nProvider } from '@kbn/i18n/react'; -import { i18n } from '@kbn/i18n'; -import { - SORT_ASCENDING, - SORT_DESCENDING, - TABLE_ACTION_UPDATE_FILTER, -} from '../../../../common/constants'; -import { - KuiTableRowCell, - KuiTableRow -} from '@kbn/ui-framework/components'; -import { MonitoringTable } from 'plugins/monitoring/components/table'; - -import { - EuiLink, -} from '@elastic/eui'; - -const filterFields = [ 'name', 'type', 'version', 'output' ]; -const columns = [ - { - title: i18n.translate('xpack.monitoring.beats.instances.nameTitle', { defaultMessage: 'Name' }), - sortKey: 'name', - sortOrder: SORT_ASCENDING - }, - { - title: i18n.translate('xpack.monitoring.beats.instances.typeTitle', { defaultMessage: 'Type' }), - sortKey: 'type' - }, - { - title: i18n.translate('xpack.monitoring.beats.instances.outputEnabledTitle', { defaultMessage: 'Output Enabled' }), - sortKey: 'output' - }, - { - title: i18n.translate('xpack.monitoring.beats.instances.totalEventsRateTitle', { defaultMessage: 'Total Events Rate' }), - sortKey: 'total_events_rate', - secondarySortOrder: SORT_DESCENDING - }, - { - title: i18n.translate('xpack.monitoring.beats.instances.bytesSentRateTitle', { defaultMessage: 'Bytes Sent Rate' }), - sortKey: 'bytes_sent_rate' - }, - { - title: i18n.translate('xpack.monitoring.beats.instances.outputErrorsTitle', { defaultMessage: 'Output Errors' }), - sortKey: 'errors' - }, - { - title: i18n.translate('xpack.monitoring.beats.instances.allocatedMemoryTitle', { defaultMessage: 'Allocated Memory' }), - sortKey: 'memory' - }, - { - title: i18n.translate('xpack.monitoring.beats.instances.versionTitle', { defaultMessage: 'Version' }), - sortKey: 'version' - }, -]; -const beatRowFactory = (scope, kbnUrl) => { - return props => { - const goToBeat = uuid => () => { - scope.$evalAsync(() => { - kbnUrl.changePath(`/beats/beat/${uuid}`); - }); - }; - const applyFiltering = filterText => () => { - props.dispatchTableAction(TABLE_ACTION_UPDATE_FILTER, filterText); - }; - - return ( - - -
- - {props.name} - -
-
- - - {props.type} - - - - {props.output} - - - {formatMetric(props.total_events_rate, '', '/s')} - - - {formatMetric(props.bytes_sent_rate, 'byte', '/s')} - - - {formatMetric(props.errors, '0')} - - - {formatMetric(props.memory, 'byte')} - - - - {props.version} - - -
- ); - }; -}; +import { Listing } from '../../../components/beats/listing/listing'; const uiModule = uiModules.get('monitoring/directives', []); -uiModule.directive('monitoringBeatsListing', (kbnUrl, i18n) => { +uiModule.directive('monitoringBeatsListing', (kbnUrl) => { return { restrict: 'E', scope: { data: '=', - pageIndex: '=', - filterText: '=', - sortKey: '=', - sortOrder: '=', - onNewState: '=', + sorting: '=', + pagination: '=paginationSettings', + onTableChange: '=', }, link(scope, $el) { - - scope.$watch('data', (data = {}) => { - const filterBeatsPlaceholder = i18n('xpack.monitoring.beats.filterBeatsPlaceholder', { defaultMessage: 'Filter Beats…' }); - + function renderReact(data) { render(( -
- -
- -
-
+ ), $el[0]); + } + scope.$watch('data', (data = {}) => { + renderReact(data); }); - } }; }); diff --git a/x-pack/plugins/monitoring/public/views/apm/instances/index.js b/x-pack/plugins/monitoring/public/views/apm/instances/index.js index a49aad8ca912b..4c6c7ef784f0d 100644 --- a/x-pack/plugins/monitoring/public/views/apm/instances/index.js +++ b/x-pack/plugins/monitoring/public/views/apm/instances/index.js @@ -10,7 +10,7 @@ import uiRoutes from'ui/routes'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import template from './index.html'; import { ApmServerInstances } from '../../../components/apm/instances'; -import { MonitoringViewBaseTableController } from '../../base_table_controller'; +import { MonitoringViewBaseEuiTableController } from '../..'; import { I18nProvider } from '@kbn/i18n/react'; uiRoutes.when('/apm/instances', { @@ -21,7 +21,7 @@ uiRoutes.when('/apm/instances', { return routeInit(); }, }, - controller: class extends MonitoringViewBaseTableController { + controller: class extends MonitoringViewBaseEuiTableController { constructor($injector, $scope, i18n) { const $route = $injector.get('$route'); const globalState = $injector.get('globalState'); @@ -51,22 +51,18 @@ uiRoutes.when('/apm/instances', { renderReact(data) { const { - pageIndex, - filterText, - sortKey, - sortOrder, - onNewState, + pagination, + sorting, + onTableChange, } = this; const component = ( diff --git a/x-pack/plugins/monitoring/public/views/logstash/nodes/index.html b/x-pack/plugins/monitoring/public/views/logstash/nodes/index.html index 8385a12a92e83..6da00b1c771b8 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/nodes/index.html +++ b/x-pack/plugins/monitoring/public/views/logstash/nodes/index.html @@ -1,19 +1,3 @@ - -
-

-

- -
+
diff --git a/x-pack/plugins/monitoring/public/views/logstash/nodes/index.js b/x-pack/plugins/monitoring/public/views/logstash/nodes/index.js index 7f614ab22572e..c86320491c916 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/nodes/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/nodes/index.js @@ -3,13 +3,16 @@ * 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 { render } from 'react-dom'; import { find } from 'lodash'; import uiRoutes from'ui/routes'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; -import { MonitoringViewBaseTableController } from '../../'; +import { MonitoringViewBaseEuiTableController } from '../../'; import { getPageData } from './get_page_data'; import template from './index.html'; +import { I18nProvider } from '@kbn/i18n/react'; +import { Listing } from '../../../components/logstash/listing'; uiRoutes.when('/logstash/nodes', { template, @@ -21,13 +24,11 @@ uiRoutes.when('/logstash/nodes', { pageData: getPageData }, controllerAs: 'lsNodes', - controller: class LsNodesList extends MonitoringViewBaseTableController { + controller: class LsNodesList extends MonitoringViewBaseEuiTableController { - constructor($injector, $scope, i18n) { + constructor($injector, $scope) { super({ - title: i18n('xpack.monitoring.logstash.nodes.routeTitle', { - defaultMessage: 'Logstash - Nodes' - }), + title: 'Logstash - Nodes', storageKey: 'logstash.nodes', getPageData, $scope, @@ -35,9 +36,34 @@ uiRoutes.when('/logstash/nodes', { }); const $route = $injector.get('$route'); + const kbnUrl = $injector.get('kbnUrl'); this.data = $route.current.locals.pageData; const globalState = $injector.get('globalState'); $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); + + const renderReact = (data) => { + if (!data) { + return; + } + + render( + + + , + document.getElementById('monitoringLogstashNodesApp') + ); + }; + + $scope.$watch(() => this.data, data => { + renderReact(data); + }); } } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/overview/index.html b/x-pack/plugins/monitoring/public/views/logstash/overview/index.html index 6c8f53ac5f96b..088aa35892bbe 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/overview/index.html +++ b/x-pack/plugins/monitoring/public/views/logstash/overview/index.html @@ -1,10 +1,3 @@ - -
-
-
-
-
-
-
+
diff --git a/x-pack/plugins/monitoring/public/views/logstash/overview/index.js b/x-pack/plugins/monitoring/public/views/logstash/overview/index.js index 19ad7fe50c0a8..749f0da9155e8 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/overview/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/overview/index.js @@ -7,12 +7,16 @@ /** * Logstash Overview */ +import React from 'react'; +import { render } from 'react-dom'; import { find } from 'lodash'; import uiRoutes from'ui/routes'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import template from './index.html'; import { timefilter } from 'ui/timefilter'; +import { I18nProvider } from '@kbn/i18n/react'; +import { Overview } from '../../../components/logstash/overview'; function getPageData($injector) { const $http = $injector.get('$http'); @@ -44,7 +48,7 @@ uiRoutes.when('/logstash', { }, pageData: getPageData }, - controller($injector, $scope, i18n) { + controller($injector, $scope) { timefilter.enableTimeRangeSelector(); timefilter.enableAutoRefreshSelector(); @@ -54,9 +58,7 @@ uiRoutes.when('/logstash', { $scope.pageData = $route.current.locals.pageData; const title = $injector.get('title'); - title($scope.cluster, i18n('xpack.monitoring.logstash.overview.routeTitle', { - defaultMessage: 'Logstash' - })); + title($scope.cluster, 'Logstash'); const $executor = $injector.get('$executor'); $executor.register({ @@ -65,5 +67,21 @@ uiRoutes.when('/logstash', { }); $executor.start($scope); $scope.$on('$destroy', $executor.destroy); + + function renderReact(pageData) { + render( + + + , + document.getElementById('monitoringLogstashOverviewApp') + ); + } + + $scope.$watch('pageData', pageData => { + renderReact(pageData); + }); } }); diff --git a/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.html b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.html index 070c7b04cfb73..bef8a7a4737f3 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.html +++ b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.html @@ -3,11 +3,5 @@ name="pipelines" data-test-subj="logstashPipelinesListing" > - -
- -
+
diff --git a/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js index 27e68ae56976b..8881f053794bf 100644 --- a/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js +++ b/x-pack/plugins/monitoring/public/views/logstash/pipelines/index.js @@ -4,8 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ +import React from 'react'; import { find } from 'lodash'; +import { render } from 'react-dom'; import uiRoutes from 'ui/routes'; +import moment from 'moment'; import { ajaxErrorHandlersProvider } from 'plugins/monitoring/lib/ajax_error_handler'; import { routeInitProvider } from 'plugins/monitoring/lib/route_init'; import { @@ -13,6 +16,9 @@ import { } from 'plugins/monitoring/lib/logstash/pipelines'; import template from './index.html'; import { timefilter } from 'ui/timefilter'; +import { I18nProvider } from '@kbn/i18n/react'; +import { PipelineListing } from '../../../components/logstash/pipeline_listing/pipeline_listing'; +import { MonitoringViewBaseEuiTableController } from '../..'; /* * Logstash Pipelines Listing page @@ -40,16 +46,14 @@ const getPageData = ($injector) => { }); }; -function makeUpgradeMessage(logstashVersions, i18n) { +function makeUpgradeMessage(logstashVersions) { if (!Array.isArray(logstashVersions) || (logstashVersions.length === 0) || logstashVersions.some(isPipelineMonitoringSupportedInVersion)) { return null; } - return i18n('xpack.monitoring.logstash.pipelines.notAvalibleDescription', { - defaultMessage: 'Pipeline monitoring is only available in Logstash version 6.0.0 or higher.' - }); + return 'Pipeline monitoring is only available in Logstash version 6.0.0 or higher.'; } uiRoutes @@ -62,30 +66,63 @@ uiRoutes }, pageData: getPageData }, - controller($injector, $scope, i18n) { - const $route = $injector.get('$route'); - const globalState = $injector.get('globalState'); - const title = $injector.get('title'); - const $executor = $injector.get('$executor'); + controller: class LogstashPipelinesList extends MonitoringViewBaseEuiTableController { + constructor($injector, $scope) { + super({ + title: 'Logstash Pipelines', + storageKey: 'logstash.pipelines', + getPageData, + $scope, + $injector + }); - $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.pageData = $route.current.locals.pageData; + const $route = $injector.get('$route'); + const kbnUrl = $injector.get('kbnUrl'); + this.data = $route.current.locals.pageData; + const globalState = $injector.get('globalState'); + $scope.cluster = find($route.current.locals.clusters, { cluster_uuid: globalState.cluster_uuid }); - $scope.upgradeMessage = makeUpgradeMessage($scope.pageData.clusterStatus.versions, i18n); - timefilter.enableTimeRangeSelector(); - timefilter.enableAutoRefreshSelector(); + function onBrush(xaxis) { + timefilter.setTime({ + from: moment(xaxis.from), + to: moment(xaxis.to), + mode: 'absolute' + }); + } - title($scope.cluster, i18n('xpack.monitoring.logstash.pipelines.routeTitle', { - defaultMessage: 'Logstash Pipelines' - })); + const renderReact = (pageData) => { + if (!pageData) { + return; + } - $executor.register({ - execute: () => getPageData($injector), - handleResponse: (response) => $scope.pageData = response - }); + const upgradeMessage = pageData + ? makeUpgradeMessage(pageData.clusterStatus.versions) + : null; - $executor.start($scope); + render( + + + , + document.getElementById('monitoringLogstashPipelinesApp') + ); + }; - $scope.$on('$destroy', $executor.destroy); + $scope.$watch(() => this.data, pageData => { + renderReact(pageData); + }); + } } }); diff --git a/x-pack/test/functional/services/monitoring/beats_listing.js b/x-pack/test/functional/services/monitoring/beats_listing.js index 505c0238b5458..3e61f1ea29919 100644 --- a/x-pack/test/functional/services/monitoring/beats_listing.js +++ b/x-pack/test/functional/services/monitoring/beats_listing.js @@ -15,8 +15,7 @@ export function MonitoringBeatsListingProvider({ getService, getPageObjects }) { const SUBJ_TABLE_CONTAINER = 'beatsTableContainer'; const SUBJ_SEARCH_BAR = `${SUBJ_TABLE_CONTAINER} monitoringTableToolBar`; - const SUBJ_TABLE_BODY = 'beatsTableBody'; - const SUBJ_INDEX_LINK_PREFIX = `${SUBJ_TABLE_BODY} beatLink-`; + const SUBJ_INDEX_LINK_PREFIX = `${SUBJ_TABLE_CONTAINER} beatLink-`; return new class BeatsListing { diff --git a/x-pack/test/functional/services/monitoring/logstash_pipelines.js b/x-pack/test/functional/services/monitoring/logstash_pipelines.js index 2a24e2534acbd..be5251a748c92 100644 --- a/x-pack/test/functional/services/monitoring/logstash_pipelines.js +++ b/x-pack/test/functional/services/monitoring/logstash_pipelines.js @@ -13,16 +13,15 @@ export function MonitoringLogstashPipelinesProvider({ getService, getPageObjects const SUBJ_LISTING_PAGE = 'logstashPipelinesListing'; - const SUBJ_TABLE_CONTAINER = 'logstashPipelinesTableContainer'; + const SUBJ_TABLE_CONTAINER = 'monitoringLogstashPipelinesTableContainer'; const SUBJ_TABLE_NO_DATA = `${SUBJ_TABLE_CONTAINER} monitoringTableNoData`; const SUBJ_SEARCH_BAR = `${SUBJ_TABLE_CONTAINER} monitoringTableToolBar`; - const SUBJ_TABLE_SORT_EVENTS_EMITTED_RATE_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell-eventsEmittedRate`; + const SUBJ_TABLE_SORT_EVENTS_EMITTED_RATE_COL = `${SUBJ_TABLE_CONTAINER} tableHeaderCell_latestThroughput_1`; - const SUBJ_TABLE_BODY = 'logstashPipelinesTableBody'; - const SUBJ_PIPELINES_IDS = `${SUBJ_TABLE_BODY} id`; - const SUBJ_PIPELINES_EVENTS_EMITTED_RATES = `${SUBJ_TABLE_BODY} eventsEmittedRate`; - const SUBJ_PIPELINES_NODE_COUNTS = `${SUBJ_TABLE_BODY} nodeCount`; + const SUBJ_PIPELINES_IDS = `${SUBJ_TABLE_CONTAINER} id`; + const SUBJ_PIPELINES_EVENTS_EMITTED_RATES = `${SUBJ_TABLE_CONTAINER} eventsEmittedRate`; + const SUBJ_PIPELINES_NODE_COUNTS = `${SUBJ_TABLE_CONTAINER} nodeCount`; return new class LogstashPipelines { async isOnListing() { @@ -31,7 +30,7 @@ export function MonitoringLogstashPipelinesProvider({ getService, getPageObjects } getRows() { - return PageObjects.monitoring.tableGetRows(SUBJ_TABLE_BODY); + return PageObjects.monitoring.tableGetRowsFromContainer(SUBJ_TABLE_CONTAINER); } async getPipelinesAll() { @@ -69,7 +68,7 @@ export function MonitoringLogstashPipelinesProvider({ getService, getPageObjects } assertNoData() { - return PageObjects.monitoring.assertTableNoData(SUBJ_TABLE_NO_DATA); + return PageObjects.monitoring.assertEuiTableNoData(SUBJ_TABLE_NO_DATA); } }; }