mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
291 lines
6.6 KiB
TypeScript
291 lines
6.6 KiB
TypeScript
import {t} from 'sentry/locale';
|
|
import type {MetricType} from 'sentry/types/metrics';
|
|
import {defined, formatBytesBase2, formatBytesBase10} from 'sentry/utils';
|
|
import {
|
|
DAY,
|
|
formatNumberWithDynamicDecimalPoints,
|
|
HOUR,
|
|
MINUTE,
|
|
MONTH,
|
|
SECOND,
|
|
WEEK,
|
|
} from 'sentry/utils/formatters';
|
|
|
|
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');
|
|
}
|
|
|
|
const MILLISECOND = 1;
|
|
const MICROSECOND = MILLISECOND / 1000;
|
|
const NANOSECOND = MICROSECOND / 1000;
|
|
|
|
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;
|
|
|
|
type FormattingSupportedMetricUnit = (typeof formattingSupportedMetricUnits)[number];
|
|
|
|
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);
|
|
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 value.toLocaleString();
|
|
}
|
|
}
|
|
|
|
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();
|
|
}
|
|
|
|
export function formatMetricsUsingUnitAndOp(
|
|
value: number | null,
|
|
unit: string,
|
|
operation?: string
|
|
) {
|
|
if (operation === 'count') {
|
|
// if the operation is count, we want to ignore the unit and always format the value as a number
|
|
return value?.toLocaleString() ?? '';
|
|
}
|
|
return formatMetricUsingUnit(value, unit);
|
|
}
|