Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Monitoring] APM Monitoring UI #22975

Merged
merged 30 commits into from
Sep 24, 2018
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
8b510a2
Merge in boilerplate branch
chrisronline Sep 12, 2018
004ba9e
Manually copy over the specific metrics and UIs
chrisronline Sep 12, 2018
bbc0f9b
Add api integration tests
chrisronline Aug 31, 2018
5408598
Fix tests
chrisronline Sep 12, 2018
39783b0
Remove unused metrics
chrisronline Sep 12, 2018
807037f
Update snapshot
chrisronline Sep 13, 2018
6b50192
Fix tests
chrisronline Sep 13, 2018
bb65e55
Merge remote-tracking branch 'elastic/master' into monitoring_apm_ui
chrisronline Sep 19, 2018
b1d744d
Remove types agg
chrisronline Sep 19, 2018
512a8f7
Use ApmClusterMetric
chrisronline Sep 19, 2018
488829d
provide description for apm-server monitoring metrics (#23331)
graphaelli Sep 19, 2018
0e9329d
Vis LESS to SASS (cont.) (#23199)
cchaos Sep 19, 2018
75d8472
Tweak migrations integraiton tests to have a stable sort (#23265)
chrisdavies Sep 19, 2018
434c0bd
Fix: plugin api route with security enabled (#23334)
w33ble Sep 19, 2018
ab91dda
[migrations/tests] sort results before assertion (#23347)
Sep 20, 2018
91871c1
[ML] Moves custom URL editor Add button and form to top of flyout (#2…
peteharverson Sep 20, 2018
65797d8
Graph LESS to SASS (#23348)
cchaos Sep 20, 2018
210eacb
Developer documentation for integrating with the telemetry service (#…
tsullivan Sep 20, 2018
ab2062c
Fix a bug where ES sends a string and migrations expect a boolean (#2…
chrisdavies Sep 20, 2018
c90443f
chore: use cheerio in i18n.html.getDirectiveMessages (#23342)
w33ble Sep 20, 2018
0cc2b61
[core/utils] add shareWeakReplay() operator (#23333)
Sep 20, 2018
54ba953
Chore: fix canvas test runner (#23336)
w33ble Sep 20, 2018
6fdf6ad
Convert Discover open top nav to EUI flyout (#22971)
nreese Sep 20, 2018
236c0e9
Migrate save top nav in Discover and Visualize to EUI (#23190)
nreese Sep 20, 2018
6829db6
Moves styleSheetPath to uiExports (#23007)
tylersmalley Sep 21, 2018
0de2a64
Timelion less to sass (#23339)
cchaos Sep 21, 2018
2c7d140
Consistent casing
chrisronline Sep 21, 2018
699629c
Merge remote-tracking branch 'elastic/master' into monitoring_apm_ui
chrisronline Sep 21, 2018
4ee344e
Fix snapshot
chrisronline Sep 24, 2018
6a7ce25
Update tests
chrisronline Sep 24, 2018
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
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 { ApmServerInstance } from './instance';
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* 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 { MonitoringTimeseriesContainer } from '../../chart';
import {
EuiFlexItem,
EuiPanel,
EuiSpacer,
EuiPage,
EuiPageBody,
EuiFlexGroup
} from '@elastic/eui';
import { Status } from './status';

export function ApmServerInstance({ summary, metrics, ...props }) {
const seriesToShow = [
metrics.apm_responses_valid,
metrics.apm_responses_errors,

metrics.apm_output_events_rate_success,
metrics.apm_output_events_rate_failure,

metrics.apm_requests,
metrics.apm_transformations,


metrics.apm_cpu,
metrics.apm_memory,

metrics.apm_os_load,
];

const charts = seriesToShow.map((data, index) => (
<EuiFlexItem style={{ minWidth: '45%' }} key={index}>
<EuiPanel>
<MonitoringTimeseriesContainer
series={data}
{...props}
/>
</EuiPanel>
</EuiFlexItem>
));

return (
<EuiPage style={{ backgroundColor: 'white' }}>
<EuiPageBody>
<Status stats={summary}/>
<EuiSpacer size="s"/>
<EuiFlexGroup wrap>
{charts}
</EuiFlexGroup>
</EuiPageBody>
</EuiPage>
);
}
64 changes: 64 additions & 0 deletions x-pack/plugins/monitoring/public/components/apm/instance/status.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* 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, { Fragment } from 'react';
import moment from 'moment';
import { SummaryStatus } from '../../summary_status';
import { ApmStatusIcon } from '../status_icon';
import { formatMetric } from '../../../lib/format_number';
import { formatTimestampToDuration } from '../../../../common';

export function Status({ stats }) {
const {
name,
output,
version,
uptime,
timeOfLastEvent,
} = stats;

const metrics = [
{
label: 'Name',
value: name,
dataTestSubj: 'name'
},
{
label: 'Output',
value: output,
dataTestSubj: 'output'
},
{
label: 'Version',
value: version,
dataTestSubj: 'version'
},
{
label: 'Uptime',
value: formatMetric(uptime, 'time_since'),
dataTestSubj: 'uptime'
},
{
label: 'Last Event',
value: formatTimestampToDuration(+moment(timeOfLastEvent), 'since') + ' ago',
dataTestSubj: 'timeOfLastEvent',
}
];

const IconComponent = ({ status }) => (
<Fragment>
Status: <ApmStatusIcon status={status} />
</Fragment>
);

return (
<SummaryStatus
metrics={metrics}
IconComponent={IconComponent}
data-test-subj="apmDetailStatus"
/>
);
}
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 { ApmServerInstances } from './instances';
107 changes: 107 additions & 0 deletions x-pack/plugins/monitoring/public/components/apm/instances/instances.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/*
* 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 moment from 'moment';
import { MonitoringTable } from '../../table';
import {
KuiTableRowCell,
KuiTableRow
} from '@kbn/ui-framework/components';
import { EuiLink } 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';


const filterFields = [ 'name', 'type', 'version', 'output' ];
const columns = [
{ title: 'Name', sortKey: 'name', sortOrder: SORT_ASCENDING },
{ title: 'Output Enabled', sortKey: 'output' },
{ title: 'Total Events Rate', sortKey: 'total_events_rate', secondarySortOrder: SORT_DESCENDING },
{ title: 'Bytes Sent Rate', sortKey: 'bytes_sent_rate' },
{ title: 'Output Errors', sortKey: 'errors' },
{ title: 'Last Event', sortKey: 'time_of_last_event' },
{ title: 'Allocated Memory', sortKey: 'memory' },
{ title: 'Version', sortKey: 'version' },
];
const instanceRowFactory = () => {
return function KibanaRow(props) {
const applyFiltering = filterText => () => {
props.dispatchTableAction(TABLE_ACTION_UPDATE_FILTER, filterText);
};

return (
<KuiTableRow>
<KuiTableRowCell>
<div className="monTableCell__name">
<EuiLink
href={`#/apm/instances/${props.uuid}`}
data-test-subj={`apmLink-${props.name}`}
>
{props.name}
</EuiLink>
</div>
</KuiTableRowCell>
<KuiTableRowCell>
{props.output}
</KuiTableRowCell>
<KuiTableRowCell>
{formatMetric(props.total_events_rate, '', '/s')}
</KuiTableRowCell>
<KuiTableRowCell>
{formatMetric(props.bytes_sent_rate, 'byte', '/s')}
</KuiTableRowCell>
<KuiTableRowCell>
{formatMetric(props.errors, '0')}
</KuiTableRowCell>
<KuiTableRowCell>
{formatTimestampToDuration(+moment(props.time_of_last_event), 'since') + ' ago'}
</KuiTableRowCell>
<KuiTableRowCell>
{formatMetric(props.memory, 'byte')}
</KuiTableRowCell>
<KuiTableRowCell>
<EuiLink
onClick={applyFiltering(props.version)}
>
{props.version}
</EuiLink>
</KuiTableRowCell>
</KuiTableRow>
);
};
};

export function ApmServerInstances({ apms }) {
const {
pageIndex,
filterText,
sortKey,
sortOrder,
onNewState,
} = apms;

return (
<div>
<Status stats={apms.data.stats}/>
<MonitoringTable
className="apmInstancesTable"
rows={apms.data.apms}
pageIndex={pageIndex}
filterText={filterText}
sortKey={sortKey}
sortOrder={sortOrder}
onNewState={onNewState}
placeholder="Filter Instances..."
filterFields={filterFields}
columns={columns}
rowComponent={instanceRowFactory()}
/>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* 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, { Fragment } from 'react';
import moment from 'moment';
import { SummaryStatus } from '../../summary_status';
import { ApmStatusIcon } from '../status_icon';
import { formatMetric } from '../../../lib/format_number';
import { formatTimestampToDuration } from '../../../../common';

export function Status({ stats }) {
const {
apms: {
total
},
totalEvents,
timeOfLastEvent,
} = stats;

const metrics = [
{
label: 'Servers',
value: total,
dataTestSubj: 'total'
},
{
label: 'Total Events',
value: formatMetric(totalEvents, '0.[0]a'),
dataTestSubj: 'totalEvents'
},
{
label: 'Last Event',
value: formatTimestampToDuration(+moment(timeOfLastEvent), 'since') + ' ago',
dataTestSubj: 'timeOfLastEvent',
}
];

const IconComponent = ({ status }) => (
<Fragment>
Status: <ApmStatusIcon status={status} />
</Fragment>
);

return (
<SummaryStatus
metrics={metrics}
IconComponent={IconComponent}
data-test-subj="apmDetailStatus"
/>
);
}
63 changes: 63 additions & 0 deletions x-pack/plugins/monitoring/public/components/apm/overview/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* 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 { MonitoringTimeseriesContainer } from '../../chart';
import {
EuiSpacer,
EuiPage,
EuiFlexGroup,
EuiFlexItem,
EuiPageBody,
EuiPanel
} from '@elastic/eui';
import { Status } from '../instances/status';

export function ApmOverview({
stats,
metrics,
...props
}) {
const seriesToShow = [
metrics.apm_responses_valid,
metrics.apm_responses_errors,

metrics.apm_output_events_rate_success,
metrics.apm_output_events_rate_failure,

metrics.apm_requests,
metrics.apm_transformations,


metrics.apm_cpu,
metrics.apm_memory,

metrics.apm_os_load,
];

const charts = seriesToShow.map((data, index) => (
<EuiFlexItem style={{ minWidth: '45%' }} key={index}>
<EuiPanel>
<MonitoringTimeseriesContainer
series={data}
{...props}
/>
</EuiPanel>
</EuiFlexItem>
));

return (
<EuiPage style={{ backgroundColor: 'white' }}>
<EuiPageBody>
<Status stats={stats}/>
<EuiSpacer size="s"/>
<EuiFlexGroup wrap>
{charts}
</EuiFlexGroup>
</EuiPageBody>
</EuiPage>
);
}
23 changes: 23 additions & 0 deletions x-pack/plugins/monitoring/public/components/apm/status_icon.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* 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 { StatusIcon } from 'plugins/monitoring/components/status_icon';

export function ApmStatusIcon({ status, availability = true }) {
const type = (() => {
if (!availability) {
return StatusIcon.TYPES.GRAY;
}

const statusKey = status.toUpperCase();
return StatusIcon.TYPES[statusKey] || StatusIcon.TYPES.YELLOW;
})();

return (
<StatusIcon type={type} label={`Health: ${status}`} />
);
}
Loading