Skip to content

Commit

Permalink
Instances latency distribution chart tooltips and axis fixes (#95577) (
Browse files Browse the repository at this point in the history
…#97050)

Fixes #88852

Co-authored-by: Nathan L Smith <nathan.smith@elastic.co>
  • Loading branch information
kibanamachine and smith authored Apr 13, 2021
1 parent 89f5f61 commit defa0f9
Show file tree
Hide file tree
Showing 10 changed files with 586 additions and 39 deletions.
7 changes: 0 additions & 7 deletions x-pack/plugins/apm/common/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,3 @@ export const NOT_AVAILABLE_LABEL = i18n.translate(
defaultMessage: 'N/A',
}
);

export const UNIDENTIFIED_SERVICE_NODES_LABEL = i18n.translate(
'xpack.apm.serviceNodeNameMissing',
{
defaultMessage: '(Empty)',
}
);
15 changes: 15 additions & 0 deletions x-pack/plugins/apm/common/service_nodes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,19 @@
* 2.0.
*/

import { i18n } from '@kbn/i18n';

export const SERVICE_NODE_NAME_MISSING = '_service_node_name_missing_';

const UNIDENTIFIED_SERVICE_NODES_LABEL = i18n.translate(
'xpack.apm.serviceNodeNameMissing',
{
defaultMessage: '(Empty)',
}
);

export function getServiceNodeName(serviceNodeName?: string) {
return serviceNodeName === SERVICE_NODE_NAME_MISSING || !serviceNodeName
? UNIDENTIFIED_SERVICE_NODES_LABEL
: serviceNodeName;
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { i18n } from '@kbn/i18n';
import React from 'react';
import { Redirect, RouteComponentProps } from 'react-router-dom';
import { ApmServiceContextProvider } from '../../../../context/apm_service/apm_service_context';
import { UNIDENTIFIED_SERVICE_NODES_LABEL } from '../../../../../common/i18n';
import { SERVICE_NODE_NAME_MISSING } from '../../../../../common/service_nodes';
import { getServiceNodeName } from '../../../../../common/service_nodes';
import { APMRouteDefinition } from '../../../../application/routes';
import { toQuery } from '../../../shared/Links/url_helpers';
import { ErrorGroupDetails } from '../../ErrorGroupDetails';
Expand Down Expand Up @@ -294,15 +293,7 @@ export const routes: APMRouteDefinition[] = [
exact: true,
path: '/services/:serviceName/nodes/:serviceNodeName/metrics',
component: withApmServiceContext(ServiceNodeMetrics),
breadcrumb: ({ match }) => {
const { serviceNodeName } = match.params;

if (serviceNodeName === SERVICE_NODE_NAME_MISSING) {
return UNIDENTIFIED_SERVICE_NODES_LABEL;
}

return serviceNodeName || '';
},
breadcrumb: ({ match }) => getServiceNodeName(match.params.serviceNodeName),
},
{
exact: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ import { EuiFlexGroup, EuiPage, EuiPanel, EuiToolTip } from '@elastic/eui';
import { i18n } from '@kbn/i18n';
import React from 'react';
import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common';
import { UNIDENTIFIED_SERVICE_NODES_LABEL } from '../../../../common/i18n';
import { SERVICE_NODE_NAME_MISSING } from '../../../../common/service_nodes';
import {
getServiceNodeName,
SERVICE_NODE_NAME_MISSING,
} from '../../../../common/service_nodes';
import {
asDynamicBytes,
asInteger,
Expand Down Expand Up @@ -83,7 +85,7 @@ function ServiceNodeOverview({ serviceName }: ServiceNodeOverviewProps) {
const { displayedName, tooltip } =
name === SERVICE_NODE_NAME_MISSING
? {
displayedName: UNIDENTIFIED_SERVICE_NODES_LABEL,
displayedName: getServiceNodeName(name),
tooltip: i18n.translate(
'xpack.apm.jvmsTable.explainServiceNodeNameMissing',
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,13 @@ import { useApmServiceContext } from '../../../context/apm_service/use_apm_servi
import { useUrlParams } from '../../../context/url_params_context/use_url_params';
import { FETCH_STATUS, useFetcher } from '../../../hooks/use_fetcher';
import { APIReturnType } from '../../../services/rest/createCallApmApi';
import { InstancesLatencyDistributionChart } from '../../shared/charts/instances_latency_distribution_chart';
import { getTimeRangeComparison } from '../../shared/time_comparison/get_time_range_comparison';
import {
ServiceOverviewInstancesTable,
TableOptions,
} from './service_overview_instances_table';

// We're hiding this chart until these issues are resolved in the 7.13 timeframe:
//
// * [[APM] Tooltips for instances latency distribution chart](https://github.com/elastic/kibana/issues/88852)
// * [[APM] x-axis on the instance bubble chart is broken](https://github.com/elastic/kibana/issues/92631)
//
// import { InstancesLatencyDistributionChart } from '../../shared/charts/instances_latency_distribution_chart';

interface ServiceOverviewInstancesChartAndTableProps {
chartHeight: number;
serviceName: string;
Expand Down Expand Up @@ -215,13 +209,13 @@ export function ServiceOverviewInstancesChartAndTable({

return (
<>
{/* <EuiFlexItem grow={3}>
<EuiFlexItem grow={3}>
<InstancesLatencyDistributionChart
height={chartHeight}
items={data.items}
status={status}
items={primaryStatsItems}
status={primaryStatsStatus}
/>
</EuiFlexItem> */}
</EuiFlexItem>
<EuiFlexItem grow={7}>
<EuiPanel>
<ServiceOverviewInstancesTable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import { i18n } from '@kbn/i18n';
import React from 'react';
import { LatencyAggregationType } from '../../../../../common/latency_aggregation_types';
import { isJavaAgentName } from '../../../../../common/agent_name';
import { UNIDENTIFIED_SERVICE_NODES_LABEL } from '../../../../../common/i18n';
import { SERVICE_NODE_NAME_MISSING } from '../../../../../common/service_nodes';
import {
getServiceNodeName,
SERVICE_NODE_NAME_MISSING,
} from '../../../../../common/service_nodes';
import {
asMillisecondDuration,
asPercent,
Expand Down Expand Up @@ -52,9 +54,7 @@ export function getColumns({
const { serviceNodeName } = item;
const isMissingServiceNodeName =
serviceNodeName === SERVICE_NODE_NAME_MISSING;
const text = isMissingServiceNodeName
? UNIDENTIFIED_SERVICE_NODES_LABEL
: serviceNodeName;
const text = getServiceNodeName(serviceNodeName);

const link = isJavaAgentName(agentName) ? (
<ServiceNodeMetricOverviewLink
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { TooltipInfo } from '@elastic/charts';
import React, { ComponentType } from 'react';
import { EuiThemeProvider } from '../../../../../../../../src/plugins/kibana_react/common';
import { getDurationFormatter } from '../../../../../common/utils/formatters';
import { PrimaryStatsServiceInstanceItem } from '../../../app/service_overview/service_overview_instances_chart_and_table';
import { CustomTooltip } from './custom_tooltip';

function getLatencyFormatter(props: TooltipInfo) {
const maxLatency = Math.max(
...props.values.map((value) => {
const datum = (value.datum as unknown) as PrimaryStatsServiceInstanceItem;
return datum.latency ?? 0;
})
);
return getDurationFormatter(maxLatency);
}

export default {
title: 'shared/charts/InstancesLatencyDistributionChart/CustomTooltip',
component: CustomTooltip,
decorators: [
(Story: ComponentType) => (
<EuiThemeProvider>
<Story />
</EuiThemeProvider>
),
],
};

export function Example(props: TooltipInfo) {
return (
<CustomTooltip {...props} latencyFormatter={getLatencyFormatter(props)} />
);
}
Example.args = {
header: {
seriesIdentifier: {
key:
'groupId{__global__}spec{Instances}yAccessor{(index:0)}splitAccessors{}',
specId: 'Instances',
yAccessor: '(index:0)',
splitAccessors: {},
seriesKeys: ['(index:0)'],
},
valueAccessor: 'y1',
label: 'Instances',
value: 9.473837632998105,
formattedValue: '9.473837632998105',
markValue: null,
color: '#6092c0',
isHighlighted: false,
isVisible: true,
datum: {
serviceNodeName:
'2f3221afa3f00d3bc07069d69efd5bd4c1607be6155a204551c8fe2e2b5dd750',
errorRate: 0.03496503496503497,
latency: 1057231.4125874126,
throughput: 9.473837632998105,
cpuUsage: 0.000033333333333333335,
memoryUsage: 0.18701022939403547,
},
},
values: [
{
seriesIdentifier: {
key:
'groupId{__global__}spec{Instances}yAccessor{(index:0)}splitAccessors{}',
specId: 'Instances',
},
valueAccessor: 'y1',
label: 'Instances',
value: 1057231.4125874126,
formattedValue: '1057231.4125874126',
markValue: null,
color: '#6092c0',
isHighlighted: true,
isVisible: true,
datum: {
serviceNodeName:
'2f3221afa3f00d3bc07069d69efd5bd4c1607be6155a204551c8fe2e2b5dd750',
errorRate: 0.03496503496503497,
latency: 1057231.4125874126,
throughput: 9.473837632998105,
cpuUsage: 0.000033333333333333335,
memoryUsage: 0.18701022939403547,
},
},
],
} as TooltipInfo;

export function MultipleInstances(props: TooltipInfo) {
return (
<CustomTooltip {...props} latencyFormatter={getLatencyFormatter(props)} />
);
}
MultipleInstances.args = {
header: {
seriesIdentifier: {
key:
'groupId{__global__}spec{Instances}yAccessor{(index:0)}splitAccessors{}',
specId: 'Instances',
yAccessor: '(index:0)',
splitAccessors: {},
seriesKeys: ['(index:0)'],
},
valueAccessor: 'y1',
label: 'Instances',
value: 9.606338858634443,
formattedValue: '9.606338858634443',
markValue: null,
color: '#6092c0',
isHighlighted: false,
isVisible: true,
datum: {
serviceNodeName:
'3b50ad269c45be69088905c4b355cc75ab94aaac1b35432bb752050438f4216f',
errorRate: 0.006896551724137931,
latency: 56465.53793103448,
throughput: 9.606338858634443,
cpuUsage: 0.0001,
memoryUsage: 0.1872131360014741,
},
},
values: [
{
seriesIdentifier: {
key:
'groupId{__global__}spec{Instances}yAccessor{(index:0)}splitAccessors{}',
specId: 'Instances',
},
valueAccessor: 'y1',
label: 'Instances',
value: 56465.53793103448,
formattedValue: '56465.53793103448',
markValue: null,
color: '#6092c0',
isHighlighted: true,
isVisible: true,
datum: {
serviceNodeName:
'3b50ad269c45be69088905c4b355cc75ab94aaac1b35432bb752050438f4216f',
errorRate: 0.006896551724137931,
latency: 56465.53793103448,
throughput: 9.606338858634443,
cpuUsage: 0.0001,
memoryUsage: 0.1872131360014741,
},
},
{
seriesIdentifier: {
key:
'groupId{__global__}spec{Instances}yAccessor{(index:0)}splitAccessors{}',
specId: 'Instances',
},
valueAccessor: 'y1',
label: 'Instances',
value: 56465.53793103448,
formattedValue: '56465.53793103448',
markValue: null,
color: '#6092c0',
isHighlighted: true,
isVisible: true,
datum: {
serviceNodeName:
'3b50ad269c45be69088905c4b355cc75ab94aaac1b35432bb752050438f4216f (2)',
errorRate: 0.006896551724137931,
latency: 56465.53793103448,
throughput: 9.606338858634443,
cpuUsage: 0.0001,
memoryUsage: 0.1872131360014741,
},
},
],
} as TooltipInfo;
Loading

0 comments on commit defa0f9

Please sign in to comment.