diff --git a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js b/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js index f1633799ea583..2fae8bdab2b30 100644 --- a/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js +++ b/x-pack/plugins/apm/e2e/cypress/integration/snapshots.js @@ -1,10 +1,10 @@ module.exports = { - "APM": { - "Transaction duration charts": { - "1": "350 ms", - "2": "175 ms", - "3": "0 ms" - } + APM: { + 'Transaction duration charts': { + '1': '350.0 ms', + '2': '175.0 ms', + '3': '0.0 ms', + }, }, - "__version": "4.5.0" -} + __version: '4.5.0', +}; diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/__test__/List.test.js b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/__test__/List.test.js index 927779b571fd8..09fef5da16ae7 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/__test__/List.test.js +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/__test__/List.test.js @@ -40,7 +40,7 @@ describe('ServiceOverview -> List', () => { expect(renderedColumns[0]).toMatchSnapshot(); expect(renderedColumns.slice(2)).toEqual([ 'python', - '92 ms', + '91.5 ms', '86.9 tpm', '12.6 err.', ]); diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx index b9048f013cb25..90cc9af45273e 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/ServiceList/index.tsx @@ -12,7 +12,7 @@ import styled from 'styled-components'; import { ServiceListAPIResponse } from '../../../../../server/lib/services/get_services'; import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n'; import { fontSizes, truncate } from '../../../../style/variables'; -import { asDecimal, convertTo } from '../../../../utils/formatters'; +import { asDecimal, asMillisecondDuration } from '../../../../utils/formatters'; import { ManagedTable } from '../../../shared/ManagedTable'; import { EnvironmentBadge } from '../../../shared/EnvironmentBadge'; import { TransactionOverviewLink } from '../../../shared/Links/apm/TransactionOverviewLink'; @@ -81,11 +81,7 @@ export const SERVICE_COLUMNS = [ }), sortable: true, dataType: 'number', - render: (time: number) => - convertTo({ - unit: 'milliseconds', - microseconds: time, - }).formatted, + render: (time: number) => asMillisecondDuration(time), }, { field: 'transactionsPerMinute', diff --git a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap index 3e6be107ce3a1..e89acca55d4fe 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap +++ b/x-pack/plugins/apm/public/components/app/ServiceOverview/__test__/__snapshots__/ServiceOverview.test.tsx.snap @@ -203,7 +203,7 @@ NodeList [
- 1 ms + 0.6 ms
- 0 ms + 0.3 ms > = [ }), sortable: true, dataType: 'number', - render: (time: number) => - convertTo({ - unit: 'milliseconds', - microseconds: time, - }).formatted, + render: (time: number) => asMillisecondDuration(time), }, { field: 'transactionsPerMinute', diff --git a/x-pack/plugins/apm/public/components/app/TransactionOverview/List/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionOverview/List/index.tsx index 61c8d3958b625..ae1b07bde0c87 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionOverview/List/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionOverview/List/index.tsx @@ -12,7 +12,7 @@ import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ITransactionGroup } from '../../../../../server/lib/transaction_groups/transform'; import { fontFamilyCode, truncate } from '../../../../style/variables'; -import { asDecimal, convertTo } from '../../../../utils/formatters'; +import { asDecimal, asMillisecondDuration } from '../../../../utils/formatters'; import { ImpactBar } from '../../../shared/ImpactBar'; import { ITableColumn, ManagedTable } from '../../../shared/ManagedTable'; import { LoadingStatePrompt } from '../../../shared/LoadingStatePrompt'; @@ -29,12 +29,6 @@ interface Props { isLoading: boolean; } -const toMilliseconds = (time: number) => - convertTo({ - unit: 'milliseconds', - microseconds: time, - }).formatted; - export function TransactionList({ items, isLoading }: Props) { const columns: Array> = useMemo( () => [ @@ -74,7 +68,7 @@ export function TransactionList({ items, isLoading }: Props) { ), sortable: true, dataType: 'number', - render: (time: number) => toMilliseconds(time), + render: (time: number) => asMillisecondDuration(time), }, { field: 'p95', @@ -86,7 +80,7 @@ export function TransactionList({ items, isLoading }: Props) { ), sortable: true, dataType: 'number', - render: (time: number) => toMilliseconds(time), + render: (time: number) => asMillisecondDuration(time), }, { field: 'transactionsPerMinute', diff --git a/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/test/__snapshots__/CustomPlot.test.js.snap b/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/test/__snapshots__/CustomPlot.test.js.snap index 4c7d21d968088..b7ea026f80fde 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/test/__snapshots__/CustomPlot.test.js.snap +++ b/x-pack/plugins/apm/public/components/shared/charts/CustomPlot/test/__snapshots__/CustomPlot.test.js.snap @@ -9,7 +9,7 @@ Array [ "text": Avg. - 468 ms + 467.6 ms , }, @@ -2744,7 +2744,7 @@ Array [ - 468 ms + 467.6 ms @@ -5923,7 +5923,7 @@ Array [ - 468 ms + 467.6 ms diff --git a/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/Histogram.test.js b/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/Histogram.test.js index 1d0a53843f538..f84b0cfeda369 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/Histogram.test.js +++ b/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/Histogram.test.js @@ -78,7 +78,7 @@ describe('Histogram', () => { const tooltips = wrapper.find('Tooltip'); expect(tooltips.length).toBe(1); - expect(tooltips.prop('header')).toBe('811 - 927 ms'); + expect(tooltips.prop('header')).toBe('811.1 - 926.9 ms'); expect(tooltips.prop('tooltipPoints')).toEqual([ { value: '49.0 occurrences' }, ]); diff --git a/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/__snapshots__/Histogram.test.js.snap b/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/__snapshots__/Histogram.test.js.snap index f1c7d4826fe0c..700602eb56929 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/__snapshots__/Histogram.test.js.snap +++ b/x-pack/plugins/apm/public/components/shared/charts/Histogram/__test__/__snapshots__/Histogram.test.js.snap @@ -127,7 +127,7 @@ exports[`Histogram Initially should have default markup 1`] = ` textAnchor="middle" transform="translate(0, 18)" > - 0 ms + 0.0 ms - 500 ms + 500.0 ms - 1,000 ms + 1,000.0 ms - 1,500 ms + 1,500.0 ms - 2,000 ms + 2,000.0 ms - 2,500 ms + 2,500.0 ms - 3,000 ms + 3,000.0 ms @@ -1477,7 +1477,7 @@ exports[`Histogram when hovering over a non-empty bucket should have correct mar
- 811 - 927 ms + 811.1 - 926.9 ms
diff --git a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/ErrorMarker.test.tsx b/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/ErrorMarker.test.tsx index d133ba5e715fd..6a28155813766 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/ErrorMarker.test.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/Timeline/Marker/ErrorMarker.test.tsx @@ -31,7 +31,7 @@ describe('ErrorMarker', () => { act(() => { fireEvent.click(component.getByTestId('popover')); }); - expectTextsInDocument(component, ['10,000 μs']); + expectTextsInDocument(component, ['10.0 ms']); return component; } function getKueryDecoded(url: string) { diff --git a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx index 3c1f4c54fc635..915b55f29ef80 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/TransactionCharts/index.tsx @@ -120,7 +120,7 @@ export class TransactionCharts extends Component { 'xpack.apm.metrics.transactionChart.machineLearningTooltip', { defaultMessage: - 'The stream around the average duration shows the expected bounds. An annotation is shown for anomaly scores >= 75.', + 'The stream around the average duration shows the expected bounds. An annotation is shown for anomaly scores ≥ 75.', } )} /> diff --git a/x-pack/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts b/x-pack/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts index da9c32c84f36f..2f0a30a5019a9 100644 --- a/x-pack/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts +++ b/x-pack/plugins/apm/public/selectors/__tests__/chartSelectors.test.ts @@ -62,7 +62,7 @@ describe('chartSelectors', () => { { x: 0, y: 100 }, { x: 1000, y: 200 }, ], - legendValue: '0 ms', + legendValue: '200 μs', title: 'Avg.', type: 'linemark', }, diff --git a/x-pack/plugins/apm/public/selectors/chartSelectors.ts b/x-pack/plugins/apm/public/selectors/chartSelectors.ts index cfe1a6a60cd22..f8aed9dcf6d9f 100644 --- a/x-pack/plugins/apm/public/selectors/chartSelectors.ts +++ b/x-pack/plugins/apm/public/selectors/chartSelectors.ts @@ -18,7 +18,7 @@ import { RectCoordinate, TimeSeries, } from '../../typings/timeseries'; -import { asDecimal, tpmUnit, convertTo } from '../utils/formatters'; +import { asDecimal, asDuration, tpmUnit } from '../utils/formatters'; import { IUrlParams } from '../context/UrlParamsContext/types'; import { getEmptySeries } from '../components/shared/charts/CustomPlot/getEmptySeries'; import { httpStatusCodeToColor } from '../utils/httpStatusCodeToColor'; @@ -72,10 +72,7 @@ export function getResponseTimeSeries({ }: TimeSeriesAPIResponse) { const { overallAvgDuration } = apmTimeseries; const { avg, p95, p99 } = apmTimeseries.responseTimes; - const formattedDuration = convertTo({ - unit: 'milliseconds', - microseconds: overallAvgDuration, - }).formatted; + const formattedDuration = asDuration(overallAvgDuration); const series: TimeSeries[] = [ { diff --git a/x-pack/plugins/apm/public/utils/formatters/__test__/duration.test.ts b/x-pack/plugins/apm/public/utils/formatters/__test__/duration.test.ts index de3e3868de396..6d4b65d2aa9b4 100644 --- a/x-pack/plugins/apm/public/utils/formatters/__test__/duration.test.ts +++ b/x-pack/plugins/apm/public/utils/formatters/__test__/duration.test.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { asDuration, convertTo, toMicroseconds } from '../duration'; +import { asDuration, toMicroseconds, asMillisecondDuration } from '../duration'; describe('duration formatters', () => { describe('asDuration', () => { @@ -14,10 +14,10 @@ describe('duration formatters', () => { expect(asDuration(1)).toEqual('1 μs'); expect(asDuration(toMicroseconds(1, 'milliseconds'))).toEqual('1,000 μs'); expect(asDuration(toMicroseconds(1000, 'milliseconds'))).toEqual( - '1,000 ms' + '1,000.0 ms' ); expect(asDuration(toMicroseconds(10000, 'milliseconds'))).toEqual( - '10,000 ms' + '10,000.0 ms' ); expect(asDuration(toMicroseconds(20, 'seconds'))).toEqual('20.0 s'); expect(asDuration(toMicroseconds(10, 'minutes'))).toEqual('10.0 min'); @@ -30,96 +30,6 @@ describe('duration formatters', () => { }); }); - describe('convertTo', () => { - it('hours', () => { - const unit = 'hours'; - const oneHourAsMicro = toMicroseconds(1, 'hours'); - const twoHourAsMicro = toMicroseconds(2, 'hours'); - expect(convertTo({ unit, microseconds: oneHourAsMicro })).toEqual({ - unit: 'h', - value: '1.0', - formatted: '1.0 h', - }); - expect(convertTo({ unit, microseconds: twoHourAsMicro })).toEqual({ - unit: 'h', - value: '2.0', - formatted: '2.0 h', - }); - expect( - convertTo({ unit, microseconds: null, defaultValue: '1.2' }) - ).toEqual({ value: '1.2', formatted: '1.2' }); - }); - - it('minutes', () => { - const unit = 'minutes'; - const oneHourAsMicro = toMicroseconds(1, 'hours'); - const twoHourAsMicro = toMicroseconds(2, 'hours'); - expect(convertTo({ unit, microseconds: oneHourAsMicro })).toEqual({ - unit: 'min', - value: '60.0', - formatted: '60.0 min', - }); - expect(convertTo({ unit, microseconds: twoHourAsMicro })).toEqual({ - unit: 'min', - value: '120.0', - formatted: '120.0 min', - }); - expect( - convertTo({ unit, microseconds: null, defaultValue: '10' }) - ).toEqual({ value: '10', formatted: '10' }); - }); - - it('seconds', () => { - const unit = 'seconds'; - const twentySecondsAsMicro = toMicroseconds(20, 'seconds'); - const thirtyFiveSecondsAsMicro = toMicroseconds(35, 'seconds'); - expect(convertTo({ unit, microseconds: twentySecondsAsMicro })).toEqual({ - unit: 's', - value: '20.0', - formatted: '20.0 s', - }); - expect( - convertTo({ unit, microseconds: thirtyFiveSecondsAsMicro }) - ).toEqual({ unit: 's', value: '35.0', formatted: '35.0 s' }); - expect( - convertTo({ unit, microseconds: null, defaultValue: '10' }) - ).toEqual({ value: '10', formatted: '10' }); - }); - - it('milliseconds', () => { - const unit = 'milliseconds'; - const twentyMilliAsMicro = toMicroseconds(20, 'milliseconds'); - const thirtyFiveMilliAsMicro = toMicroseconds(35, 'milliseconds'); - expect(convertTo({ unit, microseconds: twentyMilliAsMicro })).toEqual({ - unit: 'ms', - value: '20', - formatted: '20 ms', - }); - expect( - convertTo({ unit, microseconds: thirtyFiveMilliAsMicro }) - ).toEqual({ unit: 'ms', value: '35', formatted: '35 ms' }); - expect( - convertTo({ unit, microseconds: null, defaultValue: '10' }) - ).toEqual({ value: '10', formatted: '10' }); - }); - - it('microseconds', () => { - const unit = 'microseconds'; - expect(convertTo({ unit, microseconds: 20 })).toEqual({ - unit: 'μs', - value: '20', - formatted: '20 μs', - }); - expect(convertTo({ unit, microseconds: 35 })).toEqual({ - unit: 'μs', - value: '35', - formatted: '35 μs', - }); - expect( - convertTo({ unit, microseconds: null, defaultValue: '10' }) - ).toEqual({ value: '10', formatted: '10' }); - }); - }); describe('toMicroseconds', () => { it('transformes to microseconds', () => { expect(toMicroseconds(1, 'hours')).toEqual(3600000000); @@ -128,4 +38,10 @@ describe('duration formatters', () => { expect(toMicroseconds(10, 'milliseconds')).toEqual(10000); }); }); + + describe('asMilliseconds', () => { + it('converts to formatted decimal milliseconds', () => { + expect(asMillisecondDuration(0)).toEqual('0.0 ms'); + }); + }); }); diff --git a/x-pack/plugins/apm/public/utils/formatters/duration.ts b/x-pack/plugins/apm/public/utils/formatters/duration.ts index af87f7d517cb9..a603faab37538 100644 --- a/x-pack/plugins/apm/public/utils/formatters/duration.ts +++ b/x-pack/plugins/apm/public/utils/formatters/duration.ts @@ -65,7 +65,7 @@ const durationUnit: DurationUnit = { defaultMessage: 'ms', }), convert: (value: number) => - asInteger(moment.duration(value / 1000).asMilliseconds()), + asDecimal(moment.duration(value / 1000).asMilliseconds()), }, microseconds: { label: i18n.translate('xpack.apm.formatters.microsTimeUnitLabel', { @@ -77,13 +77,8 @@ const durationUnit: DurationUnit = { /** * Converts a microseconds value into the unit defined. - * - * @param param0 - * { unit: "milliseconds" | "hours" | "minutes" | "seconds" | "microseconds", microseconds, defaultValue } - * - * @returns object { value, unit, formatted } */ -export function convertTo({ +function convertTo({ unit, microseconds, defaultValue = NOT_AVAILABLE_LABEL, @@ -118,7 +113,7 @@ function getDurationUnitKey(max: number): DurationTimeUnit { if (max > toMicroseconds(10, 'seconds')) { return 'seconds'; } - if (max > toMicroseconds(10, 'milliseconds')) { + if (max > toMicroseconds(1, 'milliseconds')) { return 'milliseconds'; } return 'microseconds'; @@ -135,10 +130,6 @@ export const getDurationFormatter: TimeFormatterBuilder = memoize( /** * Converts value and returns it formatted - 00 unit - * - * @param value - * @param param1 { defaultValue } - * @returns formated value - 00 unit */ export function asDuration( value: Maybe, @@ -151,3 +142,15 @@ export function asDuration( const formatter = getDurationFormatter(value); return formatter(value, { defaultValue }).formatted; } + +/** + * Convert a microsecond value to decimal milliseconds. Normally we use + * `asDuration`, but this is used in places like tables where we always want + * the same units. + */ +export function asMillisecondDuration(time: number) { + return convertTo({ + unit: 'milliseconds', + microseconds: time, + }).formatted; +}