Skip to content

Commit

Permalink
[Monitoring] Metricbeat Migration Wizard (last step!!) (#45799) (#47136)
Browse files Browse the repository at this point in the history
* Enable setup mode UI toggles

* We want to keep the no data page but update the copy

* More updated copy

* Remove manual checks for logstash, beats, apm and kibana

* Hide the setup mode controls on the no data page. There is nothing different in setup mode

* Setup mode test

* Fix bug with disabling internal collection for ES

* First steps towards the redesign of setup mode

* Consolidate UI code, design changes, use constants defined in our plugin

* Fix tooltips

* Design/copy feedback

* Use badge and onClick

* More feedback

* Only detect usage on the live cluster

* Fix existing tests, remove test that will be added in other PR

* Fix failing test

* Fix issue with wrong callout showing

* Ensure we check for live nodes if no cluster uuid is provided

* We need a custom listing callout for ES

* Custom callout for kibana instances

* More space from the bottom bar

* Disable switching if they enabled internal collection

* Copy updates

* Fix broken tests

* Fix more tests

* Fix i18n

* Update copy

* Fix a couple i18n issues

* Fixing a couple of missing scenarios

* Fix translations

* Update snapshots

* PR feedback

* PR feedback

* We also need totalUniqueInternallyCollectedCount to identify when we have detected products but they are not monitored (thinking ES and Kibana)

* Remove why documentation link until we have the resource available

* Ensure tabs are properly disabled

* Address issue with the ES nodes callout not working at times

* Ensure we check if setup mode is enabled

* Change internal collection to self monitoring, and remove the word 'collection' usage

* Only show Enter setup mode on pages with valid setup mode options

* Copy updates

* Copy updates

* Ensure we update the top nav item when we toggle setup mode on or off
  • Loading branch information
chrisronline authored Oct 2, 2019
1 parent 8fb34c0 commit 8751538
Show file tree
Hide file tree
Showing 70 changed files with 1,790 additions and 2,270 deletions.
7 changes: 5 additions & 2 deletions x-pack/legacy/plugins/monitoring/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,11 @@ export const INDEX_PATTERN_FILEBEAT = 'filebeat-*';
export const METRICBEAT_INDEX_NAME_UNIQUE_TOKEN = '-mb-';

// We use this for metricbeat migration to identify specific products that we do not have constants for
export const ELASTICSEARCH_CUSTOM_ID = 'elasticsearch';
export const APM_CUSTOM_ID = 'apm';
export const ELASTICSEARCH_SYSTEM_ID = 'elasticsearch';
export const KIBANA_SYSTEM_ID = 'kibana';
export const BEATS_SYSTEM_ID = 'beats';
export const APM_SYSTEM_ID = 'apm';
export const LOGSTASH_SYSTEM_ID = 'logstash';
/**
* The id of the infra source owned by the monitoring plugin.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,80 +8,111 @@ import React, { Fragment } from 'react';
import moment from 'moment';
import { uniq, get } from 'lodash';
import { EuiMonitoringTable } from '../../table';
import { EuiLink, EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiCallOut } from '@elastic/eui';
import { EuiLink, EuiPage, EuiPageBody, EuiPageContent, EuiSpacer } from '@elastic/eui';
import { Status } from './status';
import { formatMetric } from '../../../lib/format_number';
import { formatTimestampToDuration } from '../../../../common';
import { i18n } from '@kbn/i18n';
import { APM_SYSTEM_ID } from '../../../../common/constants';
import { ListingCallOut } from '../../setup_mode/listing_callout';
import { SetupModeBadge } from '../../setup_mode/badge';

const columns = [
{
name: i18n.translate('xpack.monitoring.apm.instances.nameTitle', {
defaultMessage: 'Name'
}),
field: 'name',
render: (name, instance) => (
<EuiLink
href={`#/apm/instances/${instance.uuid}`}
data-test-subj={`apmLink-${name}`}
>
{name}
</EuiLink>
)
},
{
name: i18n.translate('xpack.monitoring.apm.instances.outputEnabledTitle', {
defaultMessage: 'Output Enabled'
}),
field: 'output'
},
{
name: i18n.translate('xpack.monitoring.apm.instances.totalEventsRateTitle', {
defaultMessage: 'Total Events Rate'
}),
field: 'total_events_rate',
render: value => formatMetric(value, '', '/s')
},
{
name: i18n.translate('xpack.monitoring.apm.instances.bytesSentRateTitle', {
defaultMessage: 'Bytes Sent Rate'
}),
field: 'bytes_sent_rate',
render: value => formatMetric(value, 'byte', '/s')
},
{
name: i18n.translate('xpack.monitoring.apm.instances.outputErrorsTitle', {
defaultMessage: 'Output Errors'
}),
field: 'errors',
render: value => formatMetric(value, '0')
},
{
name: i18n.translate('xpack.monitoring.apm.instances.lastEventTitle', {
defaultMessage: 'Last Event'
}),
field: 'time_of_last_event',
render: value => i18n.translate('xpack.monitoring.apm.instances.lastEventValue', {
defaultMessage: '{timeOfLastEvent} ago',
values: {
timeOfLastEvent: formatTimestampToDuration(+moment(value), 'since')
function getColumns(setupMode) {
return [
{
name: i18n.translate('xpack.monitoring.apm.instances.nameTitle', {
defaultMessage: 'Name'
}),
field: 'name',
render: (name, apm) => {
let setupModeStatus = null;
if (setupMode && setupMode.enabled) {
const list = get(setupMode, 'data.byUuid', {});
const status = list[apm.uuid] || {};
const instance = {
uuid: apm.uuid,
name: apm.name
};

setupModeStatus = (
<div className="monTableCell__setupModeStatus">
<SetupModeBadge
setupMode={setupMode}
status={status}
instance={instance}
productName={APM_SYSTEM_ID}
/>
</div>
);
}

return (
<Fragment>
<EuiLink
href={`#/apm/instances/${apm.uuid}`}
data-test-subj={`apmLink-${name}`}
>
{name}
</EuiLink>
{setupModeStatus}
</Fragment>
);
}
})
},
{
name: i18n.translate('xpack.monitoring.apm.instances.allocatedMemoryTitle', {
defaultMessage: 'Allocated Memory'
}),
field: 'memory',
render: value => formatMetric(value, 'byte')
},
{
name: i18n.translate('xpack.monitoring.apm.instances.versionTitle', {
defaultMessage: 'Version'
}),
field: 'version'
},
];
},
{
name: i18n.translate('xpack.monitoring.apm.instances.outputEnabledTitle', {
defaultMessage: 'Output Enabled'
}),
field: 'output'
},
{
name: i18n.translate('xpack.monitoring.apm.instances.totalEventsRateTitle', {
defaultMessage: 'Total Events Rate'
}),
field: 'total_events_rate',
render: value => formatMetric(value, '', '/s')
},
{
name: i18n.translate('xpack.monitoring.apm.instances.bytesSentRateTitle', {
defaultMessage: 'Bytes Sent Rate'
}),
field: 'bytes_sent_rate',
render: value => formatMetric(value, 'byte', '/s')
},
{
name: i18n.translate('xpack.monitoring.apm.instances.outputErrorsTitle', {
defaultMessage: 'Output Errors'
}),
field: 'errors',
render: value => formatMetric(value, '0')
},
{
name: i18n.translate('xpack.monitoring.apm.instances.lastEventTitle', {
defaultMessage: 'Last Event'
}),
field: 'time_of_last_event',
render: value => i18n.translate('xpack.monitoring.apm.instances.lastEventValue', {
defaultMessage: '{timeOfLastEvent} ago',
values: {
timeOfLastEvent: formatTimestampToDuration(+moment(value), 'since')
}
})
},
{
name: i18n.translate('xpack.monitoring.apm.instances.allocatedMemoryTitle', {
defaultMessage: 'Allocated Memory'
}),
field: 'memory',
render: value => formatMetric(value, 'byte')
},
{
name: i18n.translate('xpack.monitoring.apm.instances.versionTitle', {
defaultMessage: 'Version'
}),
field: 'version'
},
];
}

export function ApmServerInstances({ apms, setupMode }) {
const {
Expand All @@ -91,26 +122,14 @@ export function ApmServerInstances({ apms, setupMode }) {
data,
} = apms;

let detectedInstanceMessage = null;
if (setupMode.enabled && setupMode.data && get(setupMode.data, 'detected.mightExist')) {
detectedInstanceMessage = (
<Fragment>
<EuiCallOut
title={i18n.translate('xpack.monitoring.apm.instances.metricbeatMigration.detectedInstanceTitle', {
defaultMessage: 'APM server detected',
})}
color="warning"
iconType="help"
>
<p>
{i18n.translate('xpack.monitoring.apm.instances.metricbeatMigration.detectedInstanceDescription', {
defaultMessage: `Based on your indices, we think you might have an APM server. Click the 'Setup monitoring'
button below to start monitoring this APM server.`
})}
</p>
</EuiCallOut>
<EuiSpacer size="m"/>
</Fragment>
let setupModeCallout = null;
if (setupMode.enabled && setupMode.data) {
setupModeCallout = (
<ListingCallOut
setupModeData={setupMode.data}
useNodeIdentifier={false}
productName={APM_SYSTEM_ID}
/>
);
}

Expand All @@ -124,19 +143,15 @@ export function ApmServerInstances({ apms, setupMode }) {
<EuiPageContent>
<Status stats={data.stats} />
<EuiSpacer size="m"/>
{detectedInstanceMessage}
{setupModeCallout}
<EuiMonitoringTable
className="apmInstancesTable"
rows={data.apms}
columns={columns}
columns={getColumns(setupMode)}
sorting={sorting}
pagination={pagination}
setupMode={setupMode}
uuidField="uuid"
nameField="name"
setupNewButtonLabel={i18n.translate('xpack.monitoring.apm.metricbeatMigration.setupNewButtonLabel', {
defaultMessage: 'Setup monitoring for new APM server'
})}
productName={APM_SYSTEM_ID}
search={{
box: {
incremental: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,64 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React, { PureComponent, Fragment } from 'react';
import React, { PureComponent } from 'react';
import { uniq, get } from 'lodash';
import { EuiPage, EuiPageBody, EuiPageContent, EuiSpacer, EuiLink, EuiCallOut } from '@elastic/eui';
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 { BEATS_SYSTEM_ID } from '../../../../common/constants';
import { ListingCallOut } from '../../setup_mode/listing_callout';
import { SetupModeBadge } from '../../setup_mode/badge';

export class Listing extends PureComponent {
getColumns() {
const { kbnUrl, scope } = this.props.angular;
const setupMode = this.props.setupMode;

return [
{
name: i18n.translate('xpack.monitoring.beats.instances.nameTitle', { defaultMessage: 'Name' }),
field: 'name',
render: (name, beat) => (
<EuiLink
onClick={() => {
scope.$evalAsync(() => {
kbnUrl.changePath(`/beats/beat/${beat.uuid}`);
});
}}
data-test-subj={`beatLink-${name}`}
>
{name}
</EuiLink>
)
render: (name, beat) => {
let setupModeStatus = null;
if (setupMode && setupMode.enabled) {
const list = get(setupMode, 'data.byUuid', {});
const status = list[beat.uuid] || {};
const instance = {
uuid: beat.uuid,
name: beat.name
};

setupModeStatus = (
<div className="monTableCell__setupModeStatus">
<SetupModeBadge
setupMode={setupMode}
status={status}
instance={instance}
productName={BEATS_SYSTEM_ID}
/>
</div>
);
}

return (
<div>
<EuiLink
onClick={() => {
scope.$evalAsync(() => {
kbnUrl.changePath(`/beats/beat/${beat.uuid}`);
});
}}
data-test-subj={`beatLink-${name}`}
>
{name}
</EuiLink>
{setupModeStatus}
</div>
);
}
},
{
name: i18n.translate('xpack.monitoring.beats.instances.typeTitle', { defaultMessage: 'Type' }),
Expand Down Expand Up @@ -78,26 +108,14 @@ export class Listing extends PureComponent {
setupMode
} = this.props;

let detectedInstanceMessage = null;
if (setupMode.enabled && setupMode.data && get(setupMode.data, 'detected.mightExist')) {
detectedInstanceMessage = (
<Fragment>
<EuiCallOut
title={i18n.translate('xpack.monitoring.beats.instances.metricbeatMigration.detectedInstanceTitle', {
defaultMessage: 'Beats instance detected',
})}
color="warning"
iconType="help"
>
<p>
{i18n.translate('xpack.monitoring.beats.instances.metricbeatMigration.detectedInstanceDescription', {
defaultMessage: `Based on your indices, we think you might have a beats instance. Click the 'Setup monitoring'
button below to start monitoring this instance.`
})}
</p>
</EuiCallOut>
<EuiSpacer size="m"/>
</Fragment>
let setupModeCallOut = null;
if (setupMode.enabled && setupMode.data) {
setupModeCallOut = (
<ListingCallOut
setupModeData={setupMode.data}
useNodeIdentifier={false}
productName={BEATS_SYSTEM_ID}
/>
);
}

Expand All @@ -115,16 +133,12 @@ export class Listing extends PureComponent {
<EuiPageContent>
<Stats stats={stats} />
<EuiSpacer size="m"/>
{detectedInstanceMessage}
{setupModeCallOut}
<EuiMonitoringTable
className="beatsTable"
rows={data}
setupMode={setupMode}
uuidField="uuid"
nameField="name"
setupNewButtonLabel={i18n.translate('xpack.monitoring.beats.metricbeatMigration.setupNewButtonLabel', {
defaultMessage: 'Setup monitoring for new Beats instance'
})}
productName={BEATS_SYSTEM_ID}
columns={this.getColumns()}
sorting={sorting}
pagination={pagination}
Expand Down
Loading

0 comments on commit 8751538

Please sign in to comment.