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]);
|
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,
|
TransformOptions,
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
|
const POSITIVE_INFINITY_SAMPLE_VALUE = '+Inf';
|
||||||
|
const NEGATIVE_INFINITY_SAMPLE_VALUE = '-Inf';
|
||||||
|
|
||||||
export function transform(
|
export function transform(
|
||||||
response: FetchResponse<PromDataSuccessResponse>,
|
response: FetchResponse<PromDataSuccessResponse>,
|
||||||
transformOptions: {
|
transformOptions: {
|
||||||
@ -116,7 +119,7 @@ function transformToDataFrame(data: MatrixOrVectorResult, options: TransformOpti
|
|||||||
const dps: PromValue[] = [];
|
const dps: PromValue[] = [];
|
||||||
|
|
||||||
for (const value of data.values) {
|
for (const value of data.values) {
|
||||||
let dpValue: number | null = parseFloat(value[1]);
|
let dpValue: number | null = parseSampleValue(value[1]);
|
||||||
|
|
||||||
if (isNaN(dpValue)) {
|
if (isNaN(dpValue)) {
|
||||||
dpValue = null;
|
dpValue = null;
|
||||||
@ -180,12 +183,12 @@ function transformMetricDataToTable(md: MatrixOrVectorResult[], options: Transfo
|
|||||||
d.values.forEach(val => {
|
d.values.forEach(val => {
|
||||||
timeField.values.add(val[0] * 1000);
|
timeField.values.add(val[0] * 1000);
|
||||||
metricFields.forEach(metricField => metricField.values.add(getLabelValue(d.metric, metricField.name)));
|
metricFields.forEach(metricField => metricField.values.add(getLabelValue(d.metric, metricField.name)));
|
||||||
valueField.values.add(parseFloat(val[1]));
|
valueField.values.add(parseSampleValue(val[1]));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
timeField.values.add(d.value[0] * 1000);
|
timeField.values.add(d.value[0] * 1000);
|
||||||
metricFields.forEach(metricField => metricField.values.add(getLabelValue(d.metric, metricField.name)));
|
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 {
|
function getLabelValue(metric: PromMetric, label: string): string | number {
|
||||||
if (metric.hasOwnProperty(label)) {
|
if (metric.hasOwnProperty(label)) {
|
||||||
if (label === 'le') {
|
if (label === 'le') {
|
||||||
return parseHistogramLabel(metric[label]);
|
return parseSampleValue(metric[label]);
|
||||||
}
|
}
|
||||||
return metric[label];
|
return metric[label];
|
||||||
}
|
}
|
||||||
@ -225,7 +228,7 @@ function getValueField(
|
|||||||
name: valueName,
|
name: valueName,
|
||||||
type: FieldType.number,
|
type: FieldType.number,
|
||||||
config: {},
|
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 {
|
try {
|
||||||
// fail if not integer. might happen with bad queries
|
// fail if not integer. might happen with bad queries
|
||||||
le1 = parseHistogramLabel(s1.name ?? '');
|
le1 = parseSampleValue(s1.name ?? '');
|
||||||
le2 = parseHistogramLabel(s2.name ?? '');
|
le2 = parseSampleValue(s2.name ?? '');
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
return 0;
|
return 0;
|
||||||
@ -307,9 +310,13 @@ function sortSeriesByLabel(s1: DataFrame, s2: DataFrame): number {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseHistogramLabel(le: string): number {
|
function parseSampleValue(value: string): number {
|
||||||
if (le === '+Inf') {
|
switch (value) {
|
||||||
return +Infinity;
|
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