db-connector: initial postgres support
This commit is contained in:
2
dist/datasource-zabbix/config.controller.js
vendored
2
dist/datasource-zabbix/config.controller.js
vendored
@@ -34,7 +34,7 @@ System.register(['lodash'], function (_export, _context) {
|
|||||||
};
|
};
|
||||||
}();
|
}();
|
||||||
|
|
||||||
SUPPORTED_SQL_DS = ['mysql'];
|
SUPPORTED_SQL_DS = ['mysql', 'postgres'];
|
||||||
defaultConfig = {
|
defaultConfig = {
|
||||||
dbConnection: {
|
dbConnection: {
|
||||||
enable: false
|
enable: false
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
{"version":3,"sources":["../../src/datasource-zabbix/config.controller.js"],"names":["_","SUPPORTED_SQL_DS","defaultConfig","dbConnection","enable","ZabbixDSConfigController","$scope","$injector","datasourceSrv","defaults","current","jsonData","sqlDataSources","getSupportedSQLDataSources","datasources","getAll","filter","includes","ds","type","templateUrl"],"mappings":";;;;;;;;;;;;;;;AAAOA,O;;;;;;;;;;;;;;;;;;;;;AAEDC,sB,GAAmB,CAAC,OAAD,C;AAEnBC,mB,GAAgB;AACpBC,sBAAc;AACZC,kBAAQ;AADI;AADM,O;;0CAMTC,wB;AACX;AACA,0CAAYC,MAAZ,EAAoBC,SAApB,EAA+BC,aAA/B,EAA8C;AAAA;;AAC5C,eAAKA,aAAL,GAAqBA,aAArB;;AAEAR,YAAES,QAAF,CAAW,KAAKC,OAAL,CAAaC,QAAxB,EAAkCT,aAAlC;AACA,eAAKU,cAAL,GAAsB,KAAKC,0BAAL,EAAtB;AACD;;;;uDAE4B;AAC3B,gBAAIC,cAAc,KAAKN,aAAL,CAAmBO,MAAnB,EAAlB;AACA,mBAAOf,EAAEgB,MAAF,CAASF,WAAT,EAAsB,cAAM;AACjC,qBAAOd,EAAEiB,QAAF,CAAWhB,gBAAX,EAA6BiB,GAAGC,IAAhC,CAAP;AACD,aAFM,CAAP;AAGD;;;;;;;;AAGHd,+BAAyBe,WAAzB,GAAuC,wCAAvC","file":"config.controller.js","sourcesContent":["import _ from 'lodash';\n\nconst SUPPORTED_SQL_DS = ['mysql'];\n\nconst defaultConfig = {\n dbConnection: {\n enable: false,\n }\n};\n\nexport class ZabbixDSConfigController {\n /** @ngInject */\n constructor($scope, $injector, datasourceSrv) {\n this.datasourceSrv = datasourceSrv;\n\n _.defaults(this.current.jsonData, defaultConfig);\n this.sqlDataSources = this.getSupportedSQLDataSources();\n }\n\n getSupportedSQLDataSources() {\n let datasources = this.datasourceSrv.getAll();\n return _.filter(datasources, ds => {\n return _.includes(SUPPORTED_SQL_DS, ds.type);\n });\n }\n}\n\nZabbixDSConfigController.templateUrl = 'datasource-zabbix/partials/config.html';\n"]}
|
{"version":3,"sources":["../../src/datasource-zabbix/config.controller.js"],"names":["_","SUPPORTED_SQL_DS","defaultConfig","dbConnection","enable","ZabbixDSConfigController","$scope","$injector","datasourceSrv","defaults","current","jsonData","sqlDataSources","getSupportedSQLDataSources","datasources","getAll","filter","includes","ds","type","templateUrl"],"mappings":";;;;;;;;;;;;;;;AAAOA,O;;;;;;;;;;;;;;;;;;;;;AAEDC,sB,GAAmB,CAAC,OAAD,EAAU,UAAV,C;AAEnBC,mB,GAAgB;AACpBC,sBAAc;AACZC,kBAAQ;AADI;AADM,O;;0CAMTC,wB;AACX;AACA,0CAAYC,MAAZ,EAAoBC,SAApB,EAA+BC,aAA/B,EAA8C;AAAA;;AAC5C,eAAKA,aAAL,GAAqBA,aAArB;;AAEAR,YAAES,QAAF,CAAW,KAAKC,OAAL,CAAaC,QAAxB,EAAkCT,aAAlC;AACA,eAAKU,cAAL,GAAsB,KAAKC,0BAAL,EAAtB;AACD;;;;uDAE4B;AAC3B,gBAAIC,cAAc,KAAKN,aAAL,CAAmBO,MAAnB,EAAlB;AACA,mBAAOf,EAAEgB,MAAF,CAASF,WAAT,EAAsB,cAAM;AACjC,qBAAOd,EAAEiB,QAAF,CAAWhB,gBAAX,EAA6BiB,GAAGC,IAAhC,CAAP;AACD,aAFM,CAAP;AAGD;;;;;;;;AAGHd,+BAAyBe,WAAzB,GAAuC,wCAAvC","file":"config.controller.js","sourcesContent":["import _ from 'lodash';\n\nconst SUPPORTED_SQL_DS = ['mysql', 'postgres'];\n\nconst defaultConfig = {\n dbConnection: {\n enable: false,\n }\n};\n\nexport class ZabbixDSConfigController {\n /** @ngInject */\n constructor($scope, $injector, datasourceSrv) {\n this.datasourceSrv = datasourceSrv;\n\n _.defaults(this.current.jsonData, defaultConfig);\n this.sqlDataSources = this.getSupportedSQLDataSources();\n }\n\n getSupportedSQLDataSources() {\n let datasources = this.datasourceSrv.getAll();\n return _.filter(datasources, ds => {\n return _.includes(SUPPORTED_SQL_DS, ds.type);\n });\n }\n}\n\nZabbixDSConfigController.templateUrl = 'datasource-zabbix/partials/config.html';\n"]}
|
||||||
86
dist/datasource-zabbix/zabbixDBConnector.js
vendored
86
dist/datasource-zabbix/zabbixDBConnector.js
vendored
@@ -3,7 +3,7 @@
|
|||||||
System.register(['angular', 'lodash'], function (_export, _context) {
|
System.register(['angular', 'lodash'], function (_export, _context) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
var angular, _, _createClass, DEFAULT_QUERY_LIMIT, HISTORY_TO_TABLE_MAP, TREND_TO_TABLE_MAP, consolidateByFunc, consolidateByTrendColumns;
|
var angular, _, _createClass, DEFAULT_QUERY_LIMIT, HISTORY_TO_TABLE_MAP, TREND_TO_TABLE_MAP, consolidateByFunc, consolidateByTrendColumns, TEST_MYSQL_QUERY, TEST_POSTGRES_QUERY;
|
||||||
|
|
||||||
function _classCallCheck(instance, Constructor) {
|
function _classCallCheck(instance, Constructor) {
|
||||||
if (!(instance instanceof Constructor)) {
|
if (!(instance instanceof Constructor)) {
|
||||||
@@ -24,6 +24,8 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
|||||||
|
|
||||||
this.sqlDataSourceId = sqlDataSourceId;
|
this.sqlDataSourceId = sqlDataSourceId;
|
||||||
this.limit = limit || DEFAULT_QUERY_LIMIT;
|
this.limit = limit || DEFAULT_QUERY_LIMIT;
|
||||||
|
|
||||||
|
this.loadSQLDataSource(sqlDataSourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,10 +37,13 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
|||||||
_createClass(ZabbixDBConnector, [{
|
_createClass(ZabbixDBConnector, [{
|
||||||
key: 'loadSQLDataSource',
|
key: 'loadSQLDataSource',
|
||||||
value: function loadSQLDataSource(datasourceId) {
|
value: function loadSQLDataSource(datasourceId) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
var ds = _.find(datasourceSrv.getAll(), { 'id': datasourceId });
|
var ds = _.find(datasourceSrv.getAll(), { 'id': datasourceId });
|
||||||
if (ds) {
|
if (ds) {
|
||||||
return datasourceSrv.loadDatasource(ds.name).then(function (ds) {
|
return datasourceSrv.loadDatasource(ds.name).then(function (ds) {
|
||||||
console.log('SQL data source loaded', ds);
|
_this.sqlDataSourceType = ds.meta.id;
|
||||||
|
return ds;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject('SQL Data Source with ID ' + datasourceId + ' not found');
|
return Promise.reject('SQL Data Source with ID ' + datasourceId + ' not found');
|
||||||
@@ -47,13 +52,16 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
|||||||
}, {
|
}, {
|
||||||
key: 'testSQLDataSource',
|
key: 'testSQLDataSource',
|
||||||
value: function testSQLDataSource() {
|
value: function testSQLDataSource() {
|
||||||
var testQuery = 'SELECT itemid AS metric, clock AS time_sec, value_avg AS value FROM trends_uint LIMIT 1';
|
var testQuery = TEST_MYSQL_QUERY;
|
||||||
|
if (this.sqlDataSourceType === 'postgres') {
|
||||||
|
testQuery = TEST_POSTGRES_QUERY;
|
||||||
|
}
|
||||||
return this.invokeSQLQuery(testQuery);
|
return this.invokeSQLQuery(testQuery);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'getHistory',
|
key: 'getHistory',
|
||||||
value: function getHistory(items, timeFrom, timeTill, options) {
|
value: function getHistory(items, timeFrom, timeTill, options) {
|
||||||
var _this = this;
|
var _this2 = this;
|
||||||
|
|
||||||
var intervalMs = options.intervalMs,
|
var intervalMs = options.intervalMs,
|
||||||
consolidateBy = options.consolidateBy;
|
consolidateBy = options.consolidateBy;
|
||||||
@@ -69,11 +77,11 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
|||||||
var itemids = _.map(items, 'itemid').join(', ');
|
var itemids = _.map(items, 'itemid').join(', ');
|
||||||
var table = HISTORY_TO_TABLE_MAP[value_type];
|
var table = HISTORY_TO_TABLE_MAP[value_type];
|
||||||
|
|
||||||
var time_expression = 'clock DIV ' + intervalSec + ' * ' + intervalSec;
|
var dialect = _this2.sqlDataSourceType;
|
||||||
var query = '\n SELECT itemid AS metric, ' + time_expression + ' AS time_sec, ' + aggFunction + '(value) AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY ' + time_expression + ', metric\n ';
|
var query = buildSQLHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, dialect);
|
||||||
|
|
||||||
query = compactSQLQuery(query);
|
query = compactSQLQuery(query);
|
||||||
return _this.invokeSQLQuery(query);
|
return _this2.invokeSQLQuery(query);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all(promises).then(function (results) {
|
return Promise.all(promises).then(function (results) {
|
||||||
@@ -83,7 +91,7 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
|||||||
}, {
|
}, {
|
||||||
key: 'getTrends',
|
key: 'getTrends',
|
||||||
value: function getTrends(items, timeFrom, timeTill, options) {
|
value: function getTrends(items, timeFrom, timeTill, options) {
|
||||||
var _this2 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
var intervalMs = options.intervalMs,
|
var intervalMs = options.intervalMs,
|
||||||
consolidateBy = options.consolidateBy;
|
consolidateBy = options.consolidateBy;
|
||||||
@@ -101,11 +109,11 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
|||||||
var valueColumn = _.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg';
|
var valueColumn = _.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg';
|
||||||
valueColumn = consolidateByTrendColumns[valueColumn];
|
valueColumn = consolidateByTrendColumns[valueColumn];
|
||||||
|
|
||||||
var time_expression = 'clock DIV ' + intervalSec + ' * ' + intervalSec;
|
var dialect = _this3.sqlDataSourceType;
|
||||||
var query = '\n SELECT itemid AS metric, ' + time_expression + ' AS time_sec, ' + aggFunction + '(' + valueColumn + ') AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY ' + time_expression + ', metric\n ';
|
var query = buildSQLTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn, dialect);
|
||||||
|
|
||||||
query = compactSQLQuery(query);
|
query = compactSQLQuery(query);
|
||||||
return _this2.invokeSQLQuery(query);
|
return _this3.invokeSQLQuery(query);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all(promises).then(function (results) {
|
return Promise.all(promises).then(function (results) {
|
||||||
@@ -181,6 +189,59 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
|||||||
function compactSQLQuery(query) {
|
function compactSQLQuery(query) {
|
||||||
return query.replace(/\s+/g, ' ');
|
return query.replace(/\s+/g, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildSQLHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) {
|
||||||
|
var dialect = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 'mysql';
|
||||||
|
|
||||||
|
if (dialect === 'postgres') {
|
||||||
|
return buildPostgresHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction);
|
||||||
|
} else {
|
||||||
|
return buildMysqlHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildSQLTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) {
|
||||||
|
var dialect = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 'mysql';
|
||||||
|
|
||||||
|
if (dialect === 'postgres') {
|
||||||
|
return buildPostgresTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn);
|
||||||
|
} else {
|
||||||
|
return buildMysqlTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// MySQL //
|
||||||
|
///////////
|
||||||
|
|
||||||
|
function buildMysqlHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) {
|
||||||
|
var time_expression = 'clock DIV ' + intervalSec + ' * ' + intervalSec;
|
||||||
|
var query = '\n SELECT itemid AS metric, ' + time_expression + ' AS time_sec, ' + aggFunction + '(value) AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY ' + time_expression + ', metric\n ORDER BY time_sec ASC\n ';
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildMysqlTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) {
|
||||||
|
var time_expression = 'clock DIV ' + intervalSec + ' * ' + intervalSec;
|
||||||
|
var query = '\n SELECT itemid AS metric, ' + time_expression + ' AS time_sec, ' + aggFunction + '(' + valueColumn + ') AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY ' + time_expression + ', metric\n ORDER BY time_sec ASC\n ';
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
// PostgreSQL //
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
function buildPostgresHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) {
|
||||||
|
var time_expression = 'clock / ' + intervalSec + ' * ' + intervalSec;
|
||||||
|
var query = '\n SELECT DISTINCT to_char(itemid, \'FM9999999999999\') AS metric,\n ' + time_expression + ' AS time,\n ' + aggFunction + '(value) OVER (PARTITION BY clock / ' + intervalSec + ') AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY metric, clock, value\n ORDER BY time ASC\n ';
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildPostgresTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) {
|
||||||
|
var time_expression = 'clock / ' + intervalSec + ' * ' + intervalSec;
|
||||||
|
var query = '\n SELECT DISTINCT to_char(itemid, \'FM9999999999999\') AS metric,\n ' + time_expression + ' AS time,\n ' + aggFunction + '(' + valueColumn + ') OVER (PARTITION BY clock / ' + intervalSec + ') AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY metric, clock, ' + valueColumn + '\n ORDER BY time ASC\n ';
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
setters: [function (_angular) {
|
setters: [function (_angular) {
|
||||||
angular = _angular.default;
|
angular = _angular.default;
|
||||||
@@ -230,7 +291,8 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
|||||||
'min': 'value_min',
|
'min': 'value_min',
|
||||||
'max': 'value_max'
|
'max': 'value_max'
|
||||||
};
|
};
|
||||||
angular.module('grafana.services').factory('ZabbixDBConnector', ZabbixDBConnectorFactory);
|
angular.module('grafana.services').factory('ZabbixDBConnector', ZabbixDBConnectorFactory);TEST_MYSQL_QUERY = 'SELECT itemid AS metric, clock AS time_sec, value_avg AS value FROM trends_uint LIMIT 1';
|
||||||
|
TEST_POSTGRES_QUERY = '\n SELECT to_char(itemid, \'FM9999999999999\') AS metric, clock AS time, value_avg AS value\n FROM trends_uint LIMIT 1\n';
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -15,7 +15,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|||||||
|
|
||||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||||
|
|
||||||
var SUPPORTED_SQL_DS = ['mysql'];
|
var SUPPORTED_SQL_DS = ['mysql', 'postgres'];
|
||||||
|
|
||||||
var defaultConfig = {
|
var defaultConfig = {
|
||||||
dbConnection: {
|
dbConnection: {
|
||||||
|
|||||||
84
dist/test/datasource-zabbix/zabbixDBConnector.js
vendored
84
dist/test/datasource-zabbix/zabbixDBConnector.js
vendored
@@ -55,6 +55,8 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
|
|
||||||
this.sqlDataSourceId = sqlDataSourceId;
|
this.sqlDataSourceId = sqlDataSourceId;
|
||||||
this.limit = limit || DEFAULT_QUERY_LIMIT;
|
this.limit = limit || DEFAULT_QUERY_LIMIT;
|
||||||
|
|
||||||
|
this.loadSQLDataSource(sqlDataSourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -66,10 +68,13 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
_createClass(ZabbixDBConnector, [{
|
_createClass(ZabbixDBConnector, [{
|
||||||
key: 'loadSQLDataSource',
|
key: 'loadSQLDataSource',
|
||||||
value: function loadSQLDataSource(datasourceId) {
|
value: function loadSQLDataSource(datasourceId) {
|
||||||
|
var _this = this;
|
||||||
|
|
||||||
var ds = _lodash2.default.find(datasourceSrv.getAll(), { 'id': datasourceId });
|
var ds = _lodash2.default.find(datasourceSrv.getAll(), { 'id': datasourceId });
|
||||||
if (ds) {
|
if (ds) {
|
||||||
return datasourceSrv.loadDatasource(ds.name).then(function (ds) {
|
return datasourceSrv.loadDatasource(ds.name).then(function (ds) {
|
||||||
console.log('SQL data source loaded', ds);
|
_this.sqlDataSourceType = ds.meta.id;
|
||||||
|
return ds;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject('SQL Data Source with ID ' + datasourceId + ' not found');
|
return Promise.reject('SQL Data Source with ID ' + datasourceId + ' not found');
|
||||||
@@ -83,13 +88,16 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
}, {
|
}, {
|
||||||
key: 'testSQLDataSource',
|
key: 'testSQLDataSource',
|
||||||
value: function testSQLDataSource() {
|
value: function testSQLDataSource() {
|
||||||
var testQuery = 'SELECT itemid AS metric, clock AS time_sec, value_avg AS value FROM trends_uint LIMIT 1';
|
var testQuery = TEST_MYSQL_QUERY;
|
||||||
|
if (this.sqlDataSourceType === 'postgres') {
|
||||||
|
testQuery = TEST_POSTGRES_QUERY;
|
||||||
|
}
|
||||||
return this.invokeSQLQuery(testQuery);
|
return this.invokeSQLQuery(testQuery);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'getHistory',
|
key: 'getHistory',
|
||||||
value: function getHistory(items, timeFrom, timeTill, options) {
|
value: function getHistory(items, timeFrom, timeTill, options) {
|
||||||
var _this = this;
|
var _this2 = this;
|
||||||
|
|
||||||
var intervalMs = options.intervalMs,
|
var intervalMs = options.intervalMs,
|
||||||
consolidateBy = options.consolidateBy;
|
consolidateBy = options.consolidateBy;
|
||||||
@@ -105,11 +113,11 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
var itemids = _lodash2.default.map(items, 'itemid').join(', ');
|
var itemids = _lodash2.default.map(items, 'itemid').join(', ');
|
||||||
var table = HISTORY_TO_TABLE_MAP[value_type];
|
var table = HISTORY_TO_TABLE_MAP[value_type];
|
||||||
|
|
||||||
var time_expression = 'clock DIV ' + intervalSec + ' * ' + intervalSec;
|
var dialect = _this2.sqlDataSourceType;
|
||||||
var query = '\n SELECT itemid AS metric, ' + time_expression + ' AS time_sec, ' + aggFunction + '(value) AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY ' + time_expression + ', metric\n ';
|
var query = buildSQLHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, dialect);
|
||||||
|
|
||||||
query = compactSQLQuery(query);
|
query = compactSQLQuery(query);
|
||||||
return _this.invokeSQLQuery(query);
|
return _this2.invokeSQLQuery(query);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all(promises).then(function (results) {
|
return Promise.all(promises).then(function (results) {
|
||||||
@@ -119,7 +127,7 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
}, {
|
}, {
|
||||||
key: 'getTrends',
|
key: 'getTrends',
|
||||||
value: function getTrends(items, timeFrom, timeTill, options) {
|
value: function getTrends(items, timeFrom, timeTill, options) {
|
||||||
var _this2 = this;
|
var _this3 = this;
|
||||||
|
|
||||||
var intervalMs = options.intervalMs,
|
var intervalMs = options.intervalMs,
|
||||||
consolidateBy = options.consolidateBy;
|
consolidateBy = options.consolidateBy;
|
||||||
@@ -137,11 +145,11 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
var valueColumn = _lodash2.default.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg';
|
var valueColumn = _lodash2.default.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg';
|
||||||
valueColumn = consolidateByTrendColumns[valueColumn];
|
valueColumn = consolidateByTrendColumns[valueColumn];
|
||||||
|
|
||||||
var time_expression = 'clock DIV ' + intervalSec + ' * ' + intervalSec;
|
var dialect = _this3.sqlDataSourceType;
|
||||||
var query = '\n SELECT itemid AS metric, ' + time_expression + ' AS time_sec, ' + aggFunction + '(' + valueColumn + ') AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY ' + time_expression + ', metric\n ';
|
var query = buildSQLTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn, dialect);
|
||||||
|
|
||||||
query = compactSQLQuery(query);
|
query = compactSQLQuery(query);
|
||||||
return _this2.invokeSQLQuery(query);
|
return _this3.invokeSQLQuery(query);
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all(promises).then(function (results) {
|
return Promise.all(promises).then(function (results) {
|
||||||
@@ -219,3 +227,59 @@ function convertGrafanaTSResponse(time_series, items, addHostName) {
|
|||||||
function compactSQLQuery(query) {
|
function compactSQLQuery(query) {
|
||||||
return query.replace(/\s+/g, ' ');
|
return query.replace(/\s+/g, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildSQLHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) {
|
||||||
|
var dialect = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 'mysql';
|
||||||
|
|
||||||
|
if (dialect === 'postgres') {
|
||||||
|
return buildPostgresHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction);
|
||||||
|
} else {
|
||||||
|
return buildMysqlHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildSQLTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) {
|
||||||
|
var dialect = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 'mysql';
|
||||||
|
|
||||||
|
if (dialect === 'postgres') {
|
||||||
|
return buildPostgresTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn);
|
||||||
|
} else {
|
||||||
|
return buildMysqlTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// MySQL //
|
||||||
|
///////////
|
||||||
|
|
||||||
|
function buildMysqlHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) {
|
||||||
|
var time_expression = 'clock DIV ' + intervalSec + ' * ' + intervalSec;
|
||||||
|
var query = '\n SELECT itemid AS metric, ' + time_expression + ' AS time_sec, ' + aggFunction + '(value) AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY ' + time_expression + ', metric\n ORDER BY time_sec ASC\n ';
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildMysqlTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) {
|
||||||
|
var time_expression = 'clock DIV ' + intervalSec + ' * ' + intervalSec;
|
||||||
|
var query = '\n SELECT itemid AS metric, ' + time_expression + ' AS time_sec, ' + aggFunction + '(' + valueColumn + ') AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY ' + time_expression + ', metric\n ORDER BY time_sec ASC\n ';
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
var TEST_MYSQL_QUERY = 'SELECT itemid AS metric, clock AS time_sec, value_avg AS value FROM trends_uint LIMIT 1';
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
// PostgreSQL //
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
function buildPostgresHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) {
|
||||||
|
var time_expression = 'clock / ' + intervalSec + ' * ' + intervalSec;
|
||||||
|
var query = '\n SELECT DISTINCT to_char(itemid, \'FM9999999999999\') AS metric,\n ' + time_expression + ' AS time,\n ' + aggFunction + '(value) OVER (PARTITION BY clock / ' + intervalSec + ') AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY metric, clock, value\n ORDER BY time ASC\n ';
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildPostgresTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) {
|
||||||
|
var time_expression = 'clock / ' + intervalSec + ' * ' + intervalSec;
|
||||||
|
var query = '\n SELECT DISTINCT to_char(itemid, \'FM9999999999999\') AS metric,\n ' + time_expression + ' AS time,\n ' + aggFunction + '(' + valueColumn + ') OVER (PARTITION BY clock / ' + intervalSec + ') AS value\n FROM ' + table + '\n WHERE itemid IN (' + itemids + ')\n AND clock > ' + timeFrom + ' AND clock < ' + timeTill + '\n GROUP BY metric, clock, ' + valueColumn + '\n ORDER BY time ASC\n ';
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
var TEST_POSTGRES_QUERY = '\n SELECT to_char(itemid, \'FM9999999999999\') AS metric, clock AS time, value_avg AS value\n FROM trends_uint LIMIT 1\n';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
const SUPPORTED_SQL_DS = ['mysql'];
|
const SUPPORTED_SQL_DS = ['mysql', 'postgres'];
|
||||||
|
|
||||||
const defaultConfig = {
|
const defaultConfig = {
|
||||||
dbConnection: {
|
dbConnection: {
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
|
|
||||||
this.sqlDataSourceId = sqlDataSourceId;
|
this.sqlDataSourceId = sqlDataSourceId;
|
||||||
this.limit = limit || DEFAULT_QUERY_LIMIT;
|
this.limit = limit || DEFAULT_QUERY_LIMIT;
|
||||||
|
|
||||||
|
this.loadSQLDataSource(sqlDataSourceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,7 +52,8 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
if (ds) {
|
if (ds) {
|
||||||
return datasourceSrv.loadDatasource(ds.name)
|
return datasourceSrv.loadDatasource(ds.name)
|
||||||
.then(ds => {
|
.then(ds => {
|
||||||
console.log('SQL data source loaded', ds);
|
this.sqlDataSourceType = ds.meta.id;
|
||||||
|
return ds;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject(`SQL Data Source with ID ${datasourceId} not found`);
|
return Promise.reject(`SQL Data Source with ID ${datasourceId} not found`);
|
||||||
@@ -61,7 +64,10 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
* Try to invoke test query for one of Zabbix database tables.
|
* Try to invoke test query for one of Zabbix database tables.
|
||||||
*/
|
*/
|
||||||
testSQLDataSource() {
|
testSQLDataSource() {
|
||||||
let testQuery = `SELECT itemid AS metric, clock AS time_sec, value_avg AS value FROM trends_uint LIMIT 1`;
|
let testQuery = TEST_MYSQL_QUERY;
|
||||||
|
if (this.sqlDataSourceType === 'postgres') {
|
||||||
|
testQuery = TEST_POSTGRES_QUERY;
|
||||||
|
}
|
||||||
return this.invokeSQLQuery(testQuery);
|
return this.invokeSQLQuery(testQuery);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,14 +84,8 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
let itemids = _.map(items, 'itemid').join(', ');
|
let itemids = _.map(items, 'itemid').join(', ');
|
||||||
let table = HISTORY_TO_TABLE_MAP[value_type];
|
let table = HISTORY_TO_TABLE_MAP[value_type];
|
||||||
|
|
||||||
let time_expression = `clock DIV ${intervalSec} * ${intervalSec}`;
|
let dialect = this.sqlDataSourceType;
|
||||||
let query = `
|
let query = buildSQLHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, dialect);
|
||||||
SELECT itemid 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 ${time_expression}, metric
|
|
||||||
`;
|
|
||||||
|
|
||||||
query = compactSQLQuery(query);
|
query = compactSQLQuery(query);
|
||||||
return this.invokeSQLQuery(query);
|
return this.invokeSQLQuery(query);
|
||||||
@@ -111,14 +111,8 @@ function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
|||||||
let valueColumn = _.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg';
|
let valueColumn = _.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg';
|
||||||
valueColumn = consolidateByTrendColumns[valueColumn];
|
valueColumn = consolidateByTrendColumns[valueColumn];
|
||||||
|
|
||||||
let time_expression = `clock DIV ${intervalSec} * ${intervalSec}`;
|
let dialect = this.sqlDataSourceType;
|
||||||
let query = `
|
let query = buildSQLTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn, dialect);
|
||||||
SELECT itemid 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 ${time_expression}, metric
|
|
||||||
`;
|
|
||||||
|
|
||||||
query = compactSQLQuery(query);
|
query = compactSQLQuery(query);
|
||||||
return this.invokeSQLQuery(query);
|
return this.invokeSQLQuery(query);
|
||||||
@@ -194,3 +188,90 @@ function convertGrafanaTSResponse(time_series, items, addHostName) {
|
|||||||
function compactSQLQuery(query) {
|
function compactSQLQuery(query) {
|
||||||
return query.replace(/\s+/g, ' ');
|
return query.replace(/\s+/g, ' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildSQLHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, dialect = 'mysql') {
|
||||||
|
if (dialect === 'postgres') {
|
||||||
|
return buildPostgresHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction);
|
||||||
|
} else {
|
||||||
|
return buildMysqlHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildSQLTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn, dialect = 'mysql') {
|
||||||
|
if (dialect === 'postgres') {
|
||||||
|
return buildPostgresTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn);
|
||||||
|
} else {
|
||||||
|
return buildMysqlTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// MySQL //
|
||||||
|
///////////
|
||||||
|
|
||||||
|
function buildMysqlHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) {
|
||||||
|
let time_expression = `clock DIV ${intervalSec} * ${intervalSec}`;
|
||||||
|
let query = `
|
||||||
|
SELECT itemid 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 ${time_expression}, metric
|
||||||
|
ORDER BY time_sec ASC
|
||||||
|
`;
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildMysqlTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) {
|
||||||
|
let time_expression = `clock DIV ${intervalSec} * ${intervalSec}`;
|
||||||
|
let query = `
|
||||||
|
SELECT itemid 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 ${time_expression}, metric
|
||||||
|
ORDER BY time_sec ASC
|
||||||
|
`;
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TEST_MYSQL_QUERY = `SELECT itemid AS metric, clock AS time_sec, value_avg AS value FROM trends_uint LIMIT 1`;
|
||||||
|
|
||||||
|
////////////////
|
||||||
|
// PostgreSQL //
|
||||||
|
////////////////
|
||||||
|
|
||||||
|
function buildPostgresHistoryQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction) {
|
||||||
|
let time_expression = `clock / ${intervalSec} * ${intervalSec}`;
|
||||||
|
let query = `
|
||||||
|
SELECT DISTINCT to_char(itemid, 'FM9999999999999') AS metric,
|
||||||
|
${time_expression} AS time,
|
||||||
|
${aggFunction}(value) OVER (PARTITION BY clock / ${intervalSec}) AS value
|
||||||
|
FROM ${table}
|
||||||
|
WHERE itemid IN (${itemids})
|
||||||
|
AND clock > ${timeFrom} AND clock < ${timeTill}
|
||||||
|
GROUP BY metric, clock, value
|
||||||
|
ORDER BY time ASC
|
||||||
|
`;
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildPostgresTrendsQuery(itemids, table, timeFrom, timeTill, intervalSec, aggFunction, valueColumn) {
|
||||||
|
let time_expression = `clock / ${intervalSec} * ${intervalSec}`;
|
||||||
|
let query = `
|
||||||
|
SELECT DISTINCT to_char(itemid, 'FM9999999999999') AS metric,
|
||||||
|
${time_expression} AS time,
|
||||||
|
${aggFunction}(${valueColumn}) OVER (PARTITION BY clock / ${intervalSec}) AS value
|
||||||
|
FROM ${table}
|
||||||
|
WHERE itemid IN (${itemids})
|
||||||
|
AND clock > ${timeFrom} AND clock < ${timeTill}
|
||||||
|
GROUP BY metric, clock, ${valueColumn}
|
||||||
|
ORDER BY time ASC
|
||||||
|
`;
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TEST_POSTGRES_QUERY = `
|
||||||
|
SELECT to_char(itemid, 'FM9999999999999') AS metric, clock AS time, value_avg AS value
|
||||||
|
FROM trends_uint LIMIT 1
|
||||||
|
`;
|
||||||
|
|||||||
Reference in New Issue
Block a user