123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312 |
- import {t} from 'sentry/locale';
- import type {MetricType} from 'sentry/types/metrics';
- import {defined} from 'sentry/utils';
- import {formatBytesBase2} from 'sentry/utils/bytes/formatBytesBase2';
- import {formatBytesBase10} from 'sentry/utils/bytes/formatBytesBase10';
- import {
- DAY,
- formatAbbreviatedNumberWithDynamicPrecision,
- HOUR,
- MICROSECOND,
- MILLISECOND,
- MINUTE,
- MONTH,
- NANOSECOND,
- SECOND,
- WEEK,
- } from 'sentry/utils/formatters';
- import {formatNumberWithDynamicDecimalPoints} from 'sentry/utils/number/formatNumberWithDynamicDecimalPoints';
- const metricTypeToReadable: Record<MetricType, string> = {
- c: t('counter'),
- g: t('gauge'),
- d: t('distribution'),
- s: t('set'),
- e: t('derived'),
- };
- // Converts from "c" to "counter"
- export function getReadableMetricType(type?: string) {
- return metricTypeToReadable[type as MetricType] ?? t('unknown');
- }
- function formatDuration(seconds: number): string {
- if (!seconds) {
- return '0ms';
- }
- const absValue = Math.abs(seconds * 1000);
- // value in milliseconds
- const msValue = seconds * 1000;
- let unit: FormattingSupportedMetricUnit | 'month' = 'nanosecond';
- let value = msValue / NANOSECOND;
- if (absValue >= MONTH) {
- unit = 'month';
- value = msValue / MONTH;
- } else if (absValue >= WEEK) {
- unit = 'week';
- value = msValue / WEEK;
- } else if (absValue >= DAY) {
- unit = 'day';
- value = msValue / DAY;
- } else if (absValue >= HOUR) {
- unit = 'hour';
- value = msValue / HOUR;
- } else if (absValue >= MINUTE) {
- unit = 'minute';
- value = msValue / MINUTE;
- } else if (absValue >= SECOND) {
- unit = 'second';
- value = msValue / SECOND;
- } else if (absValue >= MILLISECOND) {
- unit = 'millisecond';
- value = msValue;
- } else if (absValue >= MICROSECOND) {
- unit = 'microsecond';
- value = msValue / MICROSECOND;
- }
- return `${formatNumberWithDynamicDecimalPoints(value)}${
- unit === 'month' ? 'mo' : METRIC_UNIT_TO_SHORT[unit]
- }`;
- }
- // The metric units that we have support for in the UI
- // others will still be displayed, but will not have any effect on formatting
- export const formattingSupportedMetricUnits = [
- 'none',
- 'nanosecond',
- 'nanoseconds',
- 'microsecond',
- 'microseconds',
- 'millisecond',
- 'milliseconds',
- 'second',
- 'seconds',
- 'minute',
- 'minutes',
- 'hour',
- 'hours',
- 'day',
- 'days',
- 'week',
- 'weeks',
- 'ratio',
- 'percent',
- 'percents',
- 'bit',
- 'bits',
- 'byte',
- 'bytes',
- 'kibibyte',
- 'kibibytes',
- 'kilobyte',
- 'kilobytes',
- 'mebibyte',
- 'mebibytes',
- 'megabyte',
- 'megabytes',
- 'gibibyte',
- 'gibibytes',
- 'gigabyte',
- 'gigabytes',
- 'tebibyte',
- 'tebibytes',
- 'terabyte',
- 'terabytes',
- 'pebibyte',
- 'pebibytes',
- 'petabyte',
- 'petabytes',
- 'exbibyte',
- 'exbibytes',
- 'exabyte',
- 'exabytes',
- ] as const;
- export type FormattingSupportedMetricUnit =
- (typeof formattingSupportedMetricUnits)[number];
- export const formattingSupportedMetricUnitsSingular: FormattingSupportedMetricUnit[] = [
- 'none',
- 'nanosecond',
- 'microsecond',
- 'millisecond',
- 'second',
- 'minute',
- 'hour',
- 'day',
- 'week',
- 'ratio',
- 'percent',
- 'bit',
- 'byte',
- 'kibibyte',
- 'kilobyte',
- 'mebibyte',
- 'megabyte',
- 'gibibyte',
- 'gigabyte',
- 'tebibyte',
- 'terabyte',
- 'pebibyte',
- 'petabyte',
- 'exbibyte',
- 'exabyte',
- ];
- const METRIC_UNIT_TO_SHORT: Record<FormattingSupportedMetricUnit, string> = {
- nanosecond: 'ns',
- nanoseconds: 'ns',
- microsecond: 'μs',
- microseconds: 'μs',
- millisecond: 'ms',
- milliseconds: 'ms',
- second: 's',
- seconds: 's',
- minute: 'min',
- minutes: 'min',
- hour: 'hr',
- hours: 'hr',
- day: 'day',
- days: 'day',
- week: 'wk',
- weeks: 'wk',
- ratio: '%',
- percent: '%',
- percents: '%',
- bit: 'b',
- bits: 'b',
- byte: 'B',
- bytes: 'B',
- kibibyte: 'KiB',
- kibibytes: 'KiB',
- kilobyte: 'KB',
- kilobytes: 'KB',
- mebibyte: 'MiB',
- mebibytes: 'MiB',
- megabyte: 'MB',
- megabytes: 'MB',
- gibibyte: 'GiB',
- gibibytes: 'GiB',
- gigabyte: 'GB',
- gigabytes: 'GB',
- tebibyte: 'TiB',
- tebibytes: 'TiB',
- terabyte: 'TB',
- terabytes: 'TB',
- pebibyte: 'PiB',
- pebibytes: 'PiB',
- petabyte: 'PB',
- petabytes: 'PB',
- exbibyte: 'EiB',
- exbibytes: 'EiB',
- exabyte: 'EB',
- exabytes: 'EB',
- none: '',
- };
- export function formatMetricUsingUnit(value: number | null, unit: string) {
- if (!defined(value)) {
- return '\u2014';
- }
- switch (unit as FormattingSupportedMetricUnit) {
- case 'nanosecond':
- case 'nanoseconds':
- return formatDuration(value / 1000000000);
- case 'microsecond':
- case 'microseconds':
- return formatDuration(value / 1000000);
- case 'millisecond':
- case 'milliseconds':
- return formatDuration(value / 1000);
- case 'second':
- case 'seconds':
- return formatDuration(value);
- case 'minute':
- case 'minutes':
- return formatDuration(value * 60);
- case 'hour':
- case 'hours':
- return formatDuration(value * 60 * 60);
- case 'day':
- case 'days':
- return formatDuration(value * 60 * 60 * 24);
- case 'week':
- case 'weeks':
- return formatDuration(value * 60 * 60 * 24 * 7);
- case 'ratio':
- return `${formatNumberWithDynamicDecimalPoints(value * 100)}%`;
- case 'percent':
- case 'percents':
- return `${formatNumberWithDynamicDecimalPoints(value)}%`;
- case 'bit':
- case 'bits':
- return formatBytesBase2(value / 8);
- case 'byte':
- case 'bytes':
- return formatBytesBase10(value);
- // Only used internally to support normalized byte metrics while preserving base 2 formatting
- case 'byte2' as FormattingSupportedMetricUnit:
- return formatBytesBase2(value);
- case 'kibibyte':
- case 'kibibytes':
- return formatBytesBase2(value * 1024);
- case 'kilobyte':
- case 'kilobytes':
- return formatBytesBase10(value, 1);
- case 'mebibyte':
- case 'mebibytes':
- return formatBytesBase2(value * 1024 ** 2);
- case 'megabyte':
- case 'megabytes':
- return formatBytesBase10(value, 2);
- case 'gibibyte':
- case 'gibibytes':
- return formatBytesBase2(value * 1024 ** 3);
- case 'gigabyte':
- case 'gigabytes':
- return formatBytesBase10(value, 3);
- case 'tebibyte':
- case 'tebibytes':
- return formatBytesBase2(value * 1024 ** 4);
- case 'terabyte':
- case 'terabytes':
- return formatBytesBase10(value, 4);
- case 'pebibyte':
- case 'pebibytes':
- return formatBytesBase2(value * 1024 ** 5);
- case 'petabyte':
- case 'petabytes':
- return formatBytesBase10(value, 5);
- case 'exbibyte':
- case 'exbibytes':
- return formatBytesBase2(value * 1024 ** 6);
- case 'exabyte':
- case 'exabytes':
- return formatBytesBase10(value, 6);
- case 'none':
- default:
- return formatAbbreviatedNumberWithDynamicPrecision(value);
- }
- }
- const getShortMetricUnit = (unit: string): string => METRIC_UNIT_TO_SHORT[unit] ?? '';
- export function formatMetricUsingFixedUnit(
- value: number | null,
- unit: string,
- op?: string
- ) {
- if (value === null) {
- return '\u2014';
- }
- const formattedNumber = formatNumberWithDynamicDecimalPoints(value);
- return op === 'count'
- ? formattedNumber
- : `${formattedNumber}${getShortMetricUnit(unit)}`.trim();
- }
|