Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions x-pack/plugins/monitoring/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ export const INDEX_PATTERN_FILEBEAT = 'filebeat-*';
// This is the unique token that exists in monitoring indices collected by metricbeat
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';
/**
* 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 @@ -75,6 +75,7 @@ const getProps = (field) => {
upTime: 28056934,
version: ['8.0.0']
},
setupMode: {},
nodes,
sorting: {
sort: { field: 'name', direction: 'asc' }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import React from 'react';
import React, { Fragment } from 'react';
import { NodeStatusIcon } from '../node';
import { extractIp } from '../../../lib/extract_ip'; // TODO this is only used for elasticsearch nodes summary / node detail, so it should be moved to components/elasticsearch/nodes/lib
import { ClusterStatus } from '../cluster_status';
Expand All @@ -18,6 +18,8 @@ import {
EuiPageContent,
EuiPageBody,
EuiPanel,
EuiCallOut,
EuiButton,
EuiText
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
Expand Down Expand Up @@ -207,7 +209,37 @@ const getColumns = showCgroupMetricsElasticsearch => {

export function ElasticsearchNodes({ clusterStatus, nodes, showCgroupMetricsElasticsearch, ...props }) {
const columns = getColumns(showCgroupMetricsElasticsearch);
const { sorting, pagination, onTableChange } = props;
const { sorting, pagination, onTableChange, setupMode } = props;

let disableInternalCollectionForMigrationMessage = null;
if (setupMode.data) {
if (setupMode.data.totalUniquePartiallyMigratedCount === setupMode.data.totalUniqueInstanceCount) {
disableInternalCollectionForMigrationMessage = (
<Fragment>
<EuiCallOut
title={i18n.translate('xpack.monitoring.elasticsearch.nodes.metribeatMigration.disableInternalCollectionTitle', {
defaultMessage: 'Disable internal collection to finish the migration',
})}
color="warning"
iconType="help"
>
<p>
{i18n.translate('xpack.monitoring.elasticsearch.nodes.metribeatMigration.disableInternalCollectionDescription', {
defaultMessage: `All of your Elasticsearch servers are monitored using Metricbeat,
but you need to disable internal collection to finish the migration.`
})}
</p>
<EuiButton onClick={() => setupMode.openFlyout()} size="s" color="warning" fill>
{i18n.translate('xpack.monitoring.elasticsearch.nodes.metribeatMigration.disableInternalCollectionMigrationButtonLabel', {
defaultMessage: 'Disable and finish migration'
})}
</EuiButton>
</EuiCallOut>
<EuiSpacer size="m"/>
</Fragment>
);
}
}

return (
<EuiPage>
Expand All @@ -216,13 +248,17 @@ export function ElasticsearchNodes({ clusterStatus, nodes, showCgroupMetricsElas
<ClusterStatus stats={clusterStatus} />
</EuiPanel>
<EuiSpacer size="m" />
{disableInternalCollectionForMigrationMessage}
<EuiPageContent>
<EuiMonitoringTable
className="elasticsearchNodesTable"
rows={nodes}
columns={columns}
sorting={sorting}
pagination={pagination}
setupMode={setupMode}
uuidField="resolver"
nameField="name"
search={{
box: {
incremental: true,
Expand Down
Original file line number Diff line number Diff line change
@@ -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 { KibanaInstances } from './instances';
Original file line number Diff line number Diff line change
@@ -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, { PureComponent } from 'react';
import { EuiPage, EuiPageBody, EuiPageContent, EuiPanel, EuiSpacer, EuiLink } from '@elastic/eui';
import { capitalize } from 'lodash';
import { ClusterStatus } from '../cluster_status';
import { EuiMonitoringTable } from '../../table';
import { KibanaStatusIcon } from '../status_icon';
import { formatMetric, formatNumber } from '../../../lib/format_number';
import { i18n } from '@kbn/i18n';
import { FormattedMessage } from '@kbn/i18n/react';

const getColumns = (kbnUrl, scope) => {
const columns = [
{
name: i18n.translate('xpack.monitoring.kibana.listing.nameColumnTitle', {
defaultMessage: 'Name'
}),
field: 'name',
render: (name, kibana) => (
<EuiLink
onClick={() => {
scope.$evalAsync(() => {
kbnUrl.changePath(`/kibana/instances/${kibana.kibana.uuid}`);
});
}}
data-test-subj={`kibanaLink-${name}`}
>
{ name }
</EuiLink>
)
},
{
name: i18n.translate('xpack.monitoring.kibana.listing.statusColumnTitle', {
defaultMessage: 'Status'
}),
field: 'status',
render: (status, kibana) => (
<div
title={`Instance status: ${status}`}
className="monTableCell__status"
>
<KibanaStatusIcon status={status} availability={kibana.availability} />&nbsp;
{ !kibana.availability ? (
<FormattedMessage
id="xpack.monitoring.kibana.listing.instanceStatus.offlineLabel"
defaultMessage="Offline"
/>
) : capitalize(status) }
</div>
)
},
{
name: i18n.translate('xpack.monitoring.kibana.listing.loadAverageColumnTitle', {
defaultMessage: 'Load Average'
}),
field: 'os.load.1m',
render: value => (
<span>
{formatMetric(value, '0.00')}
</span>
)
},
{
name: i18n.translate('xpack.monitoring.kibana.listing.memorySizeColumnTitle', {
defaultMessage: 'Memory Size'
}),
field: 'process.memory.resident_set_size_in_bytes',
render: value => (
<span>
{formatNumber(value, 'byte')}
</span>
)
},
{
name: i18n.translate('xpack.monitoring.kibana.listing.requestsColumnTitle', {
defaultMessage: 'Requests'
}),
field: 'requests.total',
render: value => (
<span>
{formatNumber(value, 'int_commas')}
</span>
)
},
{
name: i18n.translate('xpack.monitoring.kibana.listing.responseTimeColumnTitle', {
defaultMessage: 'Response Times'
}),
// It is possible this does not exist through MB collection
field: 'response_times.average',
render: (value, kibana) => {
if (!value) {
return null;
}

return (
<div>
<div className="monTableCell__splitNumber">
{ (formatNumber(value, 'int_commas') + ' ms avg') }
</div>
<div className="monTableCell__splitNumber">
{ formatNumber(kibana.response_times.max, 'int_commas') } ms max
</div>
</div>
);
}
}
];

return columns;
};

export class KibanaInstances extends PureComponent {
render() {
const {
instances,
clusterStatus,
angular,
setupMode,
sorting,
pagination,
onTableChange
} = this.props;

const dataFlattened = instances.map(item => ({
...item,
name: item.kibana.name,
status: item.kibana.status,
}));

return (
<EuiPage>
<EuiPageBody>
<EuiPanel>
<ClusterStatus stats={clusterStatus} />
</EuiPanel>
<EuiSpacer size="m" />
<EuiPageContent>
<EuiMonitoringTable
className="kibanaInstancesTable"
rows={dataFlattened}
columns={getColumns(angular.kbnUrl, angular.$scope)}
sorting={sorting}
pagination={pagination}
setupMode={setupMode}
uuidField="kibana.uuid"
nameField="name"
search={{
box: {
incremental: true,
placeholder: i18n.translate('xpack.monitoring.kibana.listing.filterInstancesPlaceholder', {
defaultMessage: 'Filter Instances…'
})
},
}}
onTableChange={onTableChange}
executeQueryOptions={{
defaultFields: ['name']
}}
/>
</EuiPageContent>
</EuiPageBody>
</EuiPage>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/*
* 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 const INSTRUCTION_STEP_SET_MONITORING_URL = 'setMonitoringUrl';
export const INSTRUCTION_STEP_ENABLE_METRICBEAT = 'enableMetricbeat';
export const INSTRUCTION_STEP_DISABLE_INTERNAL = 'disableInternal';
Loading