Fix: Display unit in Overview Tab (#90002)

* fix: display metric name suffix instead of unknown

* chore: add documentation comment; remove unecessary text

* fix: create helper function getUnitFromMetric()

* refactor: make getUnitFromMetric() not use getUnit, return null if unable to identify unit

* test: add test for getUnitFromMetric()

* chore: add documentation comments to functions that get unit

* chore: add comment for tests

* chore: fix imports

* fix: display  if unable to determine metric

* Update public/app/features/trails/ActionTabs/MetricOverviewScene.tsx

Co-authored-by: ismail simsek <ismailsimsek09@gmail.com>

* fix: update the translation files for drone

---------

Co-authored-by: ismail simsek <ismailsimsek09@gmail.com>
This commit is contained in:
Kat Yang 2024-07-16 09:16:55 -04:00 committed by GitHub
parent 51afb2e484
commit 881d9c0b83
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 43 additions and 1 deletions

View File

@ -10,6 +10,7 @@ import {
import { Stack, Text, TextLink } from '@grafana/ui';
import { Trans } from 'app/core/internationalization';
import { getUnitFromMetric } from '../AutomaticMetricQueries/units';
import { MetricScene } from '../MetricScene';
import { StatusWrapper } from '../StatusWrapper';
import { reportExploreMetrics } from '../interactions';
@ -67,6 +68,10 @@ export class MetricOverviewScene extends SceneObjectBase<MetricOverviewSceneStat
const variable = model.getVariable();
const { loading: labelsLoading, options: labelOptions } = variable.useState();
// Get unit name from the metric name
const metricScene = getMetricSceneFor(model);
const metric = metricScene.state.metric;
let unit = getUnitFromMetric(metric) ?? 'Unknown';
return (
<StatusWrapper isLoading={labelsLoading || metadataLoading}>
<Stack gap={6}>
@ -105,7 +110,7 @@ export class MetricOverviewScene extends SceneObjectBase<MetricOverviewSceneStat
<div>{metadata?.unit}</div>
) : (
<i>
<Trans>Unknown</Trans>
<Trans>{unit}</Trans>
</i>
)}
</Stack>

View File

@ -0,0 +1,18 @@
import { getUnitFromMetric } from './units';
// Tests for units
describe('getUnitFromMetric', () => {
it('should return the last part of the metric if it is a valid unit', () => {
expect(getUnitFromMetric('go_gc_gomemlimit_bytes')).toBe('bytes');
expect(getUnitFromMetric('go_gc_duration_seconds')).toBe('seconds');
});
it('should return the second to last part of the metric if it is a valid unit', () => {
expect(getUnitFromMetric('go_gc_heap_allocs_by_size_bytes_count')).toBe('bytes');
expect(getUnitFromMetric('go_cpu_classes_gc_mark_assist_cpu_seconds_total')).toBe('seconds');
});
it('should return null if no valid unit is found', () => {
expect(getUnitFromMetric('ALERTS')).toBe(null);
});
});

View File

@ -1,5 +1,20 @@
const DEFAULT_UNIT = 'short';
// Get unit from metric name (e.g. "go_gc_duration_seconds" -> "seconds")
export function getUnitFromMetric(metric: string) {
const metricParts = metric.split('_');
const suffix = metricParts.at(-1) ?? '';
const secondToLastSuffix = metricParts.at(-2) ?? '';
if (UNIT_LIST.includes(suffix)) {
return suffix;
} else if (UNIT_LIST.includes(secondToLastSuffix)) {
return secondToLastSuffix;
} else {
return null;
}
}
// Get Grafana unit for a panel (e.g. "go_gc_duration_seconds" -> "s")
export function getUnit(metricPart: string | undefined) {
return (metricPart && UNIT_MAP[metricPart]) || DEFAULT_UNIT;
}
@ -9,6 +24,8 @@ const UNIT_MAP: Record<string, string> = {
seconds: 's',
};
const UNIT_LIST = ['bytes', 'seconds'];
const RATE_UNIT_MAP: Record<string, string> = {
bytes: 'Bps', // bytes per second
seconds: 'short', // seconds per second is unitless -- this may indicate a count of some resource that is active

View File

@ -1,5 +1,6 @@
{
"_comment": "The code is the source of truth for English phrases. They should be updated in the components directly, and additional plurals specified in this file.",
"{unit}": "{unit}",
"access-control": {
"add-permission": {
"role-label": "Role",

View File

@ -1,5 +1,6 @@
{
"_comment": "Ŧĥę čőđę įş ŧĥę şőūřčę őƒ ŧřūŧĥ ƒőř Ēʼnģľįşĥ pĥřäşęş. Ŧĥęy şĥőūľđ þę ūpđäŧęđ įʼn ŧĥę čőmpőʼnęʼnŧş đįřęčŧľy, äʼnđ äđđįŧįőʼnäľ pľūřäľş şpęčįƒįęđ įʼn ŧĥįş ƒįľę.",
"{unit}": "{ūʼnįŧ}",
"access-control": {
"add-permission": {
"role-label": "Ŗőľę",