From c00a0e1c3f2cde86db50ecbe30d76a22fc4edcf1 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Mon, 20 Sep 2021 17:56:26 +0300 Subject: [PATCH] Fix db connection query post processing --- pkg/datasource/resource_handler.go | 2 +- pkg/datasource/zabbix.go | 6 +++--- src/datasource-zabbix/responseHandler.ts | 4 ++-- .../zabbix/connectors/sql/mysql.ts | 10 ++++++---- src/datasource-zabbix/zabbix/zabbix.ts | 14 +++++++------- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/pkg/datasource/resource_handler.go b/pkg/datasource/resource_handler.go index 92f3b59..acad976 100644 --- a/pkg/datasource/resource_handler.go +++ b/pkg/datasource/resource_handler.go @@ -92,7 +92,7 @@ func (ds *ZabbixDatasource) DBConnectionPostProcessingHandler(rw http.ResponseWr 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, true) resultJson, err := json.Marshal(frames) if err != nil { diff --git a/pkg/datasource/zabbix.go b/pkg/datasource/zabbix.go index c3a0954..da5cb77 100644 --- a/pkg/datasource/zabbix.go +++ b/pkg/datasource/zabbix.go @@ -102,10 +102,10 @@ func (ds *ZabbixDatasourceInstance) queryNumericDataForItems(ctx context.Context } series := convertHistoryToTimeSeries(history, items) - return ds.applyDataProcessing(ctx, query, series) + return ds.applyDataProcessing(ctx, query, series, false) } -func (ds *ZabbixDatasourceInstance) applyDataProcessing(ctx context.Context, query *QueryModel, series []*timeseries.TimeSeriesData) ([]*data.Frame, error) { +func (ds *ZabbixDatasourceInstance) applyDataProcessing(ctx context.Context, query *QueryModel, series []*timeseries.TimeSeriesData, DBPostProcessing bool) ([]*data.Frame, error) { consolidateBy := ds.getConsolidateBy(query) useTrend := ds.isUseTrend(query.TimeRange) @@ -117,7 +117,7 @@ func (ds *ZabbixDatasourceInstance) applyDataProcessing(ctx context.Context, que // Align time series data if possible disableDataAlignment := query.Options.DisableDataAlignment || ds.Settings.DisableDataAlignment || query.QueryType == MODE_ITSERVICE if !disableDataAlignment { - if useTrend { + if useTrend && !DBPostProcessing { for _, s := range series { // Trend data is already aligned (by 1 hour interval), but null values should be added s.TS = s.TS.FillTrendWithNulls() diff --git a/src/datasource-zabbix/responseHandler.ts b/src/datasource-zabbix/responseHandler.ts index f131ec4..3981e5f 100644 --- a/src/datasource-zabbix/responseHandler.ts +++ b/src/datasource-zabbix/responseHandler.ts @@ -154,7 +154,7 @@ export function seriesToDataFrame(timeseries, target: ZabbixMetricsQuery, valueM } // Converts DataResponse to the format which backend works with (for data processing) -export function dataResponseToTimeSeries(response: DataFrameJSON[], items) { +export function dataResponseToTimeSeries(response: DataFrameJSON[], items, request) { const series = []; if (response.length === 0) { return []; @@ -181,7 +181,7 @@ export function dataResponseToTimeSeries(response: DataFrameJSON[], items) { const item = _.find(items, { 'itemid': itemid }); // Convert interval to nanoseconds in order to unmarshall it on the backend to time.Duration - let interval = utils.parseItemInterval(item.delay) * 1000000; + let interval = request.intervalMs * 1000000; if (interval === 0) { interval = null; } diff --git a/src/datasource-zabbix/zabbix/connectors/sql/mysql.ts b/src/datasource-zabbix/zabbix/connectors/sql/mysql.ts index d71f12c..167ea94 100644 --- a/src/datasource-zabbix/zabbix/connectors/sql/mysql.ts +++ b/src/datasource-zabbix/zabbix/connectors/sql/mysql.ts @@ -3,29 +3,31 @@ */ function historyQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) { + const time_expression = `clock DIV ${intervalSec} * ${intervalSec}`; return ` - SELECT CAST(itemid AS CHAR) AS metric, MIN(clock) AS time_sec, ${aggFunction}(value) AS value + SELECT CAST(itemid AS CHAR) AS metric, ${time_expression} AS time_sec, ${aggFunction}(value) AS value FROM ${table} WHERE itemid IN (${itemids}) AND clock > ${timeFrom} AND clock < ${timeTill} - GROUP BY (clock-${timeFrom}) DIV ${intervalSec}, metric + GROUP BY ${time_expression}, metric ORDER BY time_sec ASC `; } function trendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) { + const time_expression = `clock DIV ${intervalSec} * ${intervalSec}`; return ` - SELECT CAST(itemid AS CHAR) AS metric, MIN(clock) AS time_sec, ${aggFunction}(${valueColumn}) AS value + SELECT CAST(itemid AS CHAR) AS metric, ${time_expression} AS time_sec, ${aggFunction}(${valueColumn}) AS value FROM ${table} WHERE itemid IN (${itemids}) AND clock > ${timeFrom} AND clock < ${timeTill} - GROUP BY (clock-${timeFrom}) DIV ${intervalSec}, metric + GROUP BY ${time_expression}, metric ORDER BY time_sec ASC `; } diff --git a/src/datasource-zabbix/zabbix/zabbix.ts b/src/datasource-zabbix/zabbix/zabbix.ts index 3c818ff..beabc19 100644 --- a/src/datasource-zabbix/zabbix/zabbix.ts +++ b/src/datasource-zabbix/zabbix/zabbix.ts @@ -456,24 +456,24 @@ export class Zabbix implements ZabbixConnector { }); } - getHistoryTS(items, timeRange, options) { + getHistoryTS(items, timeRange, request) { const [timeFrom, timeTo] = timeRange; if (this.enableDirectDBConnection) { - return this.getHistoryDB(items, timeFrom, timeTo, options) - .then(history => responseHandler.dataResponseToTimeSeries(history, items)); + return this.getHistoryDB(items, timeFrom, timeTo, request) + .then(history => responseHandler.dataResponseToTimeSeries(history, items, request)); } else { return this.zabbixAPI.getHistory(items, timeFrom, timeTo) .then(history => responseHandler.handleHistory(history, items)); } } - getTrends(items, timeRange, options) { + getTrends(items, timeRange, request) { const [timeFrom, timeTo] = timeRange; if (this.enableDirectDBConnection) { - return this.getTrendsDB(items, timeFrom, timeTo, options) - .then(history => responseHandler.dataResponseToTimeSeries(history, items)); + return this.getTrendsDB(items, timeFrom, timeTo, request) + .then(history => responseHandler.dataResponseToTimeSeries(history, items, request)); } else { - const valueType = options.consolidateBy || options.valueType; + const valueType = request.consolidateBy || request.valueType; return this.zabbixAPI.getTrend(items, timeFrom, timeTo) .then(history => responseHandler.handleTrends(history, items, valueType)) .then(responseHandler.sortTimeseries); // Sort trend data, issue #202