Fix data alignment for db connection queries

This commit is contained in:
Alexander Zobnin
2021-08-06 12:31:05 +03:00
parent d1f639f568
commit 736f05d398
5 changed files with 36 additions and 17 deletions

View File

@@ -47,9 +47,15 @@ type ZabbixDatasourceSettings struct {
type DBConnectionPostProcessingRequest struct {
Query QueryModel `json:"query"`
TimeRange TimeRangePostProcessingRequest `json:"timeRange"`
Series []*timeseries.TimeSeriesData `json:"series"`
}
type TimeRangePostProcessingRequest struct {
From int64
To int64
}
type ZabbixAPIResourceRequest struct {
DatasourceId int64 `json:"datasourceId"`
Method string `json:"method"`

View File

@@ -4,6 +4,7 @@ import (
"encoding/json"
"io/ioutil"
"net/http"
"time"
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
@@ -88,6 +89,9 @@ func (ds *ZabbixDatasource) DBConnectionPostProcessingHandler(rw http.ResponseWr
return
}
reqData.Query.TimeRange.From = time.Unix(reqData.TimeRange.From, 0)
reqData.Query.TimeRange.To = time.Unix(reqData.TimeRange.To, 0)
frames, err := dsInstance.applyDataProcessing(req.Context(), &reqData.Query, reqData.Series)
resultJson, err := json.Marshal(frames)

View File

@@ -319,21 +319,25 @@ export class ZabbixDatasource extends DataSourceApi<ZabbixMetricsQuery, ZabbixDS
/**
* Query history for numeric items
*/
async queryNumericDataForItems(items, target: ZabbixMetricsQuery, timeRange, useTrends, options) {
async queryNumericDataForItems(items, target: ZabbixMetricsQuery, timeRange, useTrends, request) {
let history;
options.valueType = this.getTrendValueType(target);
options.consolidateBy = getConsolidateBy(target) || options.valueType;
request.valueType = this.getTrendValueType(target);
request.consolidateBy = getConsolidateBy(target) || request.valueType;
if (useTrends) {
history = await this.zabbix.getTrends(items, timeRange, options);
history = await this.zabbix.getTrends(items, timeRange, request);
} else {
history = await this.zabbix.getHistoryTS(items, timeRange, options);
history = await this.zabbix.getHistoryTS(items, timeRange, request);
}
return await this.invokeDataProcessingQuery(history, target);
const range = {
from: timeRange[0],
to: timeRange[1],
};
return await this.invokeDataProcessingQuery(history, target, range);
}
async invokeDataProcessingQuery(timeSeriesData, query) {
async invokeDataProcessingQuery(timeSeriesData, query, timeRange) {
// Request backend for data processing
const requestOptions: BackendSrvRequest = {
url: `/api/datasources/${this.datasourceId}/resources/db-connection-post`,
@@ -345,6 +349,7 @@ export class ZabbixDatasource extends DataSourceApi<ZabbixMetricsQuery, ZabbixDS
data: {
series: timeSeriesData,
query,
timeRange,
},
};

View File

@@ -179,10 +179,13 @@ export function dataResponseToTimeSeries(response: DataFrameJSON[], items) {
const itemid = field.name;
const item = _.find(items, { 'itemid': itemid });
let interval = utils.parseItemInterval(item.delay);
// Convert interval to nanoseconds in order to unmarshall it on the backend to time.Duration
let interval = utils.parseItemInterval(item.delay) * 1000000;
if (interval === 0) {
interval = null;
}
const timeSeriesData = {
ts: s,
meta: {

View File

@@ -2,7 +2,7 @@ import _ from 'lodash';
import moment from 'moment';
import * as c from './constants';
import { VariableQuery, VariableQueryTypes } from './types';
import { MappingType, ValueMapping, getValueFormats, DataFrame, FieldType, rangeUtil } from '@grafana/data';
import { DataFrame, FieldType, getValueFormats, MappingType, rangeUtil, ValueMapping } from '@grafana/data';
/*
* This regex matches 3 types of variable reference with an optional format specifier
@@ -218,7 +218,7 @@ export function getRangeScopedVars(range) {
__range_ms: { text: msRange, value: msRange },
__range_s: { text: sRange, value: sRange },
__range: { text: regularRange, value: regularRange },
__range_series: {text: c.RANGE_VARIABLE_VALUE, value: c.RANGE_VARIABLE_VALUE},
__range_series: { text: c.RANGE_VARIABLE_VALUE, value: c.RANGE_VARIABLE_VALUE },
};
}
@@ -236,7 +236,7 @@ export function escapeRegex(value) {
}
/**
* Parses Zabbix item update interval. Returns 0 in case of custom intervals.
* Parses Zabbix item update interval (returns milliseconds). Returns 0 in case of custom intervals.
*/
export function parseItemInterval(interval: string): number {
const normalizedInterval = normalizeZabbixInterval(interval);
@@ -255,6 +255,7 @@ export function normalizeZabbixInterval(interval: string): string {
return parsedInterval[1] + (parsedInterval.length > 2 ? parsedInterval[2] : 's');
}
// Returns interval in milliseconds
export function parseInterval(interval: string): number {
const intervalPattern = /(^[\d]+)(y|M|w|d|h|m|s)/g;
const momentInterval: any[] = intervalPattern.exec(interval);
@@ -315,7 +316,7 @@ export function convertToZabbixAPIUrl(url) {
* when waiting for result.
*/
export function callOnce(func, promiseKeeper) {
return function() {
return function () {
if (!promiseKeeper) {
promiseKeeper = Promise.resolve(
func.apply(this, arguments)
@@ -337,7 +338,7 @@ export function callOnce(func, promiseKeeper) {
* @param {*} funcsArray functions to apply
*/
export function sequence(funcsArray) {
return function(result) {
return function (result) {
for (let i = 0; i < funcsArray.length; i++) {
result = funcsArray[i].call(this, result);
}
@@ -399,7 +400,7 @@ export function parseTags(tagStr: string): any[] {
let tags: any[] = _.map(tagStr.split(','), (tag) => tag.trim());
tags = _.map(tags, (tag) => {
const tagParts = tag.split(':');
return {tag: tagParts[0].trim(), value: tagParts[1].trim()};
return { tag: tagParts[0].trim(), value: tagParts[1].trim() };
});
return tags;
}