Prometheus: annotation: fix only first frame was process error & typo. (#43486)

This commit is contained in:
machinly
2022-01-07 22:04:30 +08:00
committed by GitHub
parent 720d2487fa
commit 36626554be

View File

@@ -694,13 +694,13 @@ export class PrometheusDatasource
})
.pipe(
map((rsp: FetchResponse<BackendDataSourceResponse>) => {
return this.processsAnnotationResponse(options, rsp.data);
return this.processAnnotationResponse(options, rsp.data);
})
)
);
}
processsAnnotationResponse = (options: any, data: BackendDataSourceResponse) => {
processAnnotationResponse = (options: any, data: BackendDataSourceResponse) => {
const frames: DataFrame[] = toDataQueryResponse({ data: data }).data;
if (!frames || !frames.length) {
return [];
@@ -711,71 +711,74 @@ export class PrometheusDatasource
const step = rangeUtil.intervalToSeconds(annotation.step || ANNOTATION_QUERY_STEP_DEFAULT) * 1000;
const tagKeysArray = tagKeys.split(',');
const frame = frames[0];
const timeField = frame.fields[0];
const valueField = frame.fields[1];
const labels = valueField?.labels || {};
const tags = Object.keys(labels)
.filter((label) => tagKeysArray.includes(label))
.map((label) => labels[label]);
const timeValueTuple: Array<[number, number]> = [];
let idx = 0;
valueField.values.toArray().forEach((value: string) => {
let timeStampValue: number;
let valueValue: number;
const time = timeField.values.get(idx);
// If we want to use value as a time, we use value as timeStampValue and valueValue will be 1
if (options.annotation.useValueForTime) {
timeStampValue = Math.floor(parseFloat(value));
valueValue = 1;
} else {
timeStampValue = Math.floor(parseFloat(time));
valueValue = parseFloat(value);
}
idx++;
timeValueTuple.push([timeStampValue, valueValue]);
});
const activeValues = timeValueTuple.filter((value) => value[1] >= 1);
const activeValuesTimestamps = activeValues.map((value) => value[0]);
// Instead of creating singular annotation for each active event we group events into region if they are less
// or equal to `step` apart.
const eventList: AnnotationEvent[] = [];
let latestEvent: AnnotationEvent | null = null;
for (const timestamp of activeValuesTimestamps) {
// We already have event `open` and we have new event that is inside the `step` so we just update the end.
if (latestEvent && (latestEvent.timeEnd ?? 0) + step >= timestamp) {
latestEvent.timeEnd = timestamp;
continue;
for (const frame of frames) {
const timeField = frame.fields[0];
const valueField = frame.fields[1];
const labels = valueField?.labels || {};
const tags = Object.keys(labels)
.filter((label) => tagKeysArray.includes(label))
.map((label) => labels[label]);
const timeValueTuple: Array<[number, number]> = [];
let idx = 0;
valueField.values.toArray().forEach((value: string) => {
let timeStampValue: number;
let valueValue: number;
const time = timeField.values.get(idx);
// If we want to use value as a time, we use value as timeStampValue and valueValue will be 1
if (options.annotation.useValueForTime) {
timeStampValue = Math.floor(parseFloat(value));
valueValue = 1;
} else {
timeStampValue = Math.floor(parseFloat(time));
valueValue = parseFloat(value);
}
idx++;
timeValueTuple.push([timeStampValue, valueValue]);
});
const activeValues = timeValueTuple.filter((value) => value[1] >= 1);
const activeValuesTimestamps = activeValues.map((value) => value[0]);
// Instead of creating singular annotation for each active event we group events into region if they are less
// or equal to `step` apart.
let latestEvent: AnnotationEvent | null = null;
for (const timestamp of activeValuesTimestamps) {
// We already have event `open` and we have new event that is inside the `step` so we just update the end.
if (latestEvent && (latestEvent.timeEnd ?? 0) + step >= timestamp) {
latestEvent.timeEnd = timestamp;
continue;
}
// Event exists but new one is outside of the `step` so we add it to eventList.
if (latestEvent) {
eventList.push(latestEvent);
}
// We start a new region.
latestEvent = {
time: timestamp,
timeEnd: timestamp,
annotation,
title: renderLegendFormat(titleFormat, labels),
tags,
text: renderLegendFormat(textFormat, labels),
};
}
// Event exists but new one is outside of the `step` so we add it to eventList.
if (latestEvent) {
// Finish up last point if we have one
latestEvent.timeEnd = activeValuesTimestamps[activeValuesTimestamps.length - 1];
eventList.push(latestEvent);
}
// We start a new region.
latestEvent = {
time: timestamp,
timeEnd: timestamp,
annotation,
title: renderLegendFormat(titleFormat, labels),
tags,
text: renderLegendFormat(textFormat, labels),
};
}
if (latestEvent) {
// Finish up last point if we have one
latestEvent.timeEnd = activeValuesTimestamps[activeValuesTimestamps.length - 1];
eventList.push(latestEvent);
}
return eventList;