mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
* Prometheus: fix parsing of infinite sample values (#28287) * Prometheus: Use common function to parse both sample values and histogram "le" label
This commit is contained in:
parent
ec40e49dcb
commit
f3c09e8bcc
@ -379,4 +379,47 @@ describe('Prometheus Result Transformer', () => {
|
||||
expect(result[0].fields[1].values.toArray()).toEqual([null, null, 10, null, 10]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When infinity values are returned', () => {
|
||||
describe('When resultType is scalar', () => {
|
||||
const response = {
|
||||
status: 'success',
|
||||
data: {
|
||||
resultType: 'scalar',
|
||||
result: [1443454528, '+Inf'],
|
||||
},
|
||||
};
|
||||
|
||||
it('should correctly parse values', () => {
|
||||
const result: DataFrame[] = transform({ data: response } as any, { ...options, target: { format: 'table' } });
|
||||
expect(result[0].fields[1].values.toArray()).toEqual([Number.POSITIVE_INFINITY]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When resultType is vector', () => {
|
||||
const response = {
|
||||
status: 'success',
|
||||
data: {
|
||||
resultType: 'vector',
|
||||
result: [
|
||||
{
|
||||
metric: { __name__: 'test', job: 'testjob' },
|
||||
value: [1443454528, '+Inf'],
|
||||
},
|
||||
{
|
||||
metric: { __name__: 'test', job: 'testjob' },
|
||||
value: [1443454528, '-Inf'],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
describe('When format is table', () => {
|
||||
it('should correctly parse values', () => {
|
||||
const result: DataFrame[] = transform({ data: response } as any, { ...options, target: { format: 'table' } });
|
||||
expect(result[0].fields[3].values.toArray()).toEqual([Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -22,6 +22,9 @@ import {
|
||||
TransformOptions,
|
||||
} from './types';
|
||||
|
||||
const POSITIVE_INFINITY_SAMPLE_VALUE = '+Inf';
|
||||
const NEGATIVE_INFINITY_SAMPLE_VALUE = '-Inf';
|
||||
|
||||
export function transform(
|
||||
response: FetchResponse<PromDataSuccessResponse>,
|
||||
transformOptions: {
|
||||
@ -116,7 +119,7 @@ function transformToDataFrame(data: MatrixOrVectorResult, options: TransformOpti
|
||||
const dps: PromValue[] = [];
|
||||
|
||||
for (const value of data.values) {
|
||||
let dpValue: number | null = parseFloat(value[1]);
|
||||
let dpValue: number | null = parseSampleValue(value[1]);
|
||||
|
||||
if (isNaN(dpValue)) {
|
||||
dpValue = null;
|
||||
@ -180,12 +183,12 @@ function transformMetricDataToTable(md: MatrixOrVectorResult[], options: Transfo
|
||||
d.values.forEach(val => {
|
||||
timeField.values.add(val[0] * 1000);
|
||||
metricFields.forEach(metricField => metricField.values.add(getLabelValue(d.metric, metricField.name)));
|
||||
valueField.values.add(parseFloat(val[1]));
|
||||
valueField.values.add(parseSampleValue(val[1]));
|
||||
});
|
||||
} else {
|
||||
timeField.values.add(d.value[0] * 1000);
|
||||
metricFields.forEach(metricField => metricField.values.add(getLabelValue(d.metric, metricField.name)));
|
||||
valueField.values.add(parseFloat(d.value[1]));
|
||||
valueField.values.add(parseSampleValue(d.value[1]));
|
||||
}
|
||||
});
|
||||
|
||||
@ -200,7 +203,7 @@ function transformMetricDataToTable(md: MatrixOrVectorResult[], options: Transfo
|
||||
function getLabelValue(metric: PromMetric, label: string): string | number {
|
||||
if (metric.hasOwnProperty(label)) {
|
||||
if (label === 'le') {
|
||||
return parseHistogramLabel(metric[label]);
|
||||
return parseSampleValue(metric[label]);
|
||||
}
|
||||
return metric[label];
|
||||
}
|
||||
@ -225,7 +228,7 @@ function getValueField(
|
||||
name: valueName,
|
||||
type: FieldType.number,
|
||||
config: {},
|
||||
values: new ArrayVector<number | null>(data.map(val => (parseValue ? parseFloat(val[1]) : val[1]))),
|
||||
values: new ArrayVector<number | null>(data.map(val => (parseValue ? parseSampleValue(val[1]) : val[1]))),
|
||||
};
|
||||
}
|
||||
|
||||
@ -289,8 +292,8 @@ function sortSeriesByLabel(s1: DataFrame, s2: DataFrame): number {
|
||||
|
||||
try {
|
||||
// fail if not integer. might happen with bad queries
|
||||
le1 = parseHistogramLabel(s1.name ?? '');
|
||||
le2 = parseHistogramLabel(s2.name ?? '');
|
||||
le1 = parseSampleValue(s1.name ?? '');
|
||||
le2 = parseSampleValue(s2.name ?? '');
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return 0;
|
||||
@ -307,9 +310,13 @@ function sortSeriesByLabel(s1: DataFrame, s2: DataFrame): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
function parseHistogramLabel(le: string): number {
|
||||
if (le === '+Inf') {
|
||||
return +Infinity;
|
||||
function parseSampleValue(value: string): number {
|
||||
switch (value) {
|
||||
case POSITIVE_INFINITY_SAMPLE_VALUE:
|
||||
return Number.POSITIVE_INFINITY;
|
||||
case NEGATIVE_INFINITY_SAMPLE_VALUE:
|
||||
return Number.NEGATIVE_INFINITY;
|
||||
default:
|
||||
return parseFloat(value);
|
||||
}
|
||||
return Number(le);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user