Merge branch 'master' into metric-functions
This commit is contained in:
32
dist/README.md
vendored
32
dist/README.md
vendored
@@ -1,28 +1,22 @@
|
||||
## Zabbix plugin for Grafana
|
||||
# Zabbix plugin for Grafana
|
||||
|
||||
[](https://github.com/alexanderzobnin/grafana-zabbix/releases)
|
||||
[](https://github.com/alexanderzobnin/grafana-zabbix/blob/master/CHANGELOG.md)
|
||||
[](http://docs.grafana-zabbix.org)
|
||||
[](https://github.com/alexanderzobnin/grafana-zabbix/blob/master/LICENSE)
|
||||
|
||||
Zabbix plugin allows to show different type of data from [Zabbix](http://www.zabbix.com/)
|
||||
monitoring system.
|
||||
Visualize your Zabbix metrics with the leading open source software for time series analytics.
|
||||
|
||||
### Live Demo
|
||||
|
||||
Check out the [live demo](http://play.grafana-zabbix.org/) with dashboard examples.
|
||||
See all features overview and dashboards examples at Grafana-Zabbix [Live demo](http://play.grafana-zabbix.org) site.
|
||||
|
||||
### Features
|
||||
|
||||
#### Flexible metric editor
|
||||
* Regex-based metric filtering
|
||||
* Client-side data processing functions
|
||||
* Template variables support
|
||||
|
||||
#### Templated dashboards support
|
||||
Group, host, application or item names can be replaced with a template variable. This allows you to create generic dashboards that can quickly be changed to show stats for a specific cluster, server or application.
|
||||
|
||||
#### Annotations support
|
||||
* Display zabbix events on graphs
|
||||
* Show acknowledges for problems
|
||||
|
||||
#### Triggers panel
|
||||
Panel for showing Zabbix triggers (like Last 20 issues) with some customizable features.
|
||||
- Select multiple metrics [by using Regex](http://docs.grafana-zabbix.org/guides/gettingstarted/#multiple-items-on-one-graph)
|
||||
- Create interactive and reusable dashboards with [template variables](http://docs.grafana-zabbix.org/guides/templating/)
|
||||
- Show events on graphs with [Annotations](http://docs.grafana.org/reference/annotations/)
|
||||
- Display active problems with Triggers panel
|
||||
- Transform and shape your data with [metric processing functions](http://docs.grafana-zabbix.org/reference/functions/) (Avg, Median, Min, Max, Multiply, Summarize, Time shift, Alias)
|
||||
- Find problems faster with [Alerting](http://docs.grafana-zabbix.org/reference/alerting/) feature
|
||||
- Mix metrics from multiple data sources in the same dashboard or even graph
|
||||
- Discover and share [dashboards](https://grafana.com/dashboards) in the official library
|
||||
|
||||
74
dist/datasource-zabbix/config.controller.js
vendored
Normal file
74
dist/datasource-zabbix/config.controller.js
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
'use strict';
|
||||
|
||||
System.register(['lodash'], function (_export, _context) {
|
||||
"use strict";
|
||||
|
||||
var _, _createClass, SUPPORTED_SQL_DS, defaultConfig, ZabbixDSConfigController;
|
||||
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
setters: [function (_lodash) {
|
||||
_ = _lodash.default;
|
||||
}],
|
||||
execute: function () {
|
||||
_createClass = function () {
|
||||
function defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, descriptor.key, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return function (Constructor, protoProps, staticProps) {
|
||||
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
};
|
||||
}();
|
||||
|
||||
SUPPORTED_SQL_DS = ['mysql'];
|
||||
defaultConfig = {
|
||||
dbConnection: {
|
||||
enable: false
|
||||
}
|
||||
};
|
||||
|
||||
_export('ZabbixDSConfigController', ZabbixDSConfigController = function () {
|
||||
/** @ngInject */
|
||||
function ZabbixDSConfigController($scope, $injector, datasourceSrv) {
|
||||
_classCallCheck(this, ZabbixDSConfigController);
|
||||
|
||||
this.datasourceSrv = datasourceSrv;
|
||||
|
||||
_.defaults(this.current.jsonData, defaultConfig);
|
||||
this.sqlDataSources = this.getSupportedSQLDataSources();
|
||||
}
|
||||
|
||||
_createClass(ZabbixDSConfigController, [{
|
||||
key: 'getSupportedSQLDataSources',
|
||||
value: function getSupportedSQLDataSources() {
|
||||
var datasources = this.datasourceSrv.getAll();
|
||||
return _.filter(datasources, function (ds) {
|
||||
return _.includes(SUPPORTED_SQL_DS, ds.type);
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return ZabbixDSConfigController;
|
||||
}());
|
||||
|
||||
_export('ZabbixDSConfigController', ZabbixDSConfigController);
|
||||
|
||||
ZabbixDSConfigController.templateUrl = 'datasource-zabbix/partials/config.html';
|
||||
}
|
||||
};
|
||||
});
|
||||
//# sourceMappingURL=config.controller.js.map
|
||||
1
dist/datasource-zabbix/config.controller.js.map
vendored
Normal file
1
dist/datasource-zabbix/config.controller.js.map
vendored
Normal file
@@ -0,0 +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"]}
|
||||
10
dist/datasource-zabbix/constants.js
vendored
10
dist/datasource-zabbix/constants.js
vendored
@@ -3,7 +3,7 @@
|
||||
System.register([], function (_export, _context) {
|
||||
"use strict";
|
||||
|
||||
var MODE_METRICS, MODE_TEXT, MODE_ITSERVICE, SEV_NOT_CLASSIFIED, SEV_INFORMATION, SEV_WARNING, SEV_AVERAGE, SEV_HIGH, SEV_DISASTER, SHOW_ALL_TRIGGERS, SHOW_ALL_EVENTS, SHOW_OK_EVENTS, DATAPOINT_VALUE, DATAPOINT_TS;
|
||||
var MODE_METRICS, MODE_ITSERVICE, MODE_TEXT, MODE_ITEMID, SEV_NOT_CLASSIFIED, SEV_INFORMATION, SEV_WARNING, SEV_AVERAGE, SEV_HIGH, SEV_DISASTER, SHOW_ALL_TRIGGERS, SHOW_ALL_EVENTS, SHOW_OK_EVENTS, DATAPOINT_VALUE, DATAPOINT_TS;
|
||||
return {
|
||||
setters: [],
|
||||
execute: function () {
|
||||
@@ -11,13 +11,17 @@ System.register([], function (_export, _context) {
|
||||
|
||||
_export("MODE_METRICS", MODE_METRICS);
|
||||
|
||||
_export("MODE_ITSERVICE", MODE_ITSERVICE = 1);
|
||||
|
||||
_export("MODE_ITSERVICE", MODE_ITSERVICE);
|
||||
|
||||
_export("MODE_TEXT", MODE_TEXT = 2);
|
||||
|
||||
_export("MODE_TEXT", MODE_TEXT);
|
||||
|
||||
_export("MODE_ITSERVICE", MODE_ITSERVICE = 1);
|
||||
_export("MODE_ITEMID", MODE_ITEMID = 3);
|
||||
|
||||
_export("MODE_ITSERVICE", MODE_ITSERVICE);
|
||||
_export("MODE_ITEMID", MODE_ITEMID);
|
||||
|
||||
_export("SEV_NOT_CLASSIFIED", SEV_NOT_CLASSIFIED = 0);
|
||||
|
||||
|
||||
2
dist/datasource-zabbix/constants.js.map
vendored
2
dist/datasource-zabbix/constants.js.map
vendored
@@ -1 +1 @@
|
||||
{"version":3,"sources":["../../src/datasource-zabbix/constants.js"],"names":["MODE_METRICS","MODE_TEXT","MODE_ITSERVICE","SEV_NOT_CLASSIFIED","SEV_INFORMATION","SEV_WARNING","SEV_AVERAGE","SEV_HIGH","SEV_DISASTER","SHOW_ALL_TRIGGERS","SHOW_ALL_EVENTS","SHOW_OK_EVENTS","DATAPOINT_VALUE","DATAPOINT_TS"],"mappings":";;;;;;;;;8BACaA,Y,GAAe,C;;;;2BACfC,S,GAAY,C;;;;gCACZC,c,GAAiB,C;;;;oCAGjBC,kB,GAAqB,C;;;;iCACrBC,e,GAAkB,C;;;;6BAClBC,W,GAAc,C;;;;6BACdC,W,GAAc,C;;;;0BACdC,Q,GAAW,C;;;;8BACXC,Y,GAAe,C;;;;mCAEfC,iB,GAAoB,CAAC,CAAD,EAAI,CAAJ,C;;;;iCACpBC,e,GAAkB,CAAC,CAAD,EAAI,CAAJ,C;;;;gCAClBC,c,GAAiB,C;;;;iCAGjBC,e,GAAkB,C;;;;8BAClBC,Y,GAAe,C","file":"constants.js","sourcesContent":["// Editor modes\nexport const MODE_METRICS = 0;\nexport const MODE_TEXT = 2;\nexport const MODE_ITSERVICE = 1;\n\n// Triggers severity\nexport const SEV_NOT_CLASSIFIED = 0;\nexport const SEV_INFORMATION = 1;\nexport const SEV_WARNING = 2;\nexport const SEV_AVERAGE = 3;\nexport const SEV_HIGH = 4;\nexport const SEV_DISASTER = 5;\n\nexport const SHOW_ALL_TRIGGERS = [0, 1];\nexport const SHOW_ALL_EVENTS = [0, 1];\nexport const SHOW_OK_EVENTS = 1;\n\n// Data point\nexport const DATAPOINT_VALUE = 0;\nexport const DATAPOINT_TS = 1;\n"]}
|
||||
{"version":3,"sources":["../../src/datasource-zabbix/constants.js"],"names":["MODE_METRICS","MODE_ITSERVICE","MODE_TEXT","MODE_ITEMID","SEV_NOT_CLASSIFIED","SEV_INFORMATION","SEV_WARNING","SEV_AVERAGE","SEV_HIGH","SEV_DISASTER","SHOW_ALL_TRIGGERS","SHOW_ALL_EVENTS","SHOW_OK_EVENTS","DATAPOINT_VALUE","DATAPOINT_TS"],"mappings":";;;;;;;;;8BACaA,Y,GAAe,C;;;;gCACfC,c,GAAiB,C;;;;2BACjBC,S,GAAY,C;;;;6BACZC,W,GAAc,C;;;;oCAGdC,kB,GAAqB,C;;;;iCACrBC,e,GAAkB,C;;;;6BAClBC,W,GAAc,C;;;;6BACdC,W,GAAc,C;;;;0BACdC,Q,GAAW,C;;;;8BACXC,Y,GAAe,C;;;;mCAEfC,iB,GAAoB,CAAC,CAAD,EAAI,CAAJ,C;;;;iCACpBC,e,GAAkB,CAAC,CAAD,EAAI,CAAJ,C;;;;gCAClBC,c,GAAiB,C;;;;iCAGjBC,e,GAAkB,C;;;;8BAClBC,Y,GAAe,C","file":"constants.js","sourcesContent":["// Editor modes\nexport const MODE_METRICS = 0;\nexport const MODE_ITSERVICE = 1;\nexport const MODE_TEXT = 2;\nexport const MODE_ITEMID = 3;\n\n// Triggers severity\nexport const SEV_NOT_CLASSIFIED = 0;\nexport const SEV_INFORMATION = 1;\nexport const SEV_WARNING = 2;\nexport const SEV_AVERAGE = 3;\nexport const SEV_HIGH = 4;\nexport const SEV_DISASTER = 5;\n\nexport const SHOW_ALL_TRIGGERS = [0, 1];\nexport const SHOW_ALL_EVENTS = [0, 1];\nexport const SHOW_OK_EVENTS = 1;\n\n// Data point\nexport const DATAPOINT_VALUE = 0;\nexport const DATAPOINT_TS = 1;\n"]}
|
||||
228
dist/datasource-zabbix/datasource.js
vendored
228
dist/datasource-zabbix/datasource.js
vendored
@@ -23,10 +23,23 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
});
|
||||
}
|
||||
|
||||
function getConsolidateBy(target) {
|
||||
var consolidateBy = 'avg';
|
||||
var funcDef = _.find(target.functions, function (func) {
|
||||
return func.def.name === 'consolidateBy';
|
||||
});
|
||||
if (funcDef && funcDef.params && funcDef.params.length) {
|
||||
consolidateBy = funcDef.params[0];
|
||||
}
|
||||
return consolidateBy;
|
||||
}
|
||||
|
||||
function downsampleSeries(timeseries_data, options) {
|
||||
var defaultAgg = dataProcessor.aggregationFunctions['avg'];
|
||||
var consolidateByFunc = dataProcessor.aggregationFunctions[options.consolidateBy] || defaultAgg;
|
||||
return _.map(timeseries_data, function (timeseries) {
|
||||
if (timeseries.datapoints.length > options.maxDataPoints) {
|
||||
timeseries.datapoints = dataProcessor.groupBy(options.interval, dataProcessor.AVERAGE, timeseries.datapoints);
|
||||
timeseries.datapoints = dataProcessor.groupBy(options.interval, consolidateByFunc, timeseries.datapoints);
|
||||
}
|
||||
return timeseries;
|
||||
});
|
||||
@@ -58,6 +71,13 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
return '(' + escapedValues.join('|') + ')';
|
||||
}
|
||||
|
||||
function zabbixItemIdsTemplateFormat(value) {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
return value.join(',');
|
||||
}
|
||||
|
||||
/**
|
||||
* If template variables are used in request, replace it using regex format
|
||||
* and wrap with '/' for proper multi-value work. Example:
|
||||
@@ -191,6 +211,9 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
this.dashboardSrv = dashboardSrv;
|
||||
this.zabbixAlertingSrv = zabbixAlertingSrv;
|
||||
|
||||
// Use custom format for template variables
|
||||
this.replaceTemplateVars = _.partial(replaceTemplateVars, this.templateSrv);
|
||||
|
||||
// General data source settings
|
||||
this.name = instanceSettings.name;
|
||||
this.url = instanceSettings.url;
|
||||
@@ -215,10 +238,21 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
this.addThresholds = instanceSettings.jsonData.addThresholds;
|
||||
this.alertingMinSeverity = instanceSettings.jsonData.alertingMinSeverity || c.SEV_WARNING;
|
||||
|
||||
this.zabbix = new Zabbix(this.url, this.username, this.password, this.basicAuth, this.withCredentials, this.cacheTTL);
|
||||
// Direct DB Connection options
|
||||
this.enableDirectDBConnection = instanceSettings.jsonData.dbConnection.enable;
|
||||
this.sqlDatasourceId = instanceSettings.jsonData.dbConnection.datasourceId;
|
||||
|
||||
// Use custom format for template variables
|
||||
this.replaceTemplateVars = _.partial(replaceTemplateVars, this.templateSrv);
|
||||
var zabbixOptions = {
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
basicAuth: this.basicAuth,
|
||||
withCredentials: this.withCredentials,
|
||||
cacheTTL: this.cacheTTL,
|
||||
enableDirectDBConnection: this.enableDirectDBConnection,
|
||||
sqlDatasourceId: this.sqlDatasourceId
|
||||
};
|
||||
|
||||
this.zabbix = new Zabbix(this.url, zabbixOptions);
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
@@ -253,6 +287,11 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
|
||||
// Create request for each target
|
||||
var promises = _.map(options.targets, function (t) {
|
||||
// Don't request undefined and hidden targets
|
||||
if (t.hide) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var timeFrom = Math.ceil(dateMath.parse(options.range.from) / 1000);
|
||||
var timeTo = Math.ceil(dateMath.parse(options.range.to) / 1000);
|
||||
|
||||
@@ -276,7 +315,7 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
var useTrends = _this.isUseTrends(timeRange);
|
||||
|
||||
// Metrics or Text query mode
|
||||
if (target.mode !== c.MODE_ITSERVICE) {
|
||||
if (target.mode === c.MODE_METRICS || target.mode === c.MODE_TEXT || target.mode === c.MODE_ITEMID) {
|
||||
// Migrate old targets
|
||||
target = migrations.migrate(target);
|
||||
|
||||
@@ -289,20 +328,13 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
return _this.queryNumericData(target, timeRange, useTrends, options);
|
||||
} else if (target.mode === c.MODE_TEXT) {
|
||||
return _this.queryTextData(target, timeRange);
|
||||
} else if (target.mode === c.MODE_ITEMID) {
|
||||
return _this.queryItemIdData(target, timeRange, useTrends, options);
|
||||
}
|
||||
} else if (target.mode === c.MODE_ITSERVICE) {
|
||||
// IT services mode
|
||||
return _this.queryITServiceData(target, timeRange, options);
|
||||
}
|
||||
|
||||
// IT services mode
|
||||
else if (target.mode === c.MODE_ITSERVICE) {
|
||||
// Don't show undefined and hidden targets
|
||||
if (target.hide || !target.itservice || !target.slaProperty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return _this.zabbix.getSLA(target.itservice.serviceid, timeRange).then(function (slaObject) {
|
||||
return responseHandler.handleSLAResponse(target.itservice, target.slaProperty, slaObject);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Data for panel (all targets)
|
||||
@@ -315,19 +347,33 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
value: function queryNumericData(target, timeRange, useTrends, options) {
|
||||
var _this2 = this;
|
||||
|
||||
var _timeRange = _slicedToArray(timeRange, 2),
|
||||
timeFrom = _timeRange[0],
|
||||
timeTo = _timeRange[1];
|
||||
|
||||
var getItemOptions = {
|
||||
itemtype: 'num'
|
||||
};
|
||||
return this.zabbix.getItemsFromTarget(target, getItemOptions).then(function (items) {
|
||||
var getHistoryPromise = void 0;
|
||||
return _this2.queryNumericDataForItems(items, target, timeRange, useTrends, options);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'queryNumericDataForItems',
|
||||
value: function queryNumericDataForItems(items, target, timeRange, useTrends, options) {
|
||||
var _this3 = this;
|
||||
|
||||
if (useTrends) {
|
||||
var valueType = _this2.getTrendValueType(target);
|
||||
getHistoryPromise = _this2.zabbix.getTrend(items, timeFrom, timeTo).then(function (history) {
|
||||
var _timeRange = _slicedToArray(timeRange, 2),
|
||||
timeFrom = _timeRange[0],
|
||||
timeTo = _timeRange[1];
|
||||
|
||||
var getHistoryPromise = void 0;
|
||||
options.consolidateBy = getConsolidateBy(target);
|
||||
|
||||
if (useTrends) {
|
||||
if (this.enableDirectDBConnection) {
|
||||
getHistoryPromise = this.zabbix.getTrendsDB(items, timeFrom, timeTo, options).then(function (history) {
|
||||
return _this3.zabbix.dbConnector.handleGrafanaTSResponse(history, items);
|
||||
});
|
||||
} else {
|
||||
var valueType = this.getTrendValueType(target);
|
||||
getHistoryPromise = this.zabbix.getTrend(items, timeFrom, timeTo).then(function (history) {
|
||||
return responseHandler.handleTrends(history, items, valueType);
|
||||
}).then(function (timeseries) {
|
||||
// Sort trend data, issue #202
|
||||
@@ -336,19 +382,24 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
return point[c.DATAPOINT_TS];
|
||||
});
|
||||
});
|
||||
|
||||
return timeseries;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Use history
|
||||
if (this.enableDirectDBConnection) {
|
||||
getHistoryPromise = this.zabbix.getHistoryDB(items, timeFrom, timeTo, options).then(function (history) {
|
||||
return _this3.zabbix.dbConnector.handleGrafanaTSResponse(history, items);
|
||||
});
|
||||
} else {
|
||||
// Use history
|
||||
getHistoryPromise = _this2.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) {
|
||||
getHistoryPromise = this.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) {
|
||||
return responseHandler.handleHistory(history, items);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return getHistoryPromise;
|
||||
}).then(function (timeseries) {
|
||||
return _this2.applyDataProcessingFunctions(timeseries, target);
|
||||
return getHistoryPromise.then(function (timeseries) {
|
||||
return _this3.applyDataProcessingFunctions(timeseries, target);
|
||||
}).then(function (timeseries) {
|
||||
return downsampleSeries(timeseries, options);
|
||||
}).catch(function (error) {
|
||||
@@ -427,7 +478,7 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
}, {
|
||||
key: 'queryTextData',
|
||||
value: function queryTextData(target, timeRange) {
|
||||
var _this3 = this;
|
||||
var _this4 = this;
|
||||
|
||||
var _timeRange2 = _slicedToArray(timeRange, 2),
|
||||
timeFrom = _timeRange2[0],
|
||||
@@ -438,7 +489,7 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
};
|
||||
return this.zabbix.getItemsFromTarget(target, options).then(function (items) {
|
||||
if (items.length) {
|
||||
return _this3.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) {
|
||||
return _this4.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) {
|
||||
return responseHandler.handleText(history, items, target);
|
||||
});
|
||||
} else {
|
||||
@@ -446,15 +497,79 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
}
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'queryItemIdData',
|
||||
value: function queryItemIdData(target, timeRange, useTrends, options) {
|
||||
var _this5 = this;
|
||||
|
||||
var itemids = target.itemids;
|
||||
itemids = this.templateSrv.replace(itemids, options.scopedVars, zabbixItemIdsTemplateFormat);
|
||||
itemids = _.map(itemids.split(','), function (itemid) {
|
||||
return itemid.trim();
|
||||
});
|
||||
|
||||
if (!itemids) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.zabbix.getItemsByIDs(itemids).then(function (items) {
|
||||
return _this5.queryNumericDataForItems(items, target, timeRange, useTrends, options);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'queryITServiceData',
|
||||
value: function queryITServiceData(target, timeRange, options) {
|
||||
var _this6 = this;
|
||||
|
||||
// Don't show undefined and hidden targets
|
||||
if (target.hide || !target.itservice && !target.itServiceFilter || !target.slaProperty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var itServiceIds = [];
|
||||
var itServices = [];
|
||||
var itServiceFilter = void 0;
|
||||
var isOldVersion = target.itservice && !target.itServiceFilter;
|
||||
|
||||
if (isOldVersion) {
|
||||
// Backward compatibility
|
||||
itServiceFilter = '/.*/';
|
||||
} else {
|
||||
itServiceFilter = this.replaceTemplateVars(target.itServiceFilter, options.scopedVars);
|
||||
}
|
||||
|
||||
return this.zabbix.getITServices(itServiceFilter).then(function (itservices) {
|
||||
itServices = itservices;
|
||||
if (isOldVersion) {
|
||||
itServices = _.filter(itServices, { 'serviceid': target.itservice.serviceid });
|
||||
}
|
||||
|
||||
itServiceIds = _.map(itServices, 'serviceid');
|
||||
return itServiceIds;
|
||||
}).then(function (serviceids) {
|
||||
return _this6.zabbix.getSLA(serviceids, timeRange);
|
||||
}).then(function (slaResponse) {
|
||||
return _.map(itServiceIds, function (serviceid) {
|
||||
var itservice = _.find(itServices, { 'serviceid': serviceid });
|
||||
return responseHandler.handleSLAResponse(itservice, target.slaProperty, slaResponse);
|
||||
});
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'testDatasource',
|
||||
value: function testDatasource() {
|
||||
var _this4 = this;
|
||||
var _this7 = this;
|
||||
|
||||
var zabbixVersion = void 0;
|
||||
return this.zabbix.getVersion().then(function (version) {
|
||||
zabbixVersion = version;
|
||||
return _this4.zabbix.login();
|
||||
return _this7.zabbix.login();
|
||||
}).then(function () {
|
||||
if (_this7.enableDirectDBConnection) {
|
||||
return _this7.zabbix.dbConnector.testSQLDataSource();
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}).then(function () {
|
||||
return {
|
||||
status: "success",
|
||||
@@ -468,6 +583,12 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
title: error.message,
|
||||
message: error.data
|
||||
};
|
||||
} else if (error.data && error.data.message) {
|
||||
return {
|
||||
status: "error",
|
||||
title: "Connection failed",
|
||||
message: error.data.message
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
status: "error",
|
||||
@@ -480,14 +601,14 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
}, {
|
||||
key: 'metricFindQuery',
|
||||
value: function metricFindQuery(query) {
|
||||
var _this5 = this;
|
||||
var _this8 = this;
|
||||
|
||||
var result = void 0;
|
||||
var parts = [];
|
||||
|
||||
// Split query. Query structure: group.host.app.item
|
||||
_.each(utils.splitTemplateQuery(query), function (part) {
|
||||
part = _this5.replaceTemplateVars(part, {});
|
||||
part = _this8.replaceTemplateVars(part, {});
|
||||
|
||||
// Replace wildcard to regex
|
||||
if (part === '*') {
|
||||
@@ -524,7 +645,7 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
}, {
|
||||
key: 'annotationQuery',
|
||||
value: function annotationQuery(options) {
|
||||
var _this6 = this;
|
||||
var _this9 = this;
|
||||
|
||||
var timeFrom = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);
|
||||
var timeTo = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);
|
||||
@@ -542,13 +663,14 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
return getTriggers.then(function (triggers) {
|
||||
|
||||
// Filter triggers by description
|
||||
if (utils.isRegex(annotation.trigger)) {
|
||||
var triggerName = _this9.replaceTemplateVars(annotation.trigger, {});
|
||||
if (utils.isRegex(triggerName)) {
|
||||
triggers = _.filter(triggers, function (trigger) {
|
||||
return utils.buildRegex(annotation.trigger).test(trigger.description);
|
||||
return utils.buildRegex(triggerName).test(trigger.description);
|
||||
});
|
||||
} else if (annotation.trigger) {
|
||||
} else if (triggerName) {
|
||||
triggers = _.filter(triggers, function (trigger) {
|
||||
return trigger.description === annotation.trigger;
|
||||
return trigger.description === triggerName;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -558,7 +680,7 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
});
|
||||
|
||||
var objectids = _.map(triggers, 'triggerid');
|
||||
return _this6.zabbix.getEvents(objectids, timeFrom, timeTo, showOkEvents).then(function (events) {
|
||||
return _this9.zabbix.getEvents(objectids, timeFrom, timeTo, showOkEvents).then(function (events) {
|
||||
var indexedTriggers = _.keyBy(triggers, 'triggerid');
|
||||
|
||||
// Hide acknowledged events if option enabled
|
||||
@@ -592,21 +714,23 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
}, {
|
||||
key: 'alertQuery',
|
||||
value: function alertQuery(options) {
|
||||
var _this7 = this;
|
||||
var _this10 = this;
|
||||
|
||||
var enabled_targets = filterEnabledTargets(options.targets);
|
||||
var getPanelItems = _.map(enabled_targets, function (target) {
|
||||
return _this7.zabbix.getItemsFromTarget(target, { itemtype: 'num' });
|
||||
var getPanelItems = _.map(enabled_targets, function (t) {
|
||||
var target = _.cloneDeep(t);
|
||||
_this10.replaceTargetVariables(target, options);
|
||||
return _this10.zabbix.getItemsFromTarget(target, { itemtype: 'num' });
|
||||
});
|
||||
|
||||
return Promise.all(getPanelItems).then(function (results) {
|
||||
var items = _.flatten(results);
|
||||
var itemids = _.map(items, 'itemid');
|
||||
|
||||
return _this7.zabbix.getAlerts(itemids);
|
||||
return _this10.zabbix.getAlerts(itemids);
|
||||
}).then(function (triggers) {
|
||||
triggers = _.filter(triggers, function (trigger) {
|
||||
return trigger.priority >= _this7.alertingMinSeverity;
|
||||
return trigger.priority >= _this10.alertingMinSeverity;
|
||||
});
|
||||
|
||||
if (!triggers || triggers.length === 0) {
|
||||
@@ -634,12 +758,12 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
}, {
|
||||
key: 'replaceTargetVariables',
|
||||
value: function replaceTargetVariables(target, options) {
|
||||
var _this8 = this;
|
||||
var _this11 = this;
|
||||
|
||||
var parts = ['group', 'host', 'application', 'item'];
|
||||
_.forEach(parts, function (p) {
|
||||
if (target[p] && target[p].filter) {
|
||||
target[p].filter = _this8.replaceTemplateVars(target[p].filter, options.scopedVars);
|
||||
target[p].filter = _this11.replaceTemplateVars(target[p].filter, options.scopedVars);
|
||||
}
|
||||
});
|
||||
target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars);
|
||||
@@ -647,9 +771,9 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
|
||||
_.forEach(target.functions, function (func) {
|
||||
func.params = _.map(func.params, function (param) {
|
||||
if (typeof param === 'number') {
|
||||
return +_this8.templateSrv.replace(param.toString(), options.scopedVars);
|
||||
return +_this11.templateSrv.replace(param.toString(), options.scopedVars);
|
||||
} else {
|
||||
return _this8.templateSrv.replace(param, options.scopedVars);
|
||||
return _this11.templateSrv.replace(param, options.scopedVars);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
2
dist/datasource-zabbix/datasource.js.map
vendored
2
dist/datasource-zabbix/datasource.js.map
vendored
File diff suppressed because one or more lines are too long
14
dist/datasource-zabbix/module.js
vendored
14
dist/datasource-zabbix/module.js
vendored
@@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
System.register(['./datasource', './query.controller'], function (_export, _context) {
|
||||
System.register(['./datasource', './query.controller', './config.controller'], function (_export, _context) {
|
||||
"use strict";
|
||||
|
||||
var ZabbixAPIDatasource, ZabbixQueryController, ZabbixConfigController, ZabbixQueryOptionsController, ZabbixAnnotationsQueryController;
|
||||
var ZabbixAPIDatasource, ZabbixQueryController, ZabbixDSConfigController, ZabbixQueryOptionsController, ZabbixAnnotationsQueryController;
|
||||
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
@@ -16,14 +16,10 @@ System.register(['./datasource', './query.controller'], function (_export, _cont
|
||||
ZabbixAPIDatasource = _datasource.ZabbixAPIDatasource;
|
||||
}, function (_queryController) {
|
||||
ZabbixQueryController = _queryController.ZabbixQueryController;
|
||||
}, function (_configController) {
|
||||
ZabbixDSConfigController = _configController.ZabbixDSConfigController;
|
||||
}],
|
||||
execute: function () {
|
||||
_export('ConfigCtrl', ZabbixConfigController = function ZabbixConfigController() {
|
||||
_classCallCheck(this, ZabbixConfigController);
|
||||
});
|
||||
|
||||
ZabbixConfigController.templateUrl = 'datasource-zabbix/partials/config.html';
|
||||
|
||||
_export('QueryOptionsCtrl', ZabbixQueryOptionsController = function ZabbixQueryOptionsController() {
|
||||
_classCallCheck(this, ZabbixQueryOptionsController);
|
||||
});
|
||||
@@ -38,7 +34,7 @@ System.register(['./datasource', './query.controller'], function (_export, _cont
|
||||
|
||||
_export('Datasource', ZabbixAPIDatasource);
|
||||
|
||||
_export('ConfigCtrl', ZabbixConfigController);
|
||||
_export('ConfigCtrl', ZabbixDSConfigController);
|
||||
|
||||
_export('QueryCtrl', ZabbixQueryController);
|
||||
|
||||
|
||||
2
dist/datasource-zabbix/module.js.map
vendored
2
dist/datasource-zabbix/module.js.map
vendored
@@ -1 +1 @@
|
||||
{"version":3,"sources":["../../src/datasource-zabbix/module.js"],"names":["ZabbixAPIDatasource","ZabbixQueryController","ZabbixConfigController","templateUrl","ZabbixQueryOptionsController","ZabbixAnnotationsQueryController"],"mappings":";;;;;;;;;;;;;;;AAAQA,yB,eAAAA,mB;;AACAC,2B,oBAAAA,qB;;;4BAEFC,sB;;;;AACNA,6BAAuBC,WAAvB,GAAqC,wCAArC;;kCAEMC,4B;;;;AACNA,mCAA6BD,WAA7B,GAA2C,+CAA3C;;sCAEME,gC;;;;AACNA,uCAAiCF,WAAjC,GAA+C,oDAA/C;;4BAGEH,mB;;4BACAE,sB;;2BACAD,qB;;kCACAG,4B;;sCACAC,gC","file":"module.js","sourcesContent":["import {ZabbixAPIDatasource} from './datasource';\nimport {ZabbixQueryController} from './query.controller';\n\nclass ZabbixConfigController {}\nZabbixConfigController.templateUrl = 'datasource-zabbix/partials/config.html';\n\nclass ZabbixQueryOptionsController {}\nZabbixQueryOptionsController.templateUrl = 'datasource-zabbix/partials/query.options.html';\n\nclass ZabbixAnnotationsQueryController {}\nZabbixAnnotationsQueryController.templateUrl = 'datasource-zabbix/partials/annotations.editor.html';\n\nexport {\n ZabbixAPIDatasource as Datasource,\n ZabbixConfigController as ConfigCtrl,\n ZabbixQueryController as QueryCtrl,\n ZabbixQueryOptionsController as QueryOptionsCtrl,\n ZabbixAnnotationsQueryController as AnnotationsQueryCtrl\n};\n"]}
|
||||
{"version":3,"sources":["../../src/datasource-zabbix/module.js"],"names":["ZabbixAPIDatasource","ZabbixQueryController","ZabbixDSConfigController","ZabbixQueryOptionsController","templateUrl","ZabbixAnnotationsQueryController"],"mappings":";;;;;;;;;;;;;;;AAAQA,yB,eAAAA,mB;;AACAC,2B,oBAAAA,qB;;AACAC,8B,qBAAAA,wB;;;kCAEFC,4B;;;;AACNA,mCAA6BC,WAA7B,GAA2C,+CAA3C;;sCAEMC,gC;;;;AACNA,uCAAiCD,WAAjC,GAA+C,oDAA/C;;4BAGEJ,mB;;4BACAE,wB;;2BACAD,qB;;kCACAE,4B;;sCACAE,gC","file":"module.js","sourcesContent":["import {ZabbixAPIDatasource} from './datasource';\nimport {ZabbixQueryController} from './query.controller';\nimport {ZabbixDSConfigController} from './config.controller';\n\nclass ZabbixQueryOptionsController {}\nZabbixQueryOptionsController.templateUrl = 'datasource-zabbix/partials/query.options.html';\n\nclass ZabbixAnnotationsQueryController {}\nZabbixAnnotationsQueryController.templateUrl = 'datasource-zabbix/partials/annotations.editor.html';\n\nexport {\n ZabbixAPIDatasource as Datasource,\n ZabbixDSConfigController as ConfigCtrl,\n ZabbixQueryController as QueryCtrl,\n ZabbixQueryOptionsController as QueryOptionsCtrl,\n ZabbixAnnotationsQueryController as AnnotationsQueryCtrl\n};\n"]}
|
||||
59
dist/datasource-zabbix/partials/config.html
vendored
59
dist/datasource-zabbix/partials/config.html
vendored
@@ -76,24 +76,53 @@
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<h3 class="page-heading">Alerting</h3>
|
||||
<gf-form-switch class="gf-form" label-class="width-9"
|
||||
label="Enable alerting"
|
||||
checked="ctrl.current.jsonData.alerting">
|
||||
<h3 class="page-heading">Direct DB Connection</h3>
|
||||
<gf-form-switch class="gf-form" label-class="width-12"
|
||||
label="Enable"
|
||||
checked="ctrl.current.jsonData.dbConnection.enable">
|
||||
</gf-form-switch>
|
||||
<gf-form-switch class="gf-form" label-class="width-9"
|
||||
label="Add thresholds"
|
||||
checked="ctrl.current.jsonData.addThresholds">
|
||||
</gf-form-switch>
|
||||
<div class="gf-form max-width-20">
|
||||
<span class="gf-form-label width-9">Min severity</span>
|
||||
<div ng-if="ctrl.current.jsonData.dbConnection.enable">
|
||||
<div class="gf-form max-width-20">
|
||||
<span class="gf-form-label width-12">
|
||||
SQL Data Source
|
||||
<info-popover mode="right-normal">
|
||||
Select SQL Data Source for Zabbix database.
|
||||
In order to use this feature you should <a href="/datasources/new" target="_blank">create</a> and
|
||||
configure it first. Zabbix plugin uses this data source for querying history data directly from database.
|
||||
This way usually faster than pulling data from Zabbix API, especially on the wide time ranges, and reduces
|
||||
amount of data transfered.
|
||||
</info-popover>
|
||||
</span>
|
||||
<div class="gf-form-select-wrapper max-width-16">
|
||||
<select class="gf-form-input" ng-model="ctrl.current.jsonData.alertingMinSeverity"
|
||||
ng-options="s.val as s.text for s in [
|
||||
{val: 0, text: 'Not classified'}, {val: 1, text:'Information'},
|
||||
{val: 2, text: 'Warning'}, {val: 3, text: 'Average'},
|
||||
{val: 4, text: 'High'}, {val: 5, text: 'Disaster'}]">
|
||||
<select class="gf-form-input" ng-model="ctrl.current.jsonData.dbConnection.datasourceId"
|
||||
ng-options="ds.id as ds.name for ds in ctrl.sqlDataSources">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-group">
|
||||
<h3 class="page-heading">Alerting</h3>
|
||||
<gf-form-switch class="gf-form" label-class="width-12"
|
||||
label="Enable alerting"
|
||||
checked="ctrl.current.jsonData.alerting">
|
||||
</gf-form-switch>
|
||||
<div ng-if="ctrl.current.jsonData.alerting">
|
||||
<gf-form-switch class="gf-form" label-class="width-12"
|
||||
label="Add thresholds"
|
||||
checked="ctrl.current.jsonData.addThresholds">
|
||||
</gf-form-switch>
|
||||
<div class="gf-form max-width-20">
|
||||
<span class="gf-form-label width-12">Min severity</span>
|
||||
<div class="gf-form-select-wrapper max-width-16">
|
||||
<select class="gf-form-input" ng-model="ctrl.current.jsonData.alertingMinSeverity"
|
||||
ng-options="s.val as s.text for s in [
|
||||
{val: 0, text: 'Not classified'}, {val: 1, text:'Information'},
|
||||
{val: 2, text: 'Warning'}, {val: 3, text: 'Average'},
|
||||
{val: 4, text: 'High'}, {val: 5, text: 'Disaster'}]">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<select class="gf-form-input"
|
||||
ng-change="ctrl.switchEditorMode(ctrl.target.mode)"
|
||||
ng-model="ctrl.target.mode"
|
||||
ng-options="v.mode as v.text for (k, v) in ctrl.editorModes">
|
||||
ng-options="m.mode as m.text for m in ctrl.editorModes">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -17,27 +17,29 @@
|
||||
</div>
|
||||
|
||||
<!-- IT Service editor -->
|
||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == 1">
|
||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.ITSERVICE">
|
||||
<div class="gf-form max-width-20">
|
||||
<label class="gf-form-label query-keyword width-7">IT Service</label>
|
||||
<div class="gf-form-select-wrapper max-width-20">
|
||||
<select class="gf-form-input"
|
||||
ng-change="ctrl.selectITService()"
|
||||
ng-model="ctrl.target.itservice"
|
||||
bs-tooltip="ctrl.target.itservice.name.length > 25 ? ctrl.target.itservice.name : ''"
|
||||
ng-options="itservice.name for itservice in ctrl.itserviceList track by itservice.name">
|
||||
<option value="">-- Select IT service --</option>
|
||||
</select>
|
||||
</div>
|
||||
<input type="text"
|
||||
ng-model="ctrl.target.itServiceFilter"
|
||||
bs-typeahead="ctrl.getITServices"
|
||||
ng-blur="ctrl.onTargetBlur()"
|
||||
data-min-length=0
|
||||
data-items=100
|
||||
class="gf-form-input"
|
||||
ng-class="{
|
||||
'zbx-variable': ctrl.isVariable(ctrl.target.itServiceFilter),
|
||||
'zbx-regex': ctrl.isRegex(ctrl.target.itServiceFilter)
|
||||
}">
|
||||
</input>
|
||||
</div>
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword">IT service property</label>
|
||||
<label class="gf-form-label query-keyword">Property</label>
|
||||
<div class="gf-form-select-wrapper">
|
||||
<select class="gf-form-input"
|
||||
ng-change="ctrl.selectITService()"
|
||||
ng-model="ctrl.target.slaProperty"
|
||||
ng-options="slaProperty.name for slaProperty in ctrl.slaPropertyList track by slaProperty.name">
|
||||
<option value="">-- Property --</option>
|
||||
ng-change="ctrl.onTargetBlur()"
|
||||
ng-model="ctrl.target.slaProperty"
|
||||
ng-options="slaProperty.name for slaProperty in ctrl.slaPropertyList track by slaProperty.name">
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
@@ -46,7 +48,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-inline" ng-hide="ctrl.target.mode == 1">
|
||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT">
|
||||
<!-- Select Group -->
|
||||
<div class="gf-form max-width-20">
|
||||
<label class="gf-form-label query-keyword width-7">Group</label>
|
||||
@@ -83,7 +85,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="gf-form-inline" ng-hide="ctrl.target.mode == 1">
|
||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT">
|
||||
<!-- Select Application -->
|
||||
<div class="gf-form max-width-20">
|
||||
<label class="gf-form-label query-keyword width-7">Application</label>
|
||||
@@ -129,7 +131,7 @@
|
||||
<!-- Query options -->
|
||||
<div class="gf-form-group" ng-if="ctrl.showQueryOptions">
|
||||
<div class="gf-form offset-width-7">
|
||||
<gf-form-switch class="gf-form" ng-hide="ctrl.target.mode == 2"
|
||||
<gf-form-switch class="gf-form"
|
||||
label="Show disabled items"
|
||||
checked="ctrl.target.options.showDisabledItems"
|
||||
on-change="ctrl.onQueryOptionChange()">
|
||||
@@ -137,8 +139,30 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Item IDs editor mode -->
|
||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.ITEMID">
|
||||
<div class="gf-form max-width-20">
|
||||
<label class="gf-form-label query-keyword width-7">Item IDs</label>
|
||||
<input type="text"
|
||||
ng-model="ctrl.target.itemids"
|
||||
bs-typeahead="ctrl.getVariables"
|
||||
ng-blur="ctrl.onTargetBlur()"
|
||||
data-min-length=0
|
||||
data-items=100
|
||||
class="gf-form-input"
|
||||
ng-class="{
|
||||
'zbx-variable': ctrl.isVariable(ctrl.target.itServiceFilter),
|
||||
'zbx-regex': ctrl.isRegex(ctrl.target.itServiceFilter)
|
||||
}">
|
||||
</input>
|
||||
</div>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Metric processing functions -->
|
||||
<div class="gf-form-inline" ng-hide="ctrl.target.mode">
|
||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.ITEMID">
|
||||
<div class="gf-form">
|
||||
<label class="gf-form-label query-keyword width-7">Functions</label>
|
||||
<div ng-repeat="func in ctrl.target.functions" class="gf-form-label query-part" metric-function-editor></div>
|
||||
@@ -151,7 +175,7 @@
|
||||
</div>
|
||||
|
||||
<!-- Text mode options -->
|
||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == 2">
|
||||
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.TEXT">
|
||||
<!-- Text metric regex -->
|
||||
<div class="gf-form max-width-20">
|
||||
<label class="gf-form-label query-keyword width-7">Text filter</label>
|
||||
@@ -165,6 +189,8 @@
|
||||
|
||||
<gf-form-switch class="gf-form" label="Use capture groups" checked="ctrl.target.useCaptureGroups" on-change="ctrl.onTargetBlur()">
|
||||
</gf-form-switch>
|
||||
<div class="gf-form gf-form--grow">
|
||||
<div class="gf-form-label gf-form-label--grow"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</query-editor-row>
|
||||
|
||||
89
dist/datasource-zabbix/query.controller.js
vendored
89
dist/datasource-zabbix/query.controller.js
vendored
@@ -1,9 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils', './metricFunctions', './migrations', './add-metric-function.directive', './metric-function-editor.directive', './css/query-editor.css!'], function (_export, _context) {
|
||||
System.register(['app/plugins/sdk', 'lodash', './constants', './utils', './metricFunctions', './migrations', './add-metric-function.directive', './metric-function-editor.directive', './css/query-editor.css!'], function (_export, _context) {
|
||||
"use strict";
|
||||
|
||||
var QueryCtrl, angular, _, c, utils, metricFunctions, migrations, _createClass, ZabbixQueryController;
|
||||
var QueryCtrl, _, c, utils, metricFunctions, migrations, _createClass, ZabbixQueryController;
|
||||
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
@@ -38,8 +38,6 @@ System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils
|
||||
return {
|
||||
setters: [function (_appPluginsSdk) {
|
||||
QueryCtrl = _appPluginsSdk.QueryCtrl;
|
||||
}, function (_angular) {
|
||||
angular = _angular.default;
|
||||
}, function (_lodash) {
|
||||
_ = _lodash.default;
|
||||
}, function (_constants) {
|
||||
@@ -85,17 +83,24 @@ System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils
|
||||
_this.replaceTemplateVars = _this.datasource.replaceTemplateVars;
|
||||
_this.templateSrv = templateSrv;
|
||||
|
||||
_this.editorModes = {
|
||||
0: { value: 'num', text: 'Metrics', mode: c.MODE_METRICS },
|
||||
1: { value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE },
|
||||
2: { value: 'text', text: 'Text', mode: c.MODE_TEXT }
|
||||
_this.editorModes = [{ value: 'num', text: 'Metrics', mode: c.MODE_METRICS }, { value: 'text', text: 'Text', mode: c.MODE_TEXT }, { value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE }, { value: 'itemid', text: 'Item ID', mode: c.MODE_ITEMID }];
|
||||
|
||||
_this.$scope.editorMode = {
|
||||
METRICS: c.MODE_METRICS,
|
||||
TEXT: c.MODE_TEXT,
|
||||
ITSERVICE: c.MODE_ITSERVICE,
|
||||
ITEMID: c.MODE_ITEMID
|
||||
};
|
||||
|
||||
_this.slaPropertyList = [{ name: "Status", property: "status" }, { name: "SLA", property: "sla" }, { name: "OK time", property: "okTime" }, { name: "Problem time", property: "problemTime" }, { name: "Down time", property: "downtimeTime" }];
|
||||
|
||||
// Map functions for bs-typeahead
|
||||
_this.getGroupNames = _.bind(_this.getMetricNames, _this, 'groupList');
|
||||
_this.getHostNames = _.bind(_this.getMetricNames, _this, 'hostList', true);
|
||||
_this.getApplicationNames = _.bind(_this.getMetricNames, _this, 'appList');
|
||||
_this.getItemNames = _.bind(_this.getMetricNames, _this, 'itemList');
|
||||
_this.getITServices = _.bind(_this.getMetricNames, _this, 'itServiceList');
|
||||
_this.getVariables = _.bind(_this.getTemplateVariables, _this);
|
||||
|
||||
// Update metric suggestion when template variable was changed
|
||||
$rootScope.$on('template-variable-value-updated', function () {
|
||||
@@ -122,14 +127,14 @@ System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils
|
||||
|
||||
// Load default values
|
||||
var targetDefaults = {
|
||||
mode: c.MODE_METRICS,
|
||||
group: { filter: "" },
|
||||
host: { filter: "" },
|
||||
application: { filter: "" },
|
||||
item: { filter: "" },
|
||||
functions: [],
|
||||
options: {
|
||||
showDisabledItems: false
|
||||
'mode': c.MODE_METRICS,
|
||||
'group': { 'filter': "" },
|
||||
'host': { 'filter': "" },
|
||||
'application': { 'filter': "" },
|
||||
'item': { 'filter': "" },
|
||||
'functions': [],
|
||||
'options': {
|
||||
'showDisabledItems': false
|
||||
}
|
||||
};
|
||||
_.defaults(target, targetDefaults);
|
||||
@@ -141,13 +146,10 @@ System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils
|
||||
|
||||
if (target.mode === c.MODE_METRICS || target.mode === c.MODE_TEXT) {
|
||||
|
||||
this.downsampleFunctionList = [{ name: "avg", value: "avg" }, { name: "min", value: "min" }, { name: "max", value: "max" }, { name: "sum", value: "sum" }, { name: "count", value: "count" }];
|
||||
|
||||
this.initFilters();
|
||||
} else if (target.mode === c.MODE_ITSERVICE) {
|
||||
this.slaPropertyList = [{ name: "Status", property: "status" }, { name: "SLA", property: "sla" }, { name: "OK time", property: "okTime" }, { name: "Problem time", property: "problemTime" }, { name: "Down time", property: "downtimeTime" }];
|
||||
this.itserviceList = [{ name: "test" }];
|
||||
this.updateITServiceList();
|
||||
_.defaults(target, { slaProperty: { name: "SLA", property: "sla" } });
|
||||
this.suggestITServices();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -158,7 +160,8 @@ System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils
|
||||
_createClass(ZabbixQueryController, [{
|
||||
key: 'initFilters',
|
||||
value: function initFilters() {
|
||||
var itemtype = this.editorModes[this.target.mode].value;
|
||||
var itemtype = _.find(this.editorModes, { 'mode': this.target.mode });
|
||||
itemtype = itemtype ? itemtype.value : null;
|
||||
return Promise.all([this.suggestGroups(), this.suggestHosts(), this.suggestApps(), this.suggestItems(itemtype)]);
|
||||
}
|
||||
}, {
|
||||
@@ -177,6 +180,13 @@ System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils
|
||||
|
||||
return metrics;
|
||||
}
|
||||
}, {
|
||||
key: 'getTemplateVariables',
|
||||
value: function getTemplateVariables() {
|
||||
return _.map(this.templateSrv.variables, function (variable) {
|
||||
return '$' + variable.name;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'suggestGroups',
|
||||
value: function suggestGroups() {
|
||||
@@ -230,6 +240,16 @@ System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils
|
||||
return items;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'suggestITServices',
|
||||
value: function suggestITServices() {
|
||||
var _this6 = this;
|
||||
|
||||
return this.zabbix.getITService().then(function (itservices) {
|
||||
_this6.metric.itServiceList = itservices;
|
||||
return itservices;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'isRegex',
|
||||
value: function isRegex(str) {
|
||||
@@ -259,11 +279,11 @@ System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils
|
||||
}, {
|
||||
key: 'isContainsVariables',
|
||||
value: function isContainsVariables() {
|
||||
var _this6 = this;
|
||||
var _this7 = this;
|
||||
|
||||
return _.some(['group', 'host', 'application'], function (field) {
|
||||
if (_this6.target[field] && _this6.target[field].filter) {
|
||||
return utils.isTemplateVariable(_this6.target[field].filter, _this6.templateSrv.variables);
|
||||
if (_this7.target[field] && _this7.target[field].filter) {
|
||||
return utils.isTemplateVariable(_this7.target[field].filter, _this7.templateSrv.variables);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -356,24 +376,7 @@ System.register(['app/plugins/sdk', 'angular', 'lodash', './constants', './utils
|
||||
value: function switchEditorMode(mode) {
|
||||
this.target.mode = mode;
|
||||
this.init();
|
||||
}
|
||||
}, {
|
||||
key: 'updateITServiceList',
|
||||
value: function updateITServiceList() {
|
||||
var _this7 = this;
|
||||
|
||||
this.zabbix.getITService().then(function (iteservices) {
|
||||
_this7.itserviceList = [];
|
||||
_this7.itserviceList = _this7.itserviceList.concat(iteservices);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'selectITService',
|
||||
value: function selectITService() {
|
||||
if (!_.isEqual(this.oldTarget, this.target) && _.isEmpty(this.target.errors)) {
|
||||
this.oldTarget = angular.copy(this.target);
|
||||
this.panelCtrl.refresh();
|
||||
}
|
||||
this.targetChanged();
|
||||
}
|
||||
}]);
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -15,7 +15,10 @@ describe('ZabbixDatasource', () => {
|
||||
password: 'zabbix',
|
||||
trends: true,
|
||||
trendsFrom: '14d',
|
||||
trendsRange: '7d'
|
||||
trendsRange: '7d',
|
||||
dbConnection: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
};
|
||||
ctx.templateSrv = {};
|
||||
|
||||
50
dist/datasource-zabbix/specs/utils_specs.js
vendored
50
dist/datasource-zabbix/specs/utils_specs.js
vendored
@@ -88,4 +88,54 @@ describe('Utils', () => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('splitTemplateQuery()', () => {
|
||||
|
||||
// Backward compatibility
|
||||
it('should properly split query in old format', (done) => {
|
||||
let test_cases = [
|
||||
{
|
||||
query: `/alu/./tw-(nyc|que|brx|dwt|brk)-sta_(\w|\d)*-alu-[0-9{2}/`,
|
||||
expected: ['/alu/', '/tw-(nyc|que|brx|dwt|brk)-sta_(\w|\d)*-alu-[0-9{2}/']
|
||||
},
|
||||
{
|
||||
query: `a.b.c.d`,
|
||||
expected: ['a', 'b', 'c', 'd']
|
||||
}
|
||||
];
|
||||
|
||||
_.each(test_cases, test_case => {
|
||||
let splitQuery = utils.splitTemplateQuery(test_case.query);
|
||||
expect(splitQuery).to.eql(test_case.expected);
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
it('should properly split query', (done) => {
|
||||
let test_cases = [
|
||||
{
|
||||
query: `{alu}{/tw-(nyc|que|brx|dwt|brk)-sta_(\w|\d)*-alu-[0-9]*/}`,
|
||||
expected: ['alu', '/tw-(nyc|que|brx|dwt|brk)-sta_(\w|\d)*-alu-[0-9]*/']
|
||||
},
|
||||
{
|
||||
query: `{alu}{/tw-(nyc|que|brx|dwt|brk)-sta_(\w|\d)*-alu-[0-9]{2}/}`,
|
||||
expected: ['alu', '/tw-(nyc|que|brx|dwt|brk)-sta_(\w|\d)*-alu-[0-9]{2}/']
|
||||
},
|
||||
{
|
||||
query: `{a}{b}{c}{d}`,
|
||||
expected: ['a', 'b', 'c', 'd']
|
||||
},
|
||||
{
|
||||
query: `{a}{b.c.d}`,
|
||||
expected: ['a', 'b.c.d']
|
||||
}
|
||||
];
|
||||
|
||||
_.each(test_cases, test_case => {
|
||||
let splitQuery = utils.splitTemplateQuery(test_case.query);
|
||||
expect(splitQuery).to.eql(test_case.expected);
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
19
dist/datasource-zabbix/utils.js
vendored
19
dist/datasource-zabbix/utils.js
vendored
@@ -28,6 +28,16 @@ System.register(['lodash', 'moment'], function (_export, _context) {
|
||||
|
||||
_export('expandItemName', expandItemName);
|
||||
|
||||
function expandItems(items) {
|
||||
_.forEach(items, function (item) {
|
||||
item.item = item.name;
|
||||
item.name = expandItemName(item.item, item.key_);
|
||||
return item;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
_export('expandItems', expandItems);
|
||||
|
||||
function splitKeyParams(paramStr) {
|
||||
var params = [];
|
||||
var quoted = false;
|
||||
@@ -56,7 +66,9 @@ System.register(['lodash', 'moment'], function (_export, _context) {
|
||||
|
||||
params.push(param);
|
||||
return params;
|
||||
}function containsMacro(itemName) {
|
||||
}
|
||||
|
||||
function containsMacro(itemName) {
|
||||
return MACRO_PATTERN.test(itemName);
|
||||
}
|
||||
|
||||
@@ -99,7 +111,7 @@ System.register(['lodash', 'moment'], function (_export, _context) {
|
||||
* {group}{host.com} -> [group, host.com]
|
||||
*/
|
||||
function splitTemplateQuery(query) {
|
||||
var splitPattern = /{[^{}]*}/g;
|
||||
var splitPattern = /\{[^\{\}]*\}|\{\/.*\/\}/g;
|
||||
var split = void 0;
|
||||
|
||||
if (isContainsBraces(query)) {
|
||||
@@ -117,7 +129,8 @@ System.register(['lodash', 'moment'], function (_export, _context) {
|
||||
_export('splitTemplateQuery', splitTemplateQuery);
|
||||
|
||||
function isContainsBraces(query) {
|
||||
return query.includes('{') && query.includes('}');
|
||||
var bracesPattern = /^\{.+\}$/;
|
||||
return bracesPattern.test(query);
|
||||
}
|
||||
|
||||
// Pattern for testing regex
|
||||
|
||||
2
dist/datasource-zabbix/utils.js.map
vendored
2
dist/datasource-zabbix/utils.js.map
vendored
File diff suppressed because one or more lines are too long
36
dist/datasource-zabbix/zabbix.js
vendored
36
dist/datasource-zabbix/zabbix.js
vendored
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './zabbixCachingProxy.service.js'], function (_export, _context) {
|
||||
System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './zabbixCachingProxy.service.js', './zabbixDBConnector'], function (_export, _context) {
|
||||
"use strict";
|
||||
|
||||
var angular, _, utils, _createClass;
|
||||
@@ -27,25 +27,44 @@ System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './za
|
||||
// Each Zabbix data source instance should initialize its own API instance.
|
||||
|
||||
/** @ngInject */
|
||||
function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy) {
|
||||
function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector) {
|
||||
var Zabbix = function () {
|
||||
function Zabbix(url, username, password, basicAuth, withCredentials, cacheTTL) {
|
||||
function Zabbix(url, options) {
|
||||
_classCallCheck(this, Zabbix);
|
||||
|
||||
var username = options.username,
|
||||
password = options.password,
|
||||
basicAuth = options.basicAuth,
|
||||
withCredentials = options.withCredentials,
|
||||
cacheTTL = options.cacheTTL,
|
||||
enableDirectDBConnection = options.enableDirectDBConnection,
|
||||
sqlDatasourceId = options.sqlDatasourceId;
|
||||
|
||||
|
||||
// Initialize Zabbix API
|
||||
var ZabbixAPI = zabbixAPIService;
|
||||
this.zabbixAPI = new ZabbixAPI(url, username, password, basicAuth, withCredentials);
|
||||
|
||||
if (enableDirectDBConnection) {
|
||||
this.dbConnector = new ZabbixDBConnector(sqlDatasourceId);
|
||||
}
|
||||
|
||||
// Initialize caching proxy for requests
|
||||
var cacheOptions = {
|
||||
enabled: true,
|
||||
ttl: cacheTTL
|
||||
};
|
||||
this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, cacheOptions);
|
||||
this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, this.dbConnector, cacheOptions);
|
||||
|
||||
// Proxy methods
|
||||
this.getHistory = this.cachingProxy.getHistory.bind(this.cachingProxy);
|
||||
this.getMacros = this.cachingProxy.getMacros.bind(this.cachingProxy);
|
||||
this.getItemsByIDs = this.cachingProxy.getItemsByIDs.bind(this.cachingProxy);
|
||||
|
||||
if (enableDirectDBConnection) {
|
||||
this.getHistoryDB = this.cachingProxy.getHistoryDB.bind(this.cachingProxy);
|
||||
this.getTrendsDB = this.cachingProxy.getTrendsDB.bind(this.cachingProxy);
|
||||
}
|
||||
|
||||
this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI);
|
||||
this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI);
|
||||
@@ -168,6 +187,13 @@ System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './za
|
||||
return filterByQuery(items, itemFilter);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'getITServices',
|
||||
value: function getITServices(itServiceFilter) {
|
||||
return this.cachingProxy.getITServices().then(function (itServices) {
|
||||
return findByFilter(itServices, itServiceFilter);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'getTriggers',
|
||||
value: function getTriggers(groupFilter, hostFilter, appFilter, options) {
|
||||
@@ -274,7 +300,7 @@ System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './za
|
||||
_ = _lodash.default;
|
||||
}, function (_utils) {
|
||||
utils = _utils;
|
||||
}, function (_zabbixAPIServiceJs) {}, function (_zabbixCachingProxyServiceJs) {}],
|
||||
}, function (_zabbixAPIServiceJs) {}, function (_zabbixCachingProxyServiceJs) {}, function (_zabbixDBConnector) {}],
|
||||
execute: function () {
|
||||
_createClass = function () {
|
||||
function defineProperties(target, props) {
|
||||
|
||||
2
dist/datasource-zabbix/zabbix.js.map
vendored
2
dist/datasource-zabbix/zabbix.js.map
vendored
File diff suppressed because one or more lines are too long
21
dist/datasource-zabbix/zabbixAPI.service.js
vendored
21
dist/datasource-zabbix/zabbixAPI.service.js
vendored
@@ -166,16 +166,19 @@ System.register(['angular', 'lodash', './utils', './zabbixAPICore.service'], fun
|
||||
params.filter.value_type = [1, 2, 4];
|
||||
}
|
||||
|
||||
return this.request('item.get', params).then(expandItems);
|
||||
return this.request('item.get', params).then(utils.expandItems);
|
||||
}
|
||||
}, {
|
||||
key: 'getItemsByIDs',
|
||||
value: function getItemsByIDs(itemids) {
|
||||
var params = {
|
||||
itemids: itemids,
|
||||
output: ['name', 'key_', 'value_type', 'hostid', 'status', 'state'],
|
||||
webitems: true,
|
||||
selectHosts: ['hostid', 'name']
|
||||
};
|
||||
|
||||
function expandItems(items) {
|
||||
_.forEach(items, function (item) {
|
||||
item.item = item.name;
|
||||
item.name = utils.expandItemName(item.item, item.key_);
|
||||
return item;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
return this.request('item.get', params).then(utils.expandItems);
|
||||
}
|
||||
}, {
|
||||
key: 'getMacros',
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -29,10 +29,11 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
||||
/** @ngInject */
|
||||
function ZabbixCachingProxyFactory() {
|
||||
var ZabbixCachingProxy = function () {
|
||||
function ZabbixCachingProxy(zabbixAPI, cacheOptions) {
|
||||
function ZabbixCachingProxy(zabbixAPI, zabbixDBConnector, cacheOptions) {
|
||||
_classCallCheck(this, ZabbixCachingProxy);
|
||||
|
||||
this.zabbixAPI = zabbixAPI;
|
||||
this.dbConnector = zabbixDBConnector;
|
||||
this.cacheEnabled = cacheOptions.enabled;
|
||||
this.ttl = cacheOptions.ttl || 600000; // 10 minutes by default
|
||||
|
||||
@@ -45,7 +46,8 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
||||
history: {},
|
||||
trends: {},
|
||||
macros: {},
|
||||
globalMacros: {}
|
||||
globalMacros: {},
|
||||
itServices: {}
|
||||
};
|
||||
|
||||
this.historyPromises = {};
|
||||
@@ -53,6 +55,11 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
||||
// Don't run duplicated history requests
|
||||
this.getHistory = callAPIRequestOnce(_.bind(this.zabbixAPI.getHistory, this.zabbixAPI), this.historyPromises, getHistoryRequestHash);
|
||||
|
||||
if (this.dbConnector) {
|
||||
this.getHistoryDB = callAPIRequestOnce(_.bind(this.dbConnector.getHistory, this.dbConnector), this.historyPromises, getDBQueryHash);
|
||||
this.getTrendsDB = callAPIRequestOnce(_.bind(this.dbConnector.getTrends, this.dbConnector), this.historyPromises, getDBQueryHash);
|
||||
}
|
||||
|
||||
// Don't run duplicated requests
|
||||
this.groupPromises = {};
|
||||
this.getGroupsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getGroups, this.zabbixAPI), this.groupPromises, getRequestHash);
|
||||
@@ -66,6 +73,12 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
||||
this.itemPromises = {};
|
||||
this.getItemsOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getItems, this.zabbixAPI), this.itemPromises, getRequestHash);
|
||||
|
||||
this.itemByIdPromises = {};
|
||||
this.getItemsByIdOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getItemsByIDs, this.zabbixAPI), this.itemPromises, getRequestHash);
|
||||
|
||||
this.itServicesPromises = {};
|
||||
this.getITServicesOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getITService, this.zabbixAPI), this.itServicesPromises, getRequestHash);
|
||||
|
||||
this.macroPromises = {};
|
||||
this.getMacrosOnce = callAPIRequestOnce(_.bind(this.zabbixAPI.getMacros, this.zabbixAPI), this.macroPromises, getRequestHash);
|
||||
|
||||
@@ -120,6 +133,17 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
||||
var params = [hostids, appids, itemtype];
|
||||
return this.proxyRequest(this.getItemsOnce, params, this.cache.items);
|
||||
}
|
||||
}, {
|
||||
key: 'getItemsByIDs',
|
||||
value: function getItemsByIDs(itemids) {
|
||||
var params = [itemids];
|
||||
return this.proxyRequest(this.getItemsByIdOnce, params, this.cache.items);
|
||||
}
|
||||
}, {
|
||||
key: 'getITServices',
|
||||
value: function getITServices() {
|
||||
return this.proxyRequest(this.getITServicesOnce, [], this.cache.itServices);
|
||||
}
|
||||
}, {
|
||||
key: 'getMacros',
|
||||
value: function getMacros(hostids) {
|
||||
@@ -209,6 +233,14 @@ System.register(['angular', 'lodash'], function (_export, _context) {
|
||||
return stamp.getHash();
|
||||
}
|
||||
|
||||
function getDBQueryHash(args) {
|
||||
var itemids = _.map(args[0], 'itemid');
|
||||
var consolidateBy = args[3].consolidateBy;
|
||||
var intervalMs = args[3].intervalMs;
|
||||
var stamp = itemids.join() + args[1] + args[2] + consolidateBy + intervalMs;
|
||||
return stamp.getHash();
|
||||
}
|
||||
|
||||
return {
|
||||
setters: [function (_angular) {
|
||||
angular = _angular.default;
|
||||
|
||||
File diff suppressed because one or more lines are too long
233
dist/datasource-zabbix/zabbixDBConnector.js
vendored
Normal file
233
dist/datasource-zabbix/zabbixDBConnector.js
vendored
Normal file
@@ -0,0 +1,233 @@
|
||||
'use strict';
|
||||
|
||||
System.register(['angular', 'lodash'], function (_export, _context) {
|
||||
"use strict";
|
||||
|
||||
var angular, _, _createClass, DEFAULT_QUERY_LIMIT, HISTORY_TO_TABLE_MAP, TREND_TO_TABLE_MAP, consolidateByFunc, consolidateByTrendColumns;
|
||||
|
||||
function _classCallCheck(instance, Constructor) {
|
||||
if (!(instance instanceof Constructor)) {
|
||||
throw new TypeError("Cannot call a class as a function");
|
||||
}
|
||||
}
|
||||
|
||||
/** @ngInject */
|
||||
function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
||||
var ZabbixDBConnector = function () {
|
||||
function ZabbixDBConnector(sqlDataSourceId) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
_classCallCheck(this, ZabbixDBConnector);
|
||||
|
||||
var limit = options.limit;
|
||||
|
||||
|
||||
this.sqlDataSourceId = sqlDataSourceId;
|
||||
this.limit = limit || DEFAULT_QUERY_LIMIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to load DS with given id to check it's exist.
|
||||
* @param {*} datasourceId ID of SQL data source
|
||||
*/
|
||||
|
||||
|
||||
_createClass(ZabbixDBConnector, [{
|
||||
key: 'loadSQLDataSource',
|
||||
value: function loadSQLDataSource(datasourceId) {
|
||||
var ds = _.find(datasourceSrv.getAll(), { 'id': datasourceId });
|
||||
if (ds) {
|
||||
return datasourceSrv.loadDatasource(ds.name).then(function (ds) {
|
||||
console.log('SQL data source loaded', ds);
|
||||
});
|
||||
} else {
|
||||
return Promise.reject('SQL Data Source with ID ' + datasourceId + ' not found');
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: 'testSQLDataSource',
|
||||
value: function testSQLDataSource() {
|
||||
var testQuery = 'SELECT itemid AS metric, clock AS time_sec, value_avg AS value FROM trends_uint LIMIT 1';
|
||||
return this.invokeSQLQuery(testQuery);
|
||||
}
|
||||
}, {
|
||||
key: 'getHistory',
|
||||
value: function getHistory(items, timeFrom, timeTill, options) {
|
||||
var _this = this;
|
||||
|
||||
var intervalMs = options.intervalMs,
|
||||
consolidateBy = options.consolidateBy;
|
||||
|
||||
var intervalSec = Math.ceil(intervalMs / 1000);
|
||||
|
||||
consolidateBy = consolidateBy || 'avg';
|
||||
var aggFunction = consolidateByFunc[consolidateBy];
|
||||
|
||||
// Group items by value type and perform request for each value type
|
||||
var grouped_items = _.groupBy(items, 'value_type');
|
||||
var promises = _.map(grouped_items, function (items, value_type) {
|
||||
var itemids = _.map(items, 'itemid').join(', ');
|
||||
var table = HISTORY_TO_TABLE_MAP[value_type];
|
||||
|
||||
var query = '\n SELECT itemid AS metric, clock 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_sec DIV ' + intervalSec + ', metric\n ';
|
||||
|
||||
query = compactSQLQuery(query);
|
||||
return _this.invokeSQLQuery(query);
|
||||
});
|
||||
|
||||
return Promise.all(promises).then(function (results) {
|
||||
return _.flatten(results);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'getTrends',
|
||||
value: function getTrends(items, timeFrom, timeTill, options) {
|
||||
var _this2 = this;
|
||||
|
||||
var intervalMs = options.intervalMs,
|
||||
consolidateBy = options.consolidateBy;
|
||||
|
||||
var intervalSec = Math.ceil(intervalMs / 1000);
|
||||
|
||||
consolidateBy = consolidateBy || 'avg';
|
||||
var aggFunction = consolidateByFunc[consolidateBy];
|
||||
|
||||
// Group items by value type and perform request for each value type
|
||||
var grouped_items = _.groupBy(items, 'value_type');
|
||||
var promises = _.map(grouped_items, function (items, value_type) {
|
||||
var itemids = _.map(items, 'itemid').join(', ');
|
||||
var table = TREND_TO_TABLE_MAP[value_type];
|
||||
var valueColumn = _.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg';
|
||||
valueColumn = consolidateByTrendColumns[valueColumn];
|
||||
|
||||
var query = '\n SELECT itemid AS metric, clock 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_sec DIV ' + intervalSec + ', metric\n ';
|
||||
|
||||
query = compactSQLQuery(query);
|
||||
return _this2.invokeSQLQuery(query);
|
||||
});
|
||||
|
||||
return Promise.all(promises).then(function (results) {
|
||||
return _.flatten(results);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'handleGrafanaTSResponse',
|
||||
value: function handleGrafanaTSResponse(history, items) {
|
||||
var addHostName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
||||
|
||||
return convertGrafanaTSResponse(history, items, addHostName);
|
||||
}
|
||||
}, {
|
||||
key: 'invokeSQLQuery',
|
||||
value: function invokeSQLQuery(query) {
|
||||
var queryDef = {
|
||||
refId: 'A',
|
||||
format: 'time_series',
|
||||
datasourceId: this.sqlDataSourceId,
|
||||
rawSql: query,
|
||||
maxDataPoints: this.limit
|
||||
};
|
||||
|
||||
return backendSrv.datasourceRequest({
|
||||
url: '/api/tsdb/query',
|
||||
method: 'POST',
|
||||
data: {
|
||||
queries: [queryDef]
|
||||
}
|
||||
}).then(function (response) {
|
||||
var results = response.data.results;
|
||||
if (results['A']) {
|
||||
return results['A'].series;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return ZabbixDBConnector;
|
||||
}();
|
||||
|
||||
return ZabbixDBConnector;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function convertGrafanaTSResponse(time_series, items, addHostName) {
|
||||
var hosts = _.uniqBy(_.flatten(_.map(items, 'hosts')), 'hostid'); //uniqBy is needed to deduplicate
|
||||
var grafanaSeries = _.map(time_series, function (series) {
|
||||
var itemid = series.name;
|
||||
var datapoints = series.points;
|
||||
var item = _.find(items, { 'itemid': itemid });
|
||||
var alias = item.name;
|
||||
if (_.keys(hosts).length > 1 && addHostName) {
|
||||
//only when actual multi hosts selected
|
||||
var host = _.find(hosts, { 'hostid': item.hostid });
|
||||
alias = host.name + ": " + alias;
|
||||
}
|
||||
return {
|
||||
target: alias,
|
||||
datapoints: datapoints
|
||||
};
|
||||
});
|
||||
|
||||
return _.sortBy(grafanaSeries, 'target');
|
||||
}
|
||||
|
||||
function compactSQLQuery(query) {
|
||||
return query.replace(/\s+/g, ' ');
|
||||
}
|
||||
return {
|
||||
setters: [function (_angular) {
|
||||
angular = _angular.default;
|
||||
}, function (_lodash) {
|
||||
_ = _lodash.default;
|
||||
}],
|
||||
execute: function () {
|
||||
_createClass = function () {
|
||||
function defineProperties(target, props) {
|
||||
for (var i = 0; i < props.length; i++) {
|
||||
var descriptor = props[i];
|
||||
descriptor.enumerable = descriptor.enumerable || false;
|
||||
descriptor.configurable = true;
|
||||
if ("value" in descriptor) descriptor.writable = true;
|
||||
Object.defineProperty(target, descriptor.key, descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
return function (Constructor, protoProps, staticProps) {
|
||||
if (protoProps) defineProperties(Constructor.prototype, protoProps);
|
||||
if (staticProps) defineProperties(Constructor, staticProps);
|
||||
return Constructor;
|
||||
};
|
||||
}();
|
||||
|
||||
DEFAULT_QUERY_LIMIT = 10000;
|
||||
HISTORY_TO_TABLE_MAP = {
|
||||
'0': 'history',
|
||||
'1': 'history_str',
|
||||
'2': 'history_log',
|
||||
'3': 'history_uint',
|
||||
'4': 'history_text'
|
||||
};
|
||||
TREND_TO_TABLE_MAP = {
|
||||
'0': 'trends',
|
||||
'3': 'trends_uint'
|
||||
};
|
||||
consolidateByFunc = {
|
||||
'avg': 'AVG',
|
||||
'min': 'MIN',
|
||||
'max': 'MAX',
|
||||
'sum': 'SUM',
|
||||
'count': 'COUNT'
|
||||
};
|
||||
consolidateByTrendColumns = {
|
||||
'avg': 'value_avg',
|
||||
'min': 'value_min',
|
||||
'max': 'value_max'
|
||||
};
|
||||
angular.module('grafana.services').factory('ZabbixDBConnector', ZabbixDBConnectorFactory);
|
||||
}
|
||||
};
|
||||
});
|
||||
//# sourceMappingURL=zabbixDBConnector.js.map
|
||||
1
dist/datasource-zabbix/zabbixDBConnector.js.map
vendored
Normal file
1
dist/datasource-zabbix/zabbixDBConnector.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
4
dist/panel-triggers/editor.html
vendored
4
dist/panel-triggers/editor.html
vendored
@@ -55,6 +55,10 @@
|
||||
placeholder="trigger name"
|
||||
class="gf-form-input"
|
||||
ng-style="editor.panel.triggers.trigger.style"
|
||||
ng-class="{
|
||||
'zbx-variable': editor.isVariable(editor.panel.triggers.trigger.filter),
|
||||
'zbx-regex': editor.isRegex(editor.panel.triggers.trigger.filter)
|
||||
}"
|
||||
empty-to-null>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
10
dist/panel-triggers/module.js
vendored
10
dist/panel-triggers/module.js
vendored
@@ -206,6 +206,7 @@ System.register(['lodash', 'jquery', 'moment', 'app/plugins/sdk', '../datasource
|
||||
return this.datasourceSrv.get(this.panel.datasource).then(function (datasource) {
|
||||
var zabbix = datasource.zabbix;
|
||||
_this3.zabbix = zabbix;
|
||||
_this3.datasource = datasource;
|
||||
var showEvents = _this3.panel.showEvents.value;
|
||||
var triggerFilter = _this3.panel.triggers;
|
||||
var hideHostsInMaintenance = _this3.panel.hideHostsInMaintenance;
|
||||
@@ -219,10 +220,10 @@ System.register(['lodash', 'jquery', 'moment', 'app/plugins/sdk', '../datasource
|
||||
showTriggers: showEvents,
|
||||
hideHostsInMaintenance: hideHostsInMaintenance
|
||||
};
|
||||
var getTriggers = zabbix.getTriggers(groupFilter, hostFilter, appFilter, triggersOptions);
|
||||
return getTriggers.then(function (triggers) {
|
||||
return _.map(triggers, _this3.formatTrigger.bind(_this3));
|
||||
});
|
||||
|
||||
return zabbix.getTriggers(groupFilter, hostFilter, appFilter, triggersOptions);
|
||||
}).then(function (triggers) {
|
||||
return _.map(triggers, _this3.formatTrigger.bind(_this3));
|
||||
});
|
||||
}
|
||||
}, {
|
||||
@@ -272,6 +273,7 @@ System.register(['lodash', 'jquery', 'moment', 'app/plugins/sdk', '../datasource
|
||||
|
||||
// Filter triggers by description
|
||||
var triggerFilter = this.panel.triggers.trigger.filter;
|
||||
triggerFilter = this.datasource.replaceTemplateVars(triggerFilter);
|
||||
if (triggerFilter) {
|
||||
triggerList = _filterTriggers(triggerList, triggerFilter);
|
||||
}
|
||||
|
||||
2
dist/panel-triggers/module.js.map
vendored
2
dist/panel-triggers/module.js.map
vendored
File diff suppressed because one or more lines are too long
4
dist/plugin.json
vendored
4
dist/plugin.json
vendored
@@ -26,8 +26,8 @@
|
||||
{"name": "Metric Editor", "path": "img/screenshot-metric_editor.png"},
|
||||
{"name": "Triggers", "path": "img/screenshot-triggers.png"}
|
||||
],
|
||||
"version": "3.4.0",
|
||||
"updated": "2017-05-17"
|
||||
"version": "3.5.1",
|
||||
"updated": "2017-07-10"
|
||||
},
|
||||
|
||||
"includes": [
|
||||
|
||||
50
dist/test/datasource-zabbix/config.controller.js
vendored
Normal file
50
dist/test/datasource-zabbix/config.controller.js
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
'use strict';
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.ZabbixDSConfigController = undefined;
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
var _lodash = require('lodash');
|
||||
|
||||
var _lodash2 = _interopRequireDefault(_lodash);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var SUPPORTED_SQL_DS = ['mysql'];
|
||||
|
||||
var defaultConfig = {
|
||||
dbConnection: {
|
||||
enable: false
|
||||
}
|
||||
};
|
||||
|
||||
var ZabbixDSConfigController = exports.ZabbixDSConfigController = function () {
|
||||
/** @ngInject */
|
||||
function ZabbixDSConfigController($scope, $injector, datasourceSrv) {
|
||||
_classCallCheck(this, ZabbixDSConfigController);
|
||||
|
||||
this.datasourceSrv = datasourceSrv;
|
||||
|
||||
_lodash2.default.defaults(this.current.jsonData, defaultConfig);
|
||||
this.sqlDataSources = this.getSupportedSQLDataSources();
|
||||
}
|
||||
|
||||
_createClass(ZabbixDSConfigController, [{
|
||||
key: 'getSupportedSQLDataSources',
|
||||
value: function getSupportedSQLDataSources() {
|
||||
var datasources = this.datasourceSrv.getAll();
|
||||
return _lodash2.default.filter(datasources, function (ds) {
|
||||
return _lodash2.default.includes(SUPPORTED_SQL_DS, ds.type);
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return ZabbixDSConfigController;
|
||||
}();
|
||||
|
||||
ZabbixDSConfigController.templateUrl = 'datasource-zabbix/partials/config.html';
|
||||
3
dist/test/datasource-zabbix/constants.js
vendored
3
dist/test/datasource-zabbix/constants.js
vendored
@@ -5,8 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
||||
});
|
||||
// Editor modes
|
||||
var MODE_METRICS = exports.MODE_METRICS = 0;
|
||||
var MODE_TEXT = exports.MODE_TEXT = 2;
|
||||
var MODE_ITSERVICE = exports.MODE_ITSERVICE = 1;
|
||||
var MODE_TEXT = exports.MODE_TEXT = 2;
|
||||
var MODE_ITEMID = exports.MODE_ITEMID = 3;
|
||||
|
||||
// Triggers severity
|
||||
var SEV_NOT_CLASSIFIED = exports.SEV_NOT_CLASSIFIED = 0;
|
||||
|
||||
253
dist/test/datasource-zabbix/datasource.js
vendored
253
dist/test/datasource-zabbix/datasource.js
vendored
@@ -64,6 +64,9 @@ var ZabbixAPIDatasource = function () {
|
||||
this.dashboardSrv = dashboardSrv;
|
||||
this.zabbixAlertingSrv = zabbixAlertingSrv;
|
||||
|
||||
// Use custom format for template variables
|
||||
this.replaceTemplateVars = _lodash2.default.partial(replaceTemplateVars, this.templateSrv);
|
||||
|
||||
// General data source settings
|
||||
this.name = instanceSettings.name;
|
||||
this.url = instanceSettings.url;
|
||||
@@ -88,10 +91,21 @@ var ZabbixAPIDatasource = function () {
|
||||
this.addThresholds = instanceSettings.jsonData.addThresholds;
|
||||
this.alertingMinSeverity = instanceSettings.jsonData.alertingMinSeverity || c.SEV_WARNING;
|
||||
|
||||
this.zabbix = new Zabbix(this.url, this.username, this.password, this.basicAuth, this.withCredentials, this.cacheTTL);
|
||||
// Direct DB Connection options
|
||||
this.enableDirectDBConnection = instanceSettings.jsonData.dbConnection.enable;
|
||||
this.sqlDatasourceId = instanceSettings.jsonData.dbConnection.datasourceId;
|
||||
|
||||
// Use custom format for template variables
|
||||
this.replaceTemplateVars = _lodash2.default.partial(replaceTemplateVars, this.templateSrv);
|
||||
var zabbixOptions = {
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
basicAuth: this.basicAuth,
|
||||
withCredentials: this.withCredentials,
|
||||
cacheTTL: this.cacheTTL,
|
||||
enableDirectDBConnection: this.enableDirectDBConnection,
|
||||
sqlDatasourceId: this.sqlDatasourceId
|
||||
};
|
||||
|
||||
this.zabbix = new Zabbix(this.url, zabbixOptions);
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
@@ -126,6 +140,11 @@ var ZabbixAPIDatasource = function () {
|
||||
|
||||
// Create request for each target
|
||||
var promises = _lodash2.default.map(options.targets, function (t) {
|
||||
// Don't request undefined and hidden targets
|
||||
if (t.hide) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var timeFrom = Math.ceil(dateMath.parse(options.range.from) / 1000);
|
||||
var timeTo = Math.ceil(dateMath.parse(options.range.to) / 1000);
|
||||
|
||||
@@ -149,7 +168,7 @@ var ZabbixAPIDatasource = function () {
|
||||
var useTrends = _this.isUseTrends(timeRange);
|
||||
|
||||
// Metrics or Text query mode
|
||||
if (target.mode !== c.MODE_ITSERVICE) {
|
||||
if (target.mode === c.MODE_METRICS || target.mode === c.MODE_TEXT || target.mode === c.MODE_ITEMID) {
|
||||
// Migrate old targets
|
||||
target = migrations.migrate(target);
|
||||
|
||||
@@ -162,20 +181,13 @@ var ZabbixAPIDatasource = function () {
|
||||
return _this.queryNumericData(target, timeRange, useTrends, options);
|
||||
} else if (target.mode === c.MODE_TEXT) {
|
||||
return _this.queryTextData(target, timeRange);
|
||||
} else if (target.mode === c.MODE_ITEMID) {
|
||||
return _this.queryItemIdData(target, timeRange, useTrends, options);
|
||||
}
|
||||
} else if (target.mode === c.MODE_ITSERVICE) {
|
||||
// IT services mode
|
||||
return _this.queryITServiceData(target, timeRange, options);
|
||||
}
|
||||
|
||||
// IT services mode
|
||||
else if (target.mode === c.MODE_ITSERVICE) {
|
||||
// Don't show undefined and hidden targets
|
||||
if (target.hide || !target.itservice || !target.slaProperty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return _this.zabbix.getSLA(target.itservice.serviceid, timeRange).then(function (slaObject) {
|
||||
return _responseHandler2.default.handleSLAResponse(target.itservice, target.slaProperty, slaObject);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Data for panel (all targets)
|
||||
@@ -183,24 +195,48 @@ var ZabbixAPIDatasource = function () {
|
||||
return { data: data };
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Query target data for Metrics mode
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'queryNumericData',
|
||||
value: function queryNumericData(target, timeRange, useTrends, options) {
|
||||
var _this2 = this;
|
||||
|
||||
var _timeRange = _slicedToArray(timeRange, 2),
|
||||
timeFrom = _timeRange[0],
|
||||
timeTo = _timeRange[1];
|
||||
|
||||
var getItemOptions = {
|
||||
itemtype: 'num'
|
||||
};
|
||||
return this.zabbix.getItemsFromTarget(target, getItemOptions).then(function (items) {
|
||||
var getHistoryPromise = void 0;
|
||||
return _this2.queryNumericDataForItems(items, target, timeRange, useTrends, options);
|
||||
});
|
||||
}
|
||||
|
||||
if (useTrends) {
|
||||
var valueType = _this2.getTrendValueType(target);
|
||||
getHistoryPromise = _this2.zabbix.getTrend(items, timeFrom, timeTo).then(function (history) {
|
||||
/**
|
||||
* Query history for numeric items
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'queryNumericDataForItems',
|
||||
value: function queryNumericDataForItems(items, target, timeRange, useTrends, options) {
|
||||
var _this3 = this;
|
||||
|
||||
var _timeRange = _slicedToArray(timeRange, 2),
|
||||
timeFrom = _timeRange[0],
|
||||
timeTo = _timeRange[1];
|
||||
|
||||
var getHistoryPromise = void 0;
|
||||
options.consolidateBy = getConsolidateBy(target);
|
||||
|
||||
if (useTrends) {
|
||||
if (this.enableDirectDBConnection) {
|
||||
getHistoryPromise = this.zabbix.getTrendsDB(items, timeFrom, timeTo, options).then(function (history) {
|
||||
return _this3.zabbix.dbConnector.handleGrafanaTSResponse(history, items);
|
||||
});
|
||||
} else {
|
||||
var valueType = this.getTrendValueType(target);
|
||||
getHistoryPromise = this.zabbix.getTrend(items, timeFrom, timeTo).then(function (history) {
|
||||
return _responseHandler2.default.handleTrends(history, items, valueType);
|
||||
}).then(function (timeseries) {
|
||||
// Sort trend data, issue #202
|
||||
@@ -209,19 +245,24 @@ var ZabbixAPIDatasource = function () {
|
||||
return point[c.DATAPOINT_TS];
|
||||
});
|
||||
});
|
||||
|
||||
return timeseries;
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Use history
|
||||
if (this.enableDirectDBConnection) {
|
||||
getHistoryPromise = this.zabbix.getHistoryDB(items, timeFrom, timeTo, options).then(function (history) {
|
||||
return _this3.zabbix.dbConnector.handleGrafanaTSResponse(history, items);
|
||||
});
|
||||
} else {
|
||||
// Use history
|
||||
getHistoryPromise = _this2.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) {
|
||||
getHistoryPromise = this.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) {
|
||||
return _responseHandler2.default.handleHistory(history, items);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return getHistoryPromise;
|
||||
}).then(function (timeseries) {
|
||||
return _this2.applyDataProcessingFunctions(timeseries, target);
|
||||
return getHistoryPromise.then(function (timeseries) {
|
||||
return _this3.applyDataProcessingFunctions(timeseries, target);
|
||||
}).then(function (timeseries) {
|
||||
return downsampleSeries(timeseries, options);
|
||||
}).catch(function (error) {
|
||||
@@ -297,10 +338,15 @@ var ZabbixAPIDatasource = function () {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Query target data for Text mode
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'queryTextData',
|
||||
value: function queryTextData(target, timeRange) {
|
||||
var _this3 = this;
|
||||
var _this4 = this;
|
||||
|
||||
var _timeRange2 = _slicedToArray(timeRange, 2),
|
||||
timeFrom = _timeRange2[0],
|
||||
@@ -311,7 +357,7 @@ var ZabbixAPIDatasource = function () {
|
||||
};
|
||||
return this.zabbix.getItemsFromTarget(target, options).then(function (items) {
|
||||
if (items.length) {
|
||||
return _this3.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) {
|
||||
return _this4.zabbix.getHistory(items, timeFrom, timeTo).then(function (history) {
|
||||
return _responseHandler2.default.handleText(history, items, target);
|
||||
});
|
||||
} else {
|
||||
@@ -320,6 +366,74 @@ var ZabbixAPIDatasource = function () {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Query target data for Item ID mode
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'queryItemIdData',
|
||||
value: function queryItemIdData(target, timeRange, useTrends, options) {
|
||||
var _this5 = this;
|
||||
|
||||
var itemids = target.itemids;
|
||||
itemids = this.templateSrv.replace(itemids, options.scopedVars, zabbixItemIdsTemplateFormat);
|
||||
itemids = _lodash2.default.map(itemids.split(','), function (itemid) {
|
||||
return itemid.trim();
|
||||
});
|
||||
|
||||
if (!itemids) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.zabbix.getItemsByIDs(itemids).then(function (items) {
|
||||
return _this5.queryNumericDataForItems(items, target, timeRange, useTrends, options);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Query target data for IT Services mode
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'queryITServiceData',
|
||||
value: function queryITServiceData(target, timeRange, options) {
|
||||
var _this6 = this;
|
||||
|
||||
// Don't show undefined and hidden targets
|
||||
if (target.hide || !target.itservice && !target.itServiceFilter || !target.slaProperty) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var itServiceIds = [];
|
||||
var itServices = [];
|
||||
var itServiceFilter = void 0;
|
||||
var isOldVersion = target.itservice && !target.itServiceFilter;
|
||||
|
||||
if (isOldVersion) {
|
||||
// Backward compatibility
|
||||
itServiceFilter = '/.*/';
|
||||
} else {
|
||||
itServiceFilter = this.replaceTemplateVars(target.itServiceFilter, options.scopedVars);
|
||||
}
|
||||
|
||||
return this.zabbix.getITServices(itServiceFilter).then(function (itservices) {
|
||||
itServices = itservices;
|
||||
if (isOldVersion) {
|
||||
itServices = _lodash2.default.filter(itServices, { 'serviceid': target.itservice.serviceid });
|
||||
}
|
||||
|
||||
itServiceIds = _lodash2.default.map(itServices, 'serviceid');
|
||||
return itServiceIds;
|
||||
}).then(function (serviceids) {
|
||||
return _this6.zabbix.getSLA(serviceids, timeRange);
|
||||
}).then(function (slaResponse) {
|
||||
return _lodash2.default.map(itServiceIds, function (serviceid) {
|
||||
var itservice = _lodash2.default.find(itServices, { 'serviceid': serviceid });
|
||||
return _responseHandler2.default.handleSLAResponse(itservice, target.slaProperty, slaResponse);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Test connection to Zabbix API
|
||||
* @return {object} Connection status and Zabbix API version
|
||||
@@ -328,12 +442,18 @@ var ZabbixAPIDatasource = function () {
|
||||
}, {
|
||||
key: 'testDatasource',
|
||||
value: function testDatasource() {
|
||||
var _this4 = this;
|
||||
var _this7 = this;
|
||||
|
||||
var zabbixVersion = void 0;
|
||||
return this.zabbix.getVersion().then(function (version) {
|
||||
zabbixVersion = version;
|
||||
return _this4.zabbix.login();
|
||||
return _this7.zabbix.login();
|
||||
}).then(function () {
|
||||
if (_this7.enableDirectDBConnection) {
|
||||
return _this7.zabbix.dbConnector.testSQLDataSource();
|
||||
} else {
|
||||
return Promise.resolve();
|
||||
}
|
||||
}).then(function () {
|
||||
return {
|
||||
status: "success",
|
||||
@@ -347,6 +467,12 @@ var ZabbixAPIDatasource = function () {
|
||||
title: error.message,
|
||||
message: error.data
|
||||
};
|
||||
} else if (error.data && error.data.message) {
|
||||
return {
|
||||
status: "error",
|
||||
title: "Connection failed",
|
||||
message: error.data.message
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
status: "error",
|
||||
@@ -372,14 +498,14 @@ var ZabbixAPIDatasource = function () {
|
||||
}, {
|
||||
key: 'metricFindQuery',
|
||||
value: function metricFindQuery(query) {
|
||||
var _this5 = this;
|
||||
var _this8 = this;
|
||||
|
||||
var result = void 0;
|
||||
var parts = [];
|
||||
|
||||
// Split query. Query structure: group.host.app.item
|
||||
_lodash2.default.each(utils.splitTemplateQuery(query), function (part) {
|
||||
part = _this5.replaceTemplateVars(part, {});
|
||||
part = _this8.replaceTemplateVars(part, {});
|
||||
|
||||
// Replace wildcard to regex
|
||||
if (part === '*') {
|
||||
@@ -421,7 +547,7 @@ var ZabbixAPIDatasource = function () {
|
||||
}, {
|
||||
key: 'annotationQuery',
|
||||
value: function annotationQuery(options) {
|
||||
var _this6 = this;
|
||||
var _this9 = this;
|
||||
|
||||
var timeFrom = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);
|
||||
var timeTo = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);
|
||||
@@ -439,13 +565,14 @@ var ZabbixAPIDatasource = function () {
|
||||
return getTriggers.then(function (triggers) {
|
||||
|
||||
// Filter triggers by description
|
||||
if (utils.isRegex(annotation.trigger)) {
|
||||
var triggerName = _this9.replaceTemplateVars(annotation.trigger, {});
|
||||
if (utils.isRegex(triggerName)) {
|
||||
triggers = _lodash2.default.filter(triggers, function (trigger) {
|
||||
return utils.buildRegex(annotation.trigger).test(trigger.description);
|
||||
return utils.buildRegex(triggerName).test(trigger.description);
|
||||
});
|
||||
} else if (annotation.trigger) {
|
||||
} else if (triggerName) {
|
||||
triggers = _lodash2.default.filter(triggers, function (trigger) {
|
||||
return trigger.description === annotation.trigger;
|
||||
return trigger.description === triggerName;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -455,7 +582,7 @@ var ZabbixAPIDatasource = function () {
|
||||
});
|
||||
|
||||
var objectids = _lodash2.default.map(triggers, 'triggerid');
|
||||
return _this6.zabbix.getEvents(objectids, timeFrom, timeTo, showOkEvents).then(function (events) {
|
||||
return _this9.zabbix.getEvents(objectids, timeFrom, timeTo, showOkEvents).then(function (events) {
|
||||
var indexedTriggers = _lodash2.default.keyBy(triggers, 'triggerid');
|
||||
|
||||
// Hide acknowledged events if option enabled
|
||||
@@ -496,21 +623,23 @@ var ZabbixAPIDatasource = function () {
|
||||
}, {
|
||||
key: 'alertQuery',
|
||||
value: function alertQuery(options) {
|
||||
var _this7 = this;
|
||||
var _this10 = this;
|
||||
|
||||
var enabled_targets = filterEnabledTargets(options.targets);
|
||||
var getPanelItems = _lodash2.default.map(enabled_targets, function (target) {
|
||||
return _this7.zabbix.getItemsFromTarget(target, { itemtype: 'num' });
|
||||
var getPanelItems = _lodash2.default.map(enabled_targets, function (t) {
|
||||
var target = _lodash2.default.cloneDeep(t);
|
||||
_this10.replaceTargetVariables(target, options);
|
||||
return _this10.zabbix.getItemsFromTarget(target, { itemtype: 'num' });
|
||||
});
|
||||
|
||||
return Promise.all(getPanelItems).then(function (results) {
|
||||
var items = _lodash2.default.flatten(results);
|
||||
var itemids = _lodash2.default.map(items, 'itemid');
|
||||
|
||||
return _this7.zabbix.getAlerts(itemids);
|
||||
return _this10.zabbix.getAlerts(itemids);
|
||||
}).then(function (triggers) {
|
||||
triggers = _lodash2.default.filter(triggers, function (trigger) {
|
||||
return trigger.priority >= _this7.alertingMinSeverity;
|
||||
return trigger.priority >= _this10.alertingMinSeverity;
|
||||
});
|
||||
|
||||
if (!triggers || triggers.length === 0) {
|
||||
@@ -541,12 +670,12 @@ var ZabbixAPIDatasource = function () {
|
||||
}, {
|
||||
key: 'replaceTargetVariables',
|
||||
value: function replaceTargetVariables(target, options) {
|
||||
var _this8 = this;
|
||||
var _this11 = this;
|
||||
|
||||
var parts = ['group', 'host', 'application', 'item'];
|
||||
_lodash2.default.forEach(parts, function (p) {
|
||||
if (target[p] && target[p].filter) {
|
||||
target[p].filter = _this8.replaceTemplateVars(target[p].filter, options.scopedVars);
|
||||
target[p].filter = _this11.replaceTemplateVars(target[p].filter, options.scopedVars);
|
||||
}
|
||||
});
|
||||
target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars);
|
||||
@@ -554,9 +683,9 @@ var ZabbixAPIDatasource = function () {
|
||||
_lodash2.default.forEach(target.functions, function (func) {
|
||||
func.params = _lodash2.default.map(func.params, function (param) {
|
||||
if (typeof param === 'number') {
|
||||
return +_this8.templateSrv.replace(param.toString(), options.scopedVars);
|
||||
return +_this11.templateSrv.replace(param.toString(), options.scopedVars);
|
||||
} else {
|
||||
return _this8.templateSrv.replace(param, options.scopedVars);
|
||||
return _this11.templateSrv.replace(param, options.scopedVars);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -590,10 +719,23 @@ function bindFunctionDefs(functionDefs, category) {
|
||||
});
|
||||
}
|
||||
|
||||
function getConsolidateBy(target) {
|
||||
var consolidateBy = 'avg';
|
||||
var funcDef = _lodash2.default.find(target.functions, function (func) {
|
||||
return func.def.name === 'consolidateBy';
|
||||
});
|
||||
if (funcDef && funcDef.params && funcDef.params.length) {
|
||||
consolidateBy = funcDef.params[0];
|
||||
}
|
||||
return consolidateBy;
|
||||
}
|
||||
|
||||
function downsampleSeries(timeseries_data, options) {
|
||||
var defaultAgg = _dataProcessor2.default.aggregationFunctions['avg'];
|
||||
var consolidateByFunc = _dataProcessor2.default.aggregationFunctions[options.consolidateBy] || defaultAgg;
|
||||
return _lodash2.default.map(timeseries_data, function (timeseries) {
|
||||
if (timeseries.datapoints.length > options.maxDataPoints) {
|
||||
timeseries.datapoints = _dataProcessor2.default.groupBy(options.interval, _dataProcessor2.default.AVERAGE, timeseries.datapoints);
|
||||
timeseries.datapoints = _dataProcessor2.default.groupBy(options.interval, consolidateByFunc, timeseries.datapoints);
|
||||
}
|
||||
return timeseries;
|
||||
});
|
||||
@@ -625,6 +767,13 @@ function zabbixTemplateFormat(value) {
|
||||
return '(' + escapedValues.join('|') + ')';
|
||||
}
|
||||
|
||||
function zabbixItemIdsTemplateFormat(value) {
|
||||
if (typeof value === 'string') {
|
||||
return value;
|
||||
}
|
||||
return value.join(',');
|
||||
}
|
||||
|
||||
/**
|
||||
* If template variables are used in request, replace it using regex format
|
||||
* and wrap with '/' for proper multi-value work. Example:
|
||||
|
||||
10
dist/test/datasource-zabbix/module.js
vendored
10
dist/test/datasource-zabbix/module.js
vendored
@@ -9,14 +9,10 @@ var _datasource = require('./datasource');
|
||||
|
||||
var _query = require('./query.controller');
|
||||
|
||||
var _config = require('./config.controller');
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var ZabbixConfigController = function ZabbixConfigController() {
|
||||
_classCallCheck(this, ZabbixConfigController);
|
||||
};
|
||||
|
||||
ZabbixConfigController.templateUrl = 'datasource-zabbix/partials/config.html';
|
||||
|
||||
var ZabbixQueryOptionsController = function ZabbixQueryOptionsController() {
|
||||
_classCallCheck(this, ZabbixQueryOptionsController);
|
||||
};
|
||||
@@ -30,7 +26,7 @@ var ZabbixAnnotationsQueryController = function ZabbixAnnotationsQueryController
|
||||
ZabbixAnnotationsQueryController.templateUrl = 'datasource-zabbix/partials/annotations.editor.html';
|
||||
|
||||
exports.Datasource = _datasource.ZabbixAPIDatasource;
|
||||
exports.ConfigCtrl = ZabbixConfigController;
|
||||
exports.ConfigCtrl = _config.ZabbixDSConfigController;
|
||||
exports.QueryCtrl = _query.ZabbixQueryController;
|
||||
exports.QueryOptionsCtrl = ZabbixQueryOptionsController;
|
||||
exports.AnnotationsQueryCtrl = ZabbixAnnotationsQueryController;
|
||||
|
||||
101
dist/test/datasource-zabbix/query.controller.js
vendored
101
dist/test/datasource-zabbix/query.controller.js
vendored
@@ -9,10 +9,6 @@ var _createClass = function () { function defineProperties(target, props) { for
|
||||
|
||||
var _sdk = require('app/plugins/sdk');
|
||||
|
||||
var _angular = require('angular');
|
||||
|
||||
var _angular2 = _interopRequireDefault(_angular);
|
||||
|
||||
var _lodash = require('lodash');
|
||||
|
||||
var _lodash2 = _interopRequireDefault(_lodash);
|
||||
@@ -64,17 +60,24 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
|
||||
_this.replaceTemplateVars = _this.datasource.replaceTemplateVars;
|
||||
_this.templateSrv = templateSrv;
|
||||
|
||||
_this.editorModes = {
|
||||
0: { value: 'num', text: 'Metrics', mode: c.MODE_METRICS },
|
||||
1: { value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE },
|
||||
2: { value: 'text', text: 'Text', mode: c.MODE_TEXT }
|
||||
_this.editorModes = [{ value: 'num', text: 'Metrics', mode: c.MODE_METRICS }, { value: 'text', text: 'Text', mode: c.MODE_TEXT }, { value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE }, { value: 'itemid', text: 'Item ID', mode: c.MODE_ITEMID }];
|
||||
|
||||
_this.$scope.editorMode = {
|
||||
METRICS: c.MODE_METRICS,
|
||||
TEXT: c.MODE_TEXT,
|
||||
ITSERVICE: c.MODE_ITSERVICE,
|
||||
ITEMID: c.MODE_ITEMID
|
||||
};
|
||||
|
||||
_this.slaPropertyList = [{ name: "Status", property: "status" }, { name: "SLA", property: "sla" }, { name: "OK time", property: "okTime" }, { name: "Problem time", property: "problemTime" }, { name: "Down time", property: "downtimeTime" }];
|
||||
|
||||
// Map functions for bs-typeahead
|
||||
_this.getGroupNames = _lodash2.default.bind(_this.getMetricNames, _this, 'groupList');
|
||||
_this.getHostNames = _lodash2.default.bind(_this.getMetricNames, _this, 'hostList', true);
|
||||
_this.getApplicationNames = _lodash2.default.bind(_this.getMetricNames, _this, 'appList');
|
||||
_this.getItemNames = _lodash2.default.bind(_this.getMetricNames, _this, 'itemList');
|
||||
_this.getITServices = _lodash2.default.bind(_this.getMetricNames, _this, 'itServiceList');
|
||||
_this.getVariables = _lodash2.default.bind(_this.getTemplateVariables, _this);
|
||||
|
||||
// Update metric suggestion when template variable was changed
|
||||
$rootScope.$on('template-variable-value-updated', function () {
|
||||
@@ -101,14 +104,14 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
|
||||
|
||||
// Load default values
|
||||
var targetDefaults = {
|
||||
mode: c.MODE_METRICS,
|
||||
group: { filter: "" },
|
||||
host: { filter: "" },
|
||||
application: { filter: "" },
|
||||
item: { filter: "" },
|
||||
functions: [],
|
||||
options: {
|
||||
showDisabledItems: false
|
||||
'mode': c.MODE_METRICS,
|
||||
'group': { 'filter': "" },
|
||||
'host': { 'filter': "" },
|
||||
'application': { 'filter': "" },
|
||||
'item': { 'filter': "" },
|
||||
'functions': [],
|
||||
'options': {
|
||||
'showDisabledItems': false
|
||||
}
|
||||
};
|
||||
_lodash2.default.defaults(target, targetDefaults);
|
||||
@@ -120,13 +123,10 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
|
||||
|
||||
if (target.mode === c.MODE_METRICS || target.mode === c.MODE_TEXT) {
|
||||
|
||||
this.downsampleFunctionList = [{ name: "avg", value: "avg" }, { name: "min", value: "min" }, { name: "max", value: "max" }, { name: "sum", value: "sum" }, { name: "count", value: "count" }];
|
||||
|
||||
this.initFilters();
|
||||
} else if (target.mode === c.MODE_ITSERVICE) {
|
||||
this.slaPropertyList = [{ name: "Status", property: "status" }, { name: "SLA", property: "sla" }, { name: "OK time", property: "okTime" }, { name: "Problem time", property: "problemTime" }, { name: "Down time", property: "downtimeTime" }];
|
||||
this.itserviceList = [{ name: "test" }];
|
||||
this.updateITServiceList();
|
||||
_lodash2.default.defaults(target, { slaProperty: { name: "SLA", property: "sla" } });
|
||||
this.suggestITServices();
|
||||
}
|
||||
};
|
||||
|
||||
@@ -137,7 +137,8 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
|
||||
_createClass(ZabbixQueryController, [{
|
||||
key: 'initFilters',
|
||||
value: function initFilters() {
|
||||
var itemtype = this.editorModes[this.target.mode].value;
|
||||
var itemtype = _lodash2.default.find(this.editorModes, { 'mode': this.target.mode });
|
||||
itemtype = itemtype ? itemtype.value : null;
|
||||
return Promise.all([this.suggestGroups(), this.suggestHosts(), this.suggestApps(), this.suggestItems(itemtype)]);
|
||||
}
|
||||
|
||||
@@ -159,6 +160,13 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
|
||||
|
||||
return metrics;
|
||||
}
|
||||
}, {
|
||||
key: 'getTemplateVariables',
|
||||
value: function getTemplateVariables() {
|
||||
return _lodash2.default.map(this.templateSrv.variables, function (variable) {
|
||||
return '$' + variable.name;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'suggestGroups',
|
||||
value: function suggestGroups() {
|
||||
@@ -212,6 +220,16 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
|
||||
return items;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'suggestITServices',
|
||||
value: function suggestITServices() {
|
||||
var _this6 = this;
|
||||
|
||||
return this.zabbix.getITService().then(function (itservices) {
|
||||
_this6.metric.itServiceList = itservices;
|
||||
return itservices;
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'isRegex',
|
||||
value: function isRegex(str) {
|
||||
@@ -246,11 +264,11 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
|
||||
}, {
|
||||
key: 'isContainsVariables',
|
||||
value: function isContainsVariables() {
|
||||
var _this6 = this;
|
||||
var _this7 = this;
|
||||
|
||||
return _lodash2.default.some(['group', 'host', 'application'], function (field) {
|
||||
if (_this6.target[field] && _this6.target[field].filter) {
|
||||
return utils.isTemplateVariable(_this6.target[field].filter, _this6.templateSrv.variables);
|
||||
if (_this7.target[field] && _this7.target[field].filter) {
|
||||
return utils.isTemplateVariable(_this7.target[field].filter, _this7.templateSrv.variables);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -352,38 +370,7 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
|
||||
value: function switchEditorMode(mode) {
|
||||
this.target.mode = mode;
|
||||
this.init();
|
||||
}
|
||||
|
||||
/////////////////
|
||||
// IT Services //
|
||||
/////////////////
|
||||
|
||||
/**
|
||||
* Update list of IT services
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'updateITServiceList',
|
||||
value: function updateITServiceList() {
|
||||
var _this7 = this;
|
||||
|
||||
this.zabbix.getITService().then(function (iteservices) {
|
||||
_this7.itserviceList = [];
|
||||
_this7.itserviceList = _this7.itserviceList.concat(iteservices);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when IT service is selected.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'selectITService',
|
||||
value: function selectITService() {
|
||||
if (!_lodash2.default.isEqual(this.oldTarget, this.target) && _lodash2.default.isEmpty(this.target.errors)) {
|
||||
this.oldTarget = _angular2.default.copy(this.target);
|
||||
this.panelCtrl.refresh();
|
||||
}
|
||||
this.targetChanged();
|
||||
}
|
||||
}]);
|
||||
|
||||
|
||||
@@ -29,7 +29,10 @@ describe('ZabbixDatasource', function () {
|
||||
password: 'zabbix',
|
||||
trends: true,
|
||||
trendsFrom: '14d',
|
||||
trendsRange: '7d'
|
||||
trendsRange: '7d',
|
||||
dbConnection: {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
};
|
||||
ctx.templateSrv = {};
|
||||
|
||||
42
dist/test/datasource-zabbix/specs/utils_specs.js
vendored
42
dist/test/datasource-zabbix/specs/utils_specs.js
vendored
@@ -86,4 +86,46 @@ describe('Utils', function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('splitTemplateQuery()', function () {
|
||||
|
||||
// Backward compatibility
|
||||
it('should properly split query in old format', function (done) {
|
||||
var test_cases = [{
|
||||
query: '/alu/./tw-(nyc|que|brx|dwt|brk)-sta_(w|d)*-alu-[0-9{2}/',
|
||||
expected: ['/alu/', '/tw-(nyc|que|brx|dwt|brk)-sta_(\w|\d)*-alu-[0-9{2}/']
|
||||
}, {
|
||||
query: 'a.b.c.d',
|
||||
expected: ['a', 'b', 'c', 'd']
|
||||
}];
|
||||
|
||||
_lodash2.default.each(test_cases, function (test_case) {
|
||||
var splitQuery = utils.splitTemplateQuery(test_case.query);
|
||||
expect(splitQuery).to.eql(test_case.expected);
|
||||
});
|
||||
done();
|
||||
});
|
||||
|
||||
it('should properly split query', function (done) {
|
||||
var test_cases = [{
|
||||
query: '{alu}{/tw-(nyc|que|brx|dwt|brk)-sta_(w|d)*-alu-[0-9]*/}',
|
||||
expected: ['alu', '/tw-(nyc|que|brx|dwt|brk)-sta_(\w|\d)*-alu-[0-9]*/']
|
||||
}, {
|
||||
query: '{alu}{/tw-(nyc|que|brx|dwt|brk)-sta_(w|d)*-alu-[0-9]{2}/}',
|
||||
expected: ['alu', '/tw-(nyc|que|brx|dwt|brk)-sta_(\w|\d)*-alu-[0-9]{2}/']
|
||||
}, {
|
||||
query: '{a}{b}{c}{d}',
|
||||
expected: ['a', 'b', 'c', 'd']
|
||||
}, {
|
||||
query: '{a}{b.c.d}',
|
||||
expected: ['a', 'b.c.d']
|
||||
}];
|
||||
|
||||
_lodash2.default.each(test_cases, function (test_case) {
|
||||
var splitQuery = utils.splitTemplateQuery(test_case.query);
|
||||
expect(splitQuery).to.eql(test_case.expected);
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
15
dist/test/datasource-zabbix/utils.js
vendored
15
dist/test/datasource-zabbix/utils.js
vendored
@@ -5,6 +5,7 @@ Object.defineProperty(exports, "__esModule", {
|
||||
});
|
||||
exports.regexPattern = undefined;
|
||||
exports.expandItemName = expandItemName;
|
||||
exports.expandItems = expandItems;
|
||||
exports.containsMacro = containsMacro;
|
||||
exports.replaceMacro = replaceMacro;
|
||||
exports.splitTemplateQuery = splitTemplateQuery;
|
||||
@@ -49,6 +50,15 @@ function expandItemName(name, key) {
|
||||
return name;
|
||||
}
|
||||
|
||||
function expandItems(items) {
|
||||
_lodash2.default.forEach(items, function (item) {
|
||||
item.item = item.name;
|
||||
item.name = expandItemName(item.item, item.key_);
|
||||
return item;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
|
||||
function splitKeyParams(paramStr) {
|
||||
var params = [];
|
||||
var quoted = false;
|
||||
@@ -120,7 +130,7 @@ function escapeMacro(macro) {
|
||||
* {group}{host.com} -> [group, host.com]
|
||||
*/
|
||||
function splitTemplateQuery(query) {
|
||||
var splitPattern = /{[^{}]*}/g;
|
||||
var splitPattern = /\{[^\{\}]*\}|\{\/.*\/\}/g;
|
||||
var split = void 0;
|
||||
|
||||
if (isContainsBraces(query)) {
|
||||
@@ -136,7 +146,8 @@ function splitTemplateQuery(query) {
|
||||
}
|
||||
|
||||
function isContainsBraces(query) {
|
||||
return query.includes('{') && query.includes('}');
|
||||
var bracesPattern = /^\{.+\}$/;
|
||||
return bracesPattern.test(query);
|
||||
}
|
||||
|
||||
// Pattern for testing regex
|
||||
|
||||
34
dist/test/datasource-zabbix/zabbix.js
vendored
34
dist/test/datasource-zabbix/zabbix.js
vendored
@@ -18,6 +18,8 @@ require('./zabbixAPI.service.js');
|
||||
|
||||
require('./zabbixCachingProxy.service.js');
|
||||
|
||||
require('./zabbixDBConnector');
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
@@ -30,25 +32,44 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
|
||||
// Each Zabbix data source instance should initialize its own API instance.
|
||||
|
||||
/** @ngInject */
|
||||
function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy) {
|
||||
function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector) {
|
||||
var Zabbix = function () {
|
||||
function Zabbix(url, username, password, basicAuth, withCredentials, cacheTTL) {
|
||||
function Zabbix(url, options) {
|
||||
_classCallCheck(this, Zabbix);
|
||||
|
||||
var username = options.username,
|
||||
password = options.password,
|
||||
basicAuth = options.basicAuth,
|
||||
withCredentials = options.withCredentials,
|
||||
cacheTTL = options.cacheTTL,
|
||||
enableDirectDBConnection = options.enableDirectDBConnection,
|
||||
sqlDatasourceId = options.sqlDatasourceId;
|
||||
|
||||
// Initialize Zabbix API
|
||||
|
||||
var ZabbixAPI = zabbixAPIService;
|
||||
this.zabbixAPI = new ZabbixAPI(url, username, password, basicAuth, withCredentials);
|
||||
|
||||
if (enableDirectDBConnection) {
|
||||
this.dbConnector = new ZabbixDBConnector(sqlDatasourceId);
|
||||
}
|
||||
|
||||
// Initialize caching proxy for requests
|
||||
var cacheOptions = {
|
||||
enabled: true,
|
||||
ttl: cacheTTL
|
||||
};
|
||||
this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, cacheOptions);
|
||||
this.cachingProxy = new ZabbixCachingProxy(this.zabbixAPI, this.dbConnector, cacheOptions);
|
||||
|
||||
// Proxy methods
|
||||
this.getHistory = this.cachingProxy.getHistory.bind(this.cachingProxy);
|
||||
this.getMacros = this.cachingProxy.getMacros.bind(this.cachingProxy);
|
||||
this.getItemsByIDs = this.cachingProxy.getItemsByIDs.bind(this.cachingProxy);
|
||||
|
||||
if (enableDirectDBConnection) {
|
||||
this.getHistoryDB = this.cachingProxy.getHistoryDB.bind(this.cachingProxy);
|
||||
this.getTrendsDB = this.cachingProxy.getTrendsDB.bind(this.cachingProxy);
|
||||
}
|
||||
|
||||
this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI);
|
||||
this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI);
|
||||
@@ -181,6 +202,13 @@ function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy) {
|
||||
return filterByQuery(items, itemFilter);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'getITServices',
|
||||
value: function getITServices(itServiceFilter) {
|
||||
return this.cachingProxy.getITServices().then(function (itServices) {
|
||||
return findByFilter(itServices, itServiceFilter);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Build query - convert target filters to array of Zabbix items
|
||||
|
||||
21
dist/test/datasource-zabbix/zabbixAPI.service.js
vendored
21
dist/test/datasource-zabbix/zabbixAPI.service.js
vendored
@@ -217,16 +217,19 @@ function ZabbixAPIServiceFactory(alertSrv, zabbixAPICoreService) {
|
||||
params.filter.value_type = [1, 2, 4];
|
||||
}
|
||||
|
||||
return this.request('item.get', params).then(expandItems);
|
||||
return this.request('item.get', params).then(utils.expandItems);
|
||||
}
|
||||
}, {
|
||||
key: 'getItemsByIDs',
|
||||
value: function getItemsByIDs(itemids) {
|
||||
var params = {
|
||||
itemids: itemids,
|
||||
output: ['name', 'key_', 'value_type', 'hostid', 'status', 'state'],
|
||||
webitems: true,
|
||||
selectHosts: ['hostid', 'name']
|
||||
};
|
||||
|
||||
function expandItems(items) {
|
||||
_lodash2.default.forEach(items, function (item) {
|
||||
item.item = item.name;
|
||||
item.name = utils.expandItemName(item.item, item.key_);
|
||||
return item;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
return this.request('item.get', params).then(utils.expandItems);
|
||||
}
|
||||
}, {
|
||||
key: 'getMacros',
|
||||
|
||||
@@ -22,10 +22,11 @@ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Cons
|
||||
/** @ngInject */
|
||||
function ZabbixCachingProxyFactory() {
|
||||
var ZabbixCachingProxy = function () {
|
||||
function ZabbixCachingProxy(zabbixAPI, cacheOptions) {
|
||||
function ZabbixCachingProxy(zabbixAPI, zabbixDBConnector, cacheOptions) {
|
||||
_classCallCheck(this, ZabbixCachingProxy);
|
||||
|
||||
this.zabbixAPI = zabbixAPI;
|
||||
this.dbConnector = zabbixDBConnector;
|
||||
this.cacheEnabled = cacheOptions.enabled;
|
||||
this.ttl = cacheOptions.ttl || 600000; // 10 minutes by default
|
||||
|
||||
@@ -38,7 +39,8 @@ function ZabbixCachingProxyFactory() {
|
||||
history: {},
|
||||
trends: {},
|
||||
macros: {},
|
||||
globalMacros: {}
|
||||
globalMacros: {},
|
||||
itServices: {}
|
||||
};
|
||||
|
||||
this.historyPromises = {};
|
||||
@@ -46,6 +48,11 @@ function ZabbixCachingProxyFactory() {
|
||||
// Don't run duplicated history requests
|
||||
this.getHistory = callAPIRequestOnce(_lodash2.default.bind(this.zabbixAPI.getHistory, this.zabbixAPI), this.historyPromises, getHistoryRequestHash);
|
||||
|
||||
if (this.dbConnector) {
|
||||
this.getHistoryDB = callAPIRequestOnce(_lodash2.default.bind(this.dbConnector.getHistory, this.dbConnector), this.historyPromises, getDBQueryHash);
|
||||
this.getTrendsDB = callAPIRequestOnce(_lodash2.default.bind(this.dbConnector.getTrends, this.dbConnector), this.historyPromises, getDBQueryHash);
|
||||
}
|
||||
|
||||
// Don't run duplicated requests
|
||||
this.groupPromises = {};
|
||||
this.getGroupsOnce = callAPIRequestOnce(_lodash2.default.bind(this.zabbixAPI.getGroups, this.zabbixAPI), this.groupPromises, getRequestHash);
|
||||
@@ -59,6 +66,12 @@ function ZabbixCachingProxyFactory() {
|
||||
this.itemPromises = {};
|
||||
this.getItemsOnce = callAPIRequestOnce(_lodash2.default.bind(this.zabbixAPI.getItems, this.zabbixAPI), this.itemPromises, getRequestHash);
|
||||
|
||||
this.itemByIdPromises = {};
|
||||
this.getItemsByIdOnce = callAPIRequestOnce(_lodash2.default.bind(this.zabbixAPI.getItemsByIDs, this.zabbixAPI), this.itemPromises, getRequestHash);
|
||||
|
||||
this.itServicesPromises = {};
|
||||
this.getITServicesOnce = callAPIRequestOnce(_lodash2.default.bind(this.zabbixAPI.getITService, this.zabbixAPI), this.itServicesPromises, getRequestHash);
|
||||
|
||||
this.macroPromises = {};
|
||||
this.getMacrosOnce = callAPIRequestOnce(_lodash2.default.bind(this.zabbixAPI.getMacros, this.zabbixAPI), this.macroPromises, getRequestHash);
|
||||
|
||||
@@ -119,6 +132,17 @@ function ZabbixCachingProxyFactory() {
|
||||
var params = [hostids, appids, itemtype];
|
||||
return this.proxyRequest(this.getItemsOnce, params, this.cache.items);
|
||||
}
|
||||
}, {
|
||||
key: 'getItemsByIDs',
|
||||
value: function getItemsByIDs(itemids) {
|
||||
var params = [itemids];
|
||||
return this.proxyRequest(this.getItemsByIdOnce, params, this.cache.items);
|
||||
}
|
||||
}, {
|
||||
key: 'getITServices',
|
||||
value: function getITServices() {
|
||||
return this.proxyRequest(this.getITServicesOnce, [], this.cache.itServices);
|
||||
}
|
||||
}, {
|
||||
key: 'getMacros',
|
||||
value: function getMacros(hostids) {
|
||||
@@ -210,6 +234,14 @@ function getHistoryRequestHash(args) {
|
||||
return stamp.getHash();
|
||||
}
|
||||
|
||||
function getDBQueryHash(args) {
|
||||
var itemids = _lodash2.default.map(args[0], 'itemid');
|
||||
var consolidateBy = args[3].consolidateBy;
|
||||
var intervalMs = args[3].intervalMs;
|
||||
var stamp = itemids.join() + args[1] + args[2] + consolidateBy + intervalMs;
|
||||
return stamp.getHash();
|
||||
}
|
||||
|
||||
String.prototype.getHash = function () {
|
||||
var hash = 0,
|
||||
i,
|
||||
|
||||
217
dist/test/datasource-zabbix/zabbixDBConnector.js
vendored
Normal file
217
dist/test/datasource-zabbix/zabbixDBConnector.js
vendored
Normal file
@@ -0,0 +1,217 @@
|
||||
'use strict';
|
||||
|
||||
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
|
||||
|
||||
var _angular = require('angular');
|
||||
|
||||
var _angular2 = _interopRequireDefault(_angular);
|
||||
|
||||
var _lodash = require('lodash');
|
||||
|
||||
var _lodash2 = _interopRequireDefault(_lodash);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
|
||||
|
||||
var DEFAULT_QUERY_LIMIT = 10000;
|
||||
var HISTORY_TO_TABLE_MAP = {
|
||||
'0': 'history',
|
||||
'1': 'history_str',
|
||||
'2': 'history_log',
|
||||
'3': 'history_uint',
|
||||
'4': 'history_text'
|
||||
};
|
||||
|
||||
var TREND_TO_TABLE_MAP = {
|
||||
'0': 'trends',
|
||||
'3': 'trends_uint'
|
||||
};
|
||||
|
||||
var consolidateByFunc = {
|
||||
'avg': 'AVG',
|
||||
'min': 'MIN',
|
||||
'max': 'MAX',
|
||||
'sum': 'SUM',
|
||||
'count': 'COUNT'
|
||||
};
|
||||
|
||||
var consolidateByTrendColumns = {
|
||||
'avg': 'value_avg',
|
||||
'min': 'value_min',
|
||||
'max': 'value_max'
|
||||
};
|
||||
|
||||
/** @ngInject */
|
||||
function ZabbixDBConnectorFactory(datasourceSrv, backendSrv) {
|
||||
var ZabbixDBConnector = function () {
|
||||
function ZabbixDBConnector(sqlDataSourceId) {
|
||||
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
||||
|
||||
_classCallCheck(this, ZabbixDBConnector);
|
||||
|
||||
var limit = options.limit;
|
||||
|
||||
|
||||
this.sqlDataSourceId = sqlDataSourceId;
|
||||
this.limit = limit || DEFAULT_QUERY_LIMIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to load DS with given id to check it's exist.
|
||||
* @param {*} datasourceId ID of SQL data source
|
||||
*/
|
||||
|
||||
|
||||
_createClass(ZabbixDBConnector, [{
|
||||
key: 'loadSQLDataSource',
|
||||
value: function loadSQLDataSource(datasourceId) {
|
||||
var ds = _lodash2.default.find(datasourceSrv.getAll(), { 'id': datasourceId });
|
||||
if (ds) {
|
||||
return datasourceSrv.loadDatasource(ds.name).then(function (ds) {
|
||||
console.log('SQL data source loaded', ds);
|
||||
});
|
||||
} else {
|
||||
return Promise.reject('SQL Data Source with ID ' + datasourceId + ' not found');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to invoke test query for one of Zabbix database tables.
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'testSQLDataSource',
|
||||
value: function testSQLDataSource() {
|
||||
var testQuery = 'SELECT itemid AS metric, clock AS time_sec, value_avg AS value FROM trends_uint LIMIT 1';
|
||||
return this.invokeSQLQuery(testQuery);
|
||||
}
|
||||
}, {
|
||||
key: 'getHistory',
|
||||
value: function getHistory(items, timeFrom, timeTill, options) {
|
||||
var _this = this;
|
||||
|
||||
var intervalMs = options.intervalMs,
|
||||
consolidateBy = options.consolidateBy;
|
||||
|
||||
var intervalSec = Math.ceil(intervalMs / 1000);
|
||||
|
||||
consolidateBy = consolidateBy || 'avg';
|
||||
var aggFunction = consolidateByFunc[consolidateBy];
|
||||
|
||||
// Group items by value type and perform request for each value type
|
||||
var grouped_items = _lodash2.default.groupBy(items, 'value_type');
|
||||
var promises = _lodash2.default.map(grouped_items, function (items, value_type) {
|
||||
var itemids = _lodash2.default.map(items, 'itemid').join(', ');
|
||||
var table = HISTORY_TO_TABLE_MAP[value_type];
|
||||
|
||||
var query = '\n SELECT itemid AS metric, clock 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_sec DIV ' + intervalSec + ', metric\n ';
|
||||
|
||||
query = compactSQLQuery(query);
|
||||
return _this.invokeSQLQuery(query);
|
||||
});
|
||||
|
||||
return Promise.all(promises).then(function (results) {
|
||||
return _lodash2.default.flatten(results);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'getTrends',
|
||||
value: function getTrends(items, timeFrom, timeTill, options) {
|
||||
var _this2 = this;
|
||||
|
||||
var intervalMs = options.intervalMs,
|
||||
consolidateBy = options.consolidateBy;
|
||||
|
||||
var intervalSec = Math.ceil(intervalMs / 1000);
|
||||
|
||||
consolidateBy = consolidateBy || 'avg';
|
||||
var aggFunction = consolidateByFunc[consolidateBy];
|
||||
|
||||
// Group items by value type and perform request for each value type
|
||||
var grouped_items = _lodash2.default.groupBy(items, 'value_type');
|
||||
var promises = _lodash2.default.map(grouped_items, function (items, value_type) {
|
||||
var itemids = _lodash2.default.map(items, 'itemid').join(', ');
|
||||
var table = TREND_TO_TABLE_MAP[value_type];
|
||||
var valueColumn = _lodash2.default.includes(['avg', 'min', 'max'], consolidateBy) ? consolidateBy : 'avg';
|
||||
valueColumn = consolidateByTrendColumns[valueColumn];
|
||||
|
||||
var query = '\n SELECT itemid AS metric, clock 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_sec DIV ' + intervalSec + ', metric\n ';
|
||||
|
||||
query = compactSQLQuery(query);
|
||||
return _this2.invokeSQLQuery(query);
|
||||
});
|
||||
|
||||
return Promise.all(promises).then(function (results) {
|
||||
return _lodash2.default.flatten(results);
|
||||
});
|
||||
}
|
||||
}, {
|
||||
key: 'handleGrafanaTSResponse',
|
||||
value: function handleGrafanaTSResponse(history, items) {
|
||||
var addHostName = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;
|
||||
|
||||
return convertGrafanaTSResponse(history, items, addHostName);
|
||||
}
|
||||
}, {
|
||||
key: 'invokeSQLQuery',
|
||||
value: function invokeSQLQuery(query) {
|
||||
var queryDef = {
|
||||
refId: 'A',
|
||||
format: 'time_series',
|
||||
datasourceId: this.sqlDataSourceId,
|
||||
rawSql: query,
|
||||
maxDataPoints: this.limit
|
||||
};
|
||||
|
||||
return backendSrv.datasourceRequest({
|
||||
url: '/api/tsdb/query',
|
||||
method: 'POST',
|
||||
data: {
|
||||
queries: [queryDef]
|
||||
}
|
||||
}).then(function (response) {
|
||||
var results = response.data.results;
|
||||
if (results['A']) {
|
||||
return results['A'].series;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}]);
|
||||
|
||||
return ZabbixDBConnector;
|
||||
}();
|
||||
|
||||
return ZabbixDBConnector;
|
||||
}
|
||||
|
||||
_angular2.default.module('grafana.services').factory('ZabbixDBConnector', ZabbixDBConnectorFactory);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function convertGrafanaTSResponse(time_series, items, addHostName) {
|
||||
var hosts = _lodash2.default.uniqBy(_lodash2.default.flatten(_lodash2.default.map(items, 'hosts')), 'hostid'); //uniqBy is needed to deduplicate
|
||||
var grafanaSeries = _lodash2.default.map(time_series, function (series) {
|
||||
var itemid = series.name;
|
||||
var datapoints = series.points;
|
||||
var item = _lodash2.default.find(items, { 'itemid': itemid });
|
||||
var alias = item.name;
|
||||
if (_lodash2.default.keys(hosts).length > 1 && addHostName) {
|
||||
//only when actual multi hosts selected
|
||||
var host = _lodash2.default.find(hosts, { 'hostid': item.hostid });
|
||||
alias = host.name + ": " + alias;
|
||||
}
|
||||
return {
|
||||
target: alias,
|
||||
datapoints: datapoints
|
||||
};
|
||||
});
|
||||
|
||||
return _lodash2.default.sortBy(grafanaSeries, 'target');
|
||||
}
|
||||
|
||||
function compactSQLQuery(query) {
|
||||
return query.replace(/\s+/g, ' ');
|
||||
}
|
||||
10
dist/test/panel-triggers/module.js
vendored
10
dist/test/panel-triggers/module.js
vendored
@@ -165,6 +165,7 @@ var TriggerPanelCtrl = function (_PanelCtrl) {
|
||||
return this.datasourceSrv.get(this.panel.datasource).then(function (datasource) {
|
||||
var zabbix = datasource.zabbix;
|
||||
_this3.zabbix = zabbix;
|
||||
_this3.datasource = datasource;
|
||||
var showEvents = _this3.panel.showEvents.value;
|
||||
var triggerFilter = _this3.panel.triggers;
|
||||
var hideHostsInMaintenance = _this3.panel.hideHostsInMaintenance;
|
||||
@@ -178,10 +179,10 @@ var TriggerPanelCtrl = function (_PanelCtrl) {
|
||||
showTriggers: showEvents,
|
||||
hideHostsInMaintenance: hideHostsInMaintenance
|
||||
};
|
||||
var getTriggers = zabbix.getTriggers(groupFilter, hostFilter, appFilter, triggersOptions);
|
||||
return getTriggers.then(function (triggers) {
|
||||
return _lodash2.default.map(triggers, _this3.formatTrigger.bind(_this3));
|
||||
});
|
||||
|
||||
return zabbix.getTriggers(groupFilter, hostFilter, appFilter, triggersOptions);
|
||||
}).then(function (triggers) {
|
||||
return _lodash2.default.map(triggers, _this3.formatTrigger.bind(_this3));
|
||||
});
|
||||
}
|
||||
}, {
|
||||
@@ -231,6 +232,7 @@ var TriggerPanelCtrl = function (_PanelCtrl) {
|
||||
|
||||
// Filter triggers by description
|
||||
var triggerFilter = this.panel.triggers.trigger.filter;
|
||||
triggerFilter = this.datasource.replaceTemplateVars(triggerFilter);
|
||||
if (triggerFilter) {
|
||||
triggerList = _filterTriggers(triggerList, triggerFilter);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user