From 36626554bec070a3f1dda10383d066236e63c0e1 Mon Sep 17 00:00:00 2001 From: machinly Date: Fri, 7 Jan 2022 22:04:30 +0800 Subject: [PATCH] Prometheus: annotation: fix only first frame was process error & typo. (#43486) --- .../datasource/prometheus/datasource.ts | 121 +++++++++--------- 1 file changed, 62 insertions(+), 59 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 92436f8a266..fd173e8cd30 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -694,13 +694,13 @@ export class PrometheusDatasource }) .pipe( map((rsp: FetchResponse) => { - 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;