From 1ae4b86ca92f3f0d0baabacc6779aaceece57ffe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tommi=20Palom=C3=A4ki?= Date: Fri, 15 May 2020 14:08:12 +0300 Subject: [PATCH] Fix to consolidate avg accuracy (#753) * The interval must fit exactly n times to the time range and query made so that the resulting avg will be exact * Add interval fix also to trend query --- src/datasource-zabbix/zabbix/connectors/sql/mysql.js | 10 ++++------ .../zabbix/connectors/sql/sqlConnector.js | 12 ++++++++++++ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/datasource-zabbix/zabbix/connectors/sql/mysql.js b/src/datasource-zabbix/zabbix/connectors/sql/mysql.js index 31f0efa..a49cbe3 100644 --- a/src/datasource-zabbix/zabbix/connectors/sql/mysql.js +++ b/src/datasource-zabbix/zabbix/connectors/sql/mysql.js @@ -3,26 +3,24 @@ */ function historyQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) { - let time_expression = `clock DIV ${intervalSec} * ${intervalSec}`; let query = ` - SELECT CAST(itemid AS CHAR) AS metric, ${time_expression} AS time_sec, ${aggFunction}(value) AS value + SELECT CAST(itemid AS CHAR) AS metric, MIN(clock) AS time_sec, ${aggFunction}(value) AS value FROM ${table} WHERE itemid IN (${itemids}) AND clock > ${timeFrom} AND clock < ${timeTill} - GROUP BY ${time_expression}, metric + GROUP BY (clock-${timeFrom}) DIV ${intervalSec}, metric ORDER BY time_sec ASC `; return query; } function trendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) { - let time_expression = `clock DIV ${intervalSec} * ${intervalSec}`; let query = ` - SELECT CAST(itemid AS CHAR) AS metric, ${time_expression} AS time_sec, ${aggFunction}(${valueColumn}) AS value + SELECT CAST(itemid AS CHAR) AS metric, MIN(clock) AS time_sec, ${aggFunction}(${valueColumn}) AS value FROM ${table} WHERE itemid IN (${itemids}) AND clock > ${timeFrom} AND clock < ${timeTill} - GROUP BY ${time_expression}, metric + GROUP BY (clock-${timeFrom}) DIV ${intervalSec}, metric ORDER BY time_sec ASC `; return query; diff --git a/src/datasource-zabbix/zabbix/connectors/sql/sqlConnector.js b/src/datasource-zabbix/zabbix/connectors/sql/sqlConnector.js index 9b38bdc..da48708 100644 --- a/src/datasource-zabbix/zabbix/connectors/sql/sqlConnector.js +++ b/src/datasource-zabbix/zabbix/connectors/sql/sqlConnector.js @@ -43,6 +43,12 @@ export class SQLConnector extends DBConnector { let {intervalMs, consolidateBy} = options; let intervalSec = Math.ceil(intervalMs / 1000); + // The interval must match the time range exactly n times, otherwise + // the resulting first and last data points will yield invalid values in the + // calculated average value in downsampleSeries - when using consolidateBy(avg) + let numOfIntervals = Math.ceil((timeTill - timeFrom) / intervalSec); + intervalSec = (timeTill - timeFrom) / numOfIntervals; + consolidateBy = consolidateBy || 'avg'; let aggFunction = dbConnector.consolidateByFunc[consolidateBy]; @@ -66,6 +72,12 @@ export class SQLConnector extends DBConnector { let { intervalMs, consolidateBy } = options; let intervalSec = Math.ceil(intervalMs / 1000); + // The interval must match the time range exactly n times, otherwise + // the resulting first and last data points will yield invalid values in the + // calculated average value in downsampleSeries - when using consolidateBy(avg) + let numOfIntervals = Math.ceil((timeTill - timeFrom) / intervalSec); + intervalSec = (timeTill - timeFrom) / numOfIntervals; + consolidateBy = consolidateBy || 'avg'; let aggFunction = dbConnector.consolidateByFunc[consolidateBy];