Skip to content

Commit 3b13e2f

Browse files
[APM] Service overview transactions table (#83429) (#84072)
Co-authored-by: Dario Gieselaar <[email protected]>
1 parent e5433f0 commit 3b13e2f

File tree

22 files changed

+1186
-69
lines changed

22 files changed

+1186
-69
lines changed

x-pack/plugins/apm/common/utils/formatters/duration.ts

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ import { i18n } from '@kbn/i18n';
88
import moment from 'moment';
99
import { memoize } from 'lodash';
1010
import { NOT_AVAILABLE_LABEL } from '../../../common/i18n';
11-
import { asDecimalOrInteger, asInteger } from './formatters';
11+
import { asDecimal, asDecimalOrInteger, asInteger } from './formatters';
1212
import { TimeUnit } from './datetime';
1313
import { Maybe } from '../../../typings/common';
14+
import { isFiniteNumber } from '../is_finite_number';
1415

1516
interface FormatterOptions {
1617
defaultValue?: string;
@@ -99,7 +100,7 @@ function convertTo({
99100
microseconds: Maybe<number>;
100101
defaultValue?: string;
101102
}): ConvertedDuration {
102-
if (microseconds == null) {
103+
if (!isFiniteNumber(microseconds)) {
103104
return { value: defaultValue, formatted: defaultValue };
104105
}
105106

@@ -143,14 +144,37 @@ export const getDurationFormatter: TimeFormatterBuilder = memoize(
143144
}
144145
);
145146

147+
export function asTransactionRate(value: Maybe<number>) {
148+
if (!isFiniteNumber(value)) {
149+
return NOT_AVAILABLE_LABEL;
150+
}
151+
152+
let displayedValue: string;
153+
154+
if (value === 0) {
155+
displayedValue = '0';
156+
} else if (value <= 0.1) {
157+
displayedValue = '< 0.1';
158+
} else {
159+
displayedValue = asDecimal(value);
160+
}
161+
162+
return i18n.translate('xpack.apm.transactionRateLabel', {
163+
defaultMessage: `{value} tpm`,
164+
values: {
165+
value: displayedValue,
166+
},
167+
});
168+
}
169+
146170
/**
147171
* Converts value and returns it formatted - 00 unit
148172
*/
149173
export function asDuration(
150174
value: Maybe<number>,
151175
{ defaultValue = NOT_AVAILABLE_LABEL }: FormatterOptions = {}
152176
) {
153-
if (value == null) {
177+
if (!isFiniteNumber(value)) {
154178
return defaultValue;
155179
}
156180

x-pack/plugins/apm/common/utils/formatters/formatters.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
*/
66
import numeral from '@elastic/numeral';
77
import { i18n } from '@kbn/i18n';
8+
import { Maybe } from '../../../typings/common';
9+
import { NOT_AVAILABLE_LABEL } from '../../i18n';
10+
import { isFiniteNumber } from '../is_finite_number';
811

912
export function asDecimal(value: number) {
1013
return numeral(value).format('0,0.0');
@@ -25,11 +28,11 @@ export function tpmUnit(type?: string) {
2528
}
2629

2730
export function asPercent(
28-
numerator: number,
31+
numerator: Maybe<number>,
2932
denominator: number | undefined,
30-
fallbackResult = ''
33+
fallbackResult = NOT_AVAILABLE_LABEL
3134
) {
32-
if (!denominator || isNaN(numerator)) {
35+
if (!denominator || !isFiniteNumber(numerator)) {
3336
return fallbackResult;
3437
}
3538

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License;
4+
* you may not use this file except in compliance with the Elastic License.
5+
*/
6+
import { isFinite } from 'lodash';
7+
import { Maybe } from '../../typings/common';
8+
9+
// _.isNumber() returns true for NaN, _.isFinite() does not refine
10+
export function isFiniteNumber(value: Maybe<number>): value is number {
11+
return isFinite(value);
12+
}

x-pack/plugins/apm/public/components/app/ServiceMap/Popover/ServiceStatsList.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,21 +65,19 @@ export function ServiceStatsList({
6565
title: i18n.translate('xpack.apm.serviceMap.errorRatePopoverStat', {
6666
defaultMessage: 'Trans. error rate (avg.)',
6767
}),
68-
description: isNumber(avgErrorRate) ? asPercent(avgErrorRate, 1) : null,
68+
description: asPercent(avgErrorRate, 1, ''),
6969
},
7070
{
7171
title: i18n.translate('xpack.apm.serviceMap.avgCpuUsagePopoverStat', {
7272
defaultMessage: 'CPU usage (avg.)',
7373
}),
74-
description: isNumber(avgCpuUsage) ? asPercent(avgCpuUsage, 1) : null,
74+
description: asPercent(avgCpuUsage, 1, ''),
7575
},
7676
{
7777
title: i18n.translate('xpack.apm.serviceMap.avgMemoryUsagePopoverStat', {
7878
defaultMessage: 'Memory usage (avg.)',
7979
}),
80-
description: isNumber(avgMemoryUsage)
81-
? asPercent(avgMemoryUsage, 1)
82-
: null,
80+
description: asPercent(avgMemoryUsage, 1, ''),
8381
},
8482
];
8583

x-pack/plugins/apm/public/components/app/ServiceNodeOverview/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ function ServiceNodeOverview({ serviceName }: ServiceNodeOverviewProps) {
128128
}),
129129
field: 'cpu',
130130
sortable: true,
131-
render: (value: number | null) => asPercent(value || 0, 1),
131+
render: (value: number | null) => asPercent(value, 1),
132132
},
133133
{
134134
name: i18n.translate('xpack.apm.jvmsTable.heapMemoryColumnLabel', {

x-pack/plugins/apm/public/components/app/service_inventory/ServiceList/ServiceListMetric.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66
import React from 'react';
7-
import { useUrlParams } from '../../../../hooks/useUrlParams';
87
import { SparkPlotWithValueLabel } from '../../../shared/charts/spark_plot/spark_plot_with_value_label';
98

109
export function ServiceListMetric({
@@ -16,14 +15,8 @@ export function ServiceListMetric({
1615
series?: Array<{ x: number; y: number | null }>;
1716
valueLabel: React.ReactNode;
1817
}) {
19-
const {
20-
urlParams: { start, end },
21-
} = useUrlParams();
22-
2318
return (
2419
<SparkPlotWithValueLabel
25-
start={parseFloat(start!)}
26-
end={parseFloat(end!)}
2720
valueLabel={valueLabel}
2821
series={series}
2922
color={color}

x-pack/plugins/apm/public/components/app/service_inventory/ServiceList/index.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,7 @@ export const SERVICE_COLUMNS: Array<ITableColumn<ServiceListItem>> = [
177177
render: (_, { transactionErrorRate }) => {
178178
const value = transactionErrorRate?.value;
179179

180-
const valueLabel =
181-
value !== null && value !== undefined ? asPercent(value, 1) : '';
180+
const valueLabel = asPercent(value, 1);
182181

183182
return (
184183
<ServiceListMetric

x-pack/plugins/apm/public/components/app/service_overview/index.tsx

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ import { isRumAgentName } from '../../../../common/agent_name';
1818
import { ChartsSyncContextProvider } from '../../../context/charts_sync_context';
1919
import { TransactionErrorRateChart } from '../../shared/charts/transaction_error_rate_chart';
2020
import { ServiceMapLink } from '../../shared/Links/apm/ServiceMapLink';
21-
import { TransactionOverviewLink } from '../../shared/Links/apm/TransactionOverviewLink';
2221
import { SearchBar } from '../../shared/search_bar';
2322
import { ServiceOverviewErrorsTable } from './service_overview_errors_table';
23+
import { ServiceOverviewTransactionsTable } from './service_overview_transactions_table';
2424
import { TableLinkFlexItem } from './table_link_flex_item';
2525

2626
/**
@@ -78,30 +78,7 @@ export function ServiceOverview({
7878
</EuiFlexItem>
7979
<EuiFlexItem grow={6}>
8080
<EuiPanel>
81-
<EuiFlexGroup justifyContent="spaceBetween">
82-
<EuiFlexItem>
83-
<EuiTitle size="xs">
84-
<h2>
85-
{i18n.translate(
86-
'xpack.apm.serviceOverview.transactionsTableTitle',
87-
{
88-
defaultMessage: 'Transactions',
89-
}
90-
)}
91-
</h2>
92-
</EuiTitle>
93-
</EuiFlexItem>
94-
<TableLinkFlexItem>
95-
<TransactionOverviewLink serviceName={serviceName}>
96-
{i18n.translate(
97-
'xpack.apm.serviceOverview.transactionsTableLinkText',
98-
{
99-
defaultMessage: 'View transactions',
100-
}
101-
)}
102-
</TransactionOverviewLink>
103-
</TableLinkFlexItem>
104-
</EuiFlexGroup>
81+
<ServiceOverviewTransactionsTable serviceName={serviceName} />
10582
</EuiPanel>
10683
</EuiFlexItem>
10784
</EuiFlexGroup>

x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ import { px, truncate, unit } from '../../../../style/variables';
2121
import { SparkPlotWithValueLabel } from '../../../shared/charts/spark_plot/spark_plot_with_value_label';
2222
import { ErrorDetailLink } from '../../../shared/Links/apm/ErrorDetailLink';
2323
import { ErrorOverviewLink } from '../../../shared/Links/apm/ErrorOverviewLink';
24+
import { TableFetchWrapper } from '../../../shared/table_fetch_wrapper';
2425
import { TimestampTooltip } from '../../../shared/TimestampTooltip';
2526
import { ServiceOverviewTable } from '../service_overview_table';
2627
import { TableLinkFlexItem } from '../table_link_flex_item';
27-
import { FetchWrapper } from './fetch_wrapper';
2828

2929
interface Props {
3030
serviceName: string;
@@ -135,8 +135,6 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) {
135135
},
136136
}
137137
)}
138-
start={parseFloat(start!)}
139-
end={parseFloat(end!)}
140138
/>
141139
);
142140
},
@@ -225,7 +223,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) {
225223
</EuiFlexGroup>
226224
</EuiFlexItem>
227225
<EuiFlexItem>
228-
<FetchWrapper status={status}>
226+
<TableFetchWrapper status={status}>
229227
<ServiceOverviewTable
230228
columns={columns}
231229
items={items}
@@ -261,7 +259,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) {
261259
},
262260
}}
263261
/>
264-
</FetchWrapper>
262+
</TableFetchWrapper>
265263
</EuiFlexItem>
266264
</EuiFlexGroup>
267265
);

0 commit comments

Comments
 (0)