From 1f6ecd5aed202f3cc91d7c3d9f43efcce733e8c7 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Tue, 18 Aug 2015 23:24:15 +0300 Subject: [PATCH] iss #71 - Implemented text metrics query. --- zabbix/datasource.js | 168 +++++++++++++++++++++---------------- zabbix/queryCtrl.js | 5 +- zabbix/zabbixAPIWrapper.js | 12 ++- 3 files changed, 105 insertions(+), 80 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 9fdb34d..5fa61b4 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -94,7 +94,7 @@ function (angular, _, kbn) { // Create request for each target var promises = _.map(options.targets, function(target) { - if (!target.mode || target.mode === 0) { + if (target.mode !== 1) { // Don't show undefined and hidden targets if (target.hide || !target.group || !target.host || !target.application || !target.item) { @@ -119,86 +119,111 @@ function (angular, _, kbn) { var delete_hostname_pattern = /(?:\[[\w\.]+]:\s)/g; var itemnames = zabbixHelperSrv.splitMetrics(itemname.replace(delete_hostname_pattern, '')); - // Find items by item names and perform queries var self = this; - return this.zabbixAPI.itemFindQuery(groups, hosts, apps) - .then(function (items) { - // Filter hosts by regex - if (target.host.visible_name === 'All') { - if (target.hostFilter && _.every(items, _.identity.hosts)) { + // Query numeric data + if (!target.mode) { - // Use templated variables in filter - var host_pattern = new RegExp(templateSrv.replace(target.hostFilter, options.scopedVars)); - items = _.filter(items, function (item) { - return _.some(item.hosts, function (host) { - return host_pattern.test(host.name); + // Find items by item names and perform queries + return this.zabbixAPI.itemFindQuery(groups, hosts, apps) + .then(function (items) { + + // Filter hosts by regex + if (target.host.visible_name === 'All') { + if (target.hostFilter && _.every(items, _.identity.hosts)) { + + // Use templated variables in filter + var host_pattern = new RegExp(templateSrv.replace(target.hostFilter, options.scopedVars)); + items = _.filter(items, function (item) { + return _.some(item.hosts, function (host) { + return host_pattern.test(host.name); + }); }); - }); + } } - } - if (itemnames[0] === 'All') { + if (itemnames[0] === 'All') { - // Filter items by regex - if (target.itemFilter) { + // Filter items by regex + if (target.itemFilter) { - // Use templated variables in filter - var item_pattern = new RegExp(templateSrv.replace(target.itemFilter, options.scopedVars)); - return _.filter(items, function (item) { - return item_pattern.test(zabbixHelperSrv.expandItemName(item)); - }); + // Use templated variables in filter + var item_pattern = new RegExp(templateSrv.replace(target.itemFilter, options.scopedVars)); + return _.filter(items, function (item) { + return item_pattern.test(zabbixHelperSrv.expandItemName(item)); + }); + } else { + return items; + } } else { - return items; - } - } else { - // Filtering items - return _.filter(items, function (item) { + // Filtering items + return _.filter(items, function (item) { + return _.contains(itemnames, zabbixHelperSrv.expandItemName(item)); + }); + } + }).then(function (items) { + + // Don't perform query for high number of items + // to prevent Grafana slowdown + if (items.length > self.limitmetrics) { + var message = "Try to increase limitmetrics parameter in datasource config.
" + + "Current limitmetrics value is " + self.limitmetrics; + alertSrv.set("Metrics limit exceeded", message, "warning", 10000); + return []; + } else { + items = _.flatten(items); + + // Use alias only for single metric, otherwise use item names + var alias = target.item.name === 'All' || itemnames.length > 1 ? + undefined : templateSrv.replace(target.alias, options.scopedVars); + + var history; + if ((from < useTrendsFrom) && self.trends) { + var points = target.downsampleFunction ? target.downsampleFunction.value : "avg"; + history = self.zabbixAPI.getTrends(items, from, to) + .then(_.bind(zabbixHelperSrv.handleTrendResponse, zabbixHelperSrv, items, alias, target.scale, points)); + } else { + history = self.zabbixAPI.getHistory(items, from, to) + .then(_.bind(zabbixHelperSrv.handleHistoryResponse, zabbixHelperSrv, items, alias, target.scale)); + } + + return history.then(function (timeseries) { + var timeseries_data = _.flatten(timeseries); + return _.map(timeseries_data, function (timeseries) { + + // Series downsampling + if (timeseries.datapoints.length > options.maxDataPoints) { + var ms_interval = Math.floor((to - from) / options.maxDataPoints) * 1000; + var downsampleFunc = target.downsampleFunction ? target.downsampleFunction.value : "avg"; + timeseries.datapoints = zabbixHelperSrv.downsampleSeries(timeseries.datapoints, to, ms_interval, downsampleFunc); + } + return timeseries; + }); + }); + } + }); + } + + // Query text data + else if (target.mode === 2) { + + // Find items by item names and perform queries + return this.zabbixAPI.itemFindQuery(groups, hosts, apps, "text") + .then(function (items) { + items = _.filter(items, function (item) { return _.contains(itemnames, zabbixHelperSrv.expandItemName(item)); }); - } - }).then(function (items) { - - // Don't perform query for high number of items - // to prevent Grafana slowdown - if (items.length > self.limitmetrics) { - var message = "Try to increase limitmetrics parameter in datasource config.
" - + "Current limitmetrics value is " + self.limitmetrics; - alertSrv.set("Metrics limit exceeded", message, "warning", 10000); - return []; - } else { - items = _.flatten(items); - - // Use alias only for single metric, otherwise use item names - var alias = target.item.name === 'All' || itemnames.length > 1 ? - undefined : templateSrv.replace(target.alias, options.scopedVars); - - var history; - if ((from < useTrendsFrom) && self.trends) { - var points = target.downsampleFunction ? target.downsampleFunction.value : "avg"; - history = self.zabbixAPI.getTrends(items, from, to) - .then(_.bind(zabbixHelperSrv.handleTrendResponse, zabbixHelperSrv, items, alias, target.scale, points)); - } else { - history = self.zabbixAPI.getHistory(items, from, to) - .then(_.bind(zabbixHelperSrv.handleHistoryResponse, zabbixHelperSrv, items, alias, target.scale)); - } - - return history.then(function (timeseries) { - var timeseries_data = _.flatten(timeseries); - return _.map(timeseries_data, function (timeseries) { - - // Series downsampling - if (timeseries.datapoints.length > options.maxDataPoints) { - var ms_interval = Math.floor((to - from) / options.maxDataPoints) * 1000; - var downsampleFunc = target.downsampleFunction ? target.downsampleFunction.value : "avg"; - timeseries.datapoints = zabbixHelperSrv.downsampleSeries(timeseries.datapoints, to, ms_interval, downsampleFunc); - } - return timeseries; - }); - }); - } - }); + return self.zabbixAPI.getHistory(items, from, to).then(function(history) { + return { + target: target.item.name, + datapoints: _.map(history, function (p) { + return [p.value, p.clock * 1000]; + }) + }; + }); + }); + } } // IT services mode @@ -211,11 +236,6 @@ function (angular, _, kbn) { .then(_.bind(zabbixHelperSrv.handleSLAResponse, zabbixHelperSrv, target.itservice, target.slaProperty)); } } - - // Text metrics mode - else if (target.mode === 2) { - return []; - } }, this); return $q.all(_.flatten(promises)).then(function (results) { diff --git a/zabbix/queryCtrl.js b/zabbix/queryCtrl.js index 2af2af6..92e676a 100644 --- a/zabbix/queryCtrl.js +++ b/zabbix/queryCtrl.js @@ -13,7 +13,7 @@ define([ $scope.init = function () { $scope.targetLetters = targetLetters; - if (!$scope.target.mode || $scope.target.mode === 0) { + if (!$scope.target.mode || $scope.target.mode !== 1) { $scope.downsampleFunctionList = [ {name: "avg", value: "avg"}, {name: "min", value: "min"}, @@ -224,8 +224,9 @@ define([ var hosts = $scope.target.host ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined; var apps = $scope.target.application ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.application.name)) : undefined; + var itemtype = $scope.target.mode === 2 ? "text" : "numeric"; if (groups && hosts && apps) { - $scope.datasource.zabbixAPI.itemFindQuery(groups, hosts, apps).then(function (items) { + $scope.datasource.zabbixAPI.itemFindQuery(groups, hosts, apps, itemtype).then(function (items) { // Show only unique item names var uniq_items = _.map(_.uniq(items, function (item) { return zabbixHelperSrv.expandItemName(item); diff --git a/zabbix/zabbixAPIWrapper.js b/zabbix/zabbixAPIWrapper.js index c0b8980..8a89ccc 100644 --- a/zabbix/zabbixAPIWrapper.js +++ b/zabbix/zabbixAPIWrapper.js @@ -294,7 +294,7 @@ function (angular, _) { * @param {string|string[]} groupids /////////////////////////// * @return {string|string[]} Array of Zabbix API item objects */ - p.performItemSuggestQuery = function(hostids, applicationids, /* optional */ groupids) { + p.performItemSuggestQuery = function(hostids, applicationids, groupids, itemtype) { var params = { output: ['name', 'key_', 'value_type', 'delay'], sortfield: 'name', @@ -302,13 +302,17 @@ function (angular, _) { webitems: true, // Return only numeric items filter: { - value_type: [0,3] + value_type: [0, 3] }, // Return only enabled items monitored: true, searchByAny: true }; + if (itemtype === "text") { + params.filter.value_type = [1, 2, 4]; + } + // Filter by hosts or by groups if (hostids) { params.hostids = hostids; @@ -409,7 +413,7 @@ function (angular, _) { * @param {string or array} apps * @return {array} array of Zabbix API item objects */ - p.itemFindQuery = function(groups, hosts, apps) { + p.itemFindQuery = function(groups, hosts, apps, itemtype) { var promises = []; // Get hostids from names @@ -447,7 +451,7 @@ function (angular, _) { }), 'applicationid'); } - return self.performItemSuggestQuery(hostids, applicationids, groupids); + return self.performItemSuggestQuery(hostids, applicationids, groupids, itemtype); }); };