Fix data alignment for db connection queries
This commit is contained in:
@@ -47,9 +47,15 @@ type ZabbixDatasourceSettings struct {
|
|||||||
|
|
||||||
type DBConnectionPostProcessingRequest struct {
|
type DBConnectionPostProcessingRequest struct {
|
||||||
Query QueryModel `json:"query"`
|
Query QueryModel `json:"query"`
|
||||||
|
TimeRange TimeRangePostProcessingRequest `json:"timeRange"`
|
||||||
Series []*timeseries.TimeSeriesData `json:"series"`
|
Series []*timeseries.TimeSeriesData `json:"series"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type TimeRangePostProcessingRequest struct {
|
||||||
|
From int64
|
||||||
|
To int64
|
||||||
|
}
|
||||||
|
|
||||||
type ZabbixAPIResourceRequest struct {
|
type ZabbixAPIResourceRequest struct {
|
||||||
DatasourceId int64 `json:"datasourceId"`
|
DatasourceId int64 `json:"datasourceId"`
|
||||||
Method string `json:"method"`
|
Method string `json:"method"`
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
|
"github.com/alexanderzobnin/grafana-zabbix/pkg/zabbix"
|
||||||
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
"github.com/grafana/grafana-plugin-sdk-go/backend/resource/httpadapter"
|
||||||
@@ -88,6 +89,9 @@ func (ds *ZabbixDatasource) DBConnectionPostProcessingHandler(rw http.ResponseWr
|
|||||||
return
|
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)
|
frames, err := dsInstance.applyDataProcessing(req.Context(), &reqData.Query, reqData.Series)
|
||||||
|
|
||||||
resultJson, err := json.Marshal(frames)
|
resultJson, err := json.Marshal(frames)
|
||||||
|
|||||||
@@ -319,21 +319,25 @@ export class ZabbixDatasource extends DataSourceApi<ZabbixMetricsQuery, ZabbixDS
|
|||||||
/**
|
/**
|
||||||
* Query history for numeric items
|
* Query history for numeric items
|
||||||
*/
|
*/
|
||||||
async queryNumericDataForItems(items, target: ZabbixMetricsQuery, timeRange, useTrends, options) {
|
async queryNumericDataForItems(items, target: ZabbixMetricsQuery, timeRange, useTrends, request) {
|
||||||
let history;
|
let history;
|
||||||
options.valueType = this.getTrendValueType(target);
|
request.valueType = this.getTrendValueType(target);
|
||||||
options.consolidateBy = getConsolidateBy(target) || options.valueType;
|
request.consolidateBy = getConsolidateBy(target) || request.valueType;
|
||||||
|
|
||||||
if (useTrends) {
|
if (useTrends) {
|
||||||
history = await this.zabbix.getTrends(items, timeRange, options);
|
history = await this.zabbix.getTrends(items, timeRange, request);
|
||||||
} else {
|
} 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
|
// Request backend for data processing
|
||||||
const requestOptions: BackendSrvRequest = {
|
const requestOptions: BackendSrvRequest = {
|
||||||
url: `/api/datasources/${this.datasourceId}/resources/db-connection-post`,
|
url: `/api/datasources/${this.datasourceId}/resources/db-connection-post`,
|
||||||
@@ -345,6 +349,7 @@ export class ZabbixDatasource extends DataSourceApi<ZabbixMetricsQuery, ZabbixDS
|
|||||||
data: {
|
data: {
|
||||||
series: timeSeriesData,
|
series: timeSeriesData,
|
||||||
query,
|
query,
|
||||||
|
timeRange,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -179,10 +179,13 @@ export function dataResponseToTimeSeries(response: DataFrameJSON[], items) {
|
|||||||
|
|
||||||
const itemid = field.name;
|
const itemid = field.name;
|
||||||
const item = _.find(items, { 'itemid': itemid });
|
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) {
|
if (interval === 0) {
|
||||||
interval = null;
|
interval = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const timeSeriesData = {
|
const timeSeriesData = {
|
||||||
ts: s,
|
ts: s,
|
||||||
meta: {
|
meta: {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import _ from 'lodash';
|
|||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import * as c from './constants';
|
import * as c from './constants';
|
||||||
import { VariableQuery, VariableQueryTypes } from './types';
|
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
|
* 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_ms: { text: msRange, value: msRange },
|
||||||
__range_s: { text: sRange, value: sRange },
|
__range_s: { text: sRange, value: sRange },
|
||||||
__range: { text: regularRange, value: regularRange },
|
__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 {
|
export function parseItemInterval(interval: string): number {
|
||||||
const normalizedInterval = normalizeZabbixInterval(interval);
|
const normalizedInterval = normalizeZabbixInterval(interval);
|
||||||
@@ -255,6 +255,7 @@ export function normalizeZabbixInterval(interval: string): string {
|
|||||||
return parsedInterval[1] + (parsedInterval.length > 2 ? parsedInterval[2] : 's');
|
return parsedInterval[1] + (parsedInterval.length > 2 ? parsedInterval[2] : 's');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns interval in milliseconds
|
||||||
export function parseInterval(interval: string): number {
|
export function parseInterval(interval: string): number {
|
||||||
const intervalPattern = /(^[\d]+)(y|M|w|d|h|m|s)/g;
|
const intervalPattern = /(^[\d]+)(y|M|w|d|h|m|s)/g;
|
||||||
const momentInterval: any[] = intervalPattern.exec(interval);
|
const momentInterval: any[] = intervalPattern.exec(interval);
|
||||||
@@ -315,7 +316,7 @@ export function convertToZabbixAPIUrl(url) {
|
|||||||
* when waiting for result.
|
* when waiting for result.
|
||||||
*/
|
*/
|
||||||
export function callOnce(func, promiseKeeper) {
|
export function callOnce(func, promiseKeeper) {
|
||||||
return function() {
|
return function () {
|
||||||
if (!promiseKeeper) {
|
if (!promiseKeeper) {
|
||||||
promiseKeeper = Promise.resolve(
|
promiseKeeper = Promise.resolve(
|
||||||
func.apply(this, arguments)
|
func.apply(this, arguments)
|
||||||
@@ -337,7 +338,7 @@ export function callOnce(func, promiseKeeper) {
|
|||||||
* @param {*} funcsArray functions to apply
|
* @param {*} funcsArray functions to apply
|
||||||
*/
|
*/
|
||||||
export function sequence(funcsArray) {
|
export function sequence(funcsArray) {
|
||||||
return function(result) {
|
return function (result) {
|
||||||
for (let i = 0; i < funcsArray.length; i++) {
|
for (let i = 0; i < funcsArray.length; i++) {
|
||||||
result = funcsArray[i].call(this, result);
|
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());
|
let tags: any[] = _.map(tagStr.split(','), (tag) => tag.trim());
|
||||||
tags = _.map(tags, (tag) => {
|
tags = _.map(tags, (tag) => {
|
||||||
const tagParts = tag.split(':');
|
const tagParts = tag.split(':');
|
||||||
return {tag: tagParts[0].trim(), value: tagParts[1].trim()};
|
return { tag: tagParts[0].trim(), value: tagParts[1].trim() };
|
||||||
});
|
});
|
||||||
return tags;
|
return tags;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user