Commit f3c09e8b by Aliaksei Tuzik Committed by GitHub

Prometheus: fix parsing of infinite sample values (#28287) (#28288)

* Prometheus: fix parsing of infinite sample values (#28287)

* Prometheus: Use common function to parse both sample values and histogram "le" label
parent ec40e49d
......@@ -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);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment