From a1d31d54585cb66fc7d17ace65b690e7db0b4ecf Mon Sep 17 00:00:00 2001 From: nucleusv Date: Fri, 8 May 2015 01:25:08 +0300 Subject: [PATCH 1/8] Written ptototype.query method This method now uses the same request doZabbixAPIRequest without code dublication. Please check on your installation cause I have only one metric per graph --- zabbix/datasource.js | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index bbf1820..103bc2e 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -56,20 +56,11 @@ function (angular, _, kbn) { from = Math.ceil(from/1000); to = Math.ceil(to/1000); - var performedQuery; + - // Check authorization first - if (!this.auth) { - var self = this; - performedQuery = this.performZabbixAPILogin().then(function (response) { - self.auth = response; - return self.performTimeSeriesQuery(target_items, from, to); - }); - } else { - performedQuery = this.performTimeSeriesQuery(target_items, from, to); - } - - return performedQuery.then(function (response) { + return this.performTimeSeriesQuery(target_items, from, to).then(function (response) { + + console.log(response); /** * Response should be in the format: * data: [ @@ -85,7 +76,7 @@ function (angular, _, kbn) { */ // Index returned datapoints by item/metric id - var indexed_result = _.groupBy(response.data.result, function (history_item) { + var indexed_result = _.groupBy(response, function (history_item) { return history_item.itemid; }); @@ -177,10 +168,8 @@ function (angular, _, kbn) { // TODO: if different value types passed? // Perform multiple api request. var hystory_type = items[0].value_type; - var options = { - method: 'POST', - url: this.url, - data: { + + var data = { jsonrpc: '2.0', method: 'history.get', params: { @@ -194,14 +183,14 @@ function (angular, _, kbn) { }, auth: this.auth, id: 1 - }, - }; + }; + // Relative queries (e.g. last hour) don't include an end time if (end) { - options.data.params.time_till = end; + data.params.time_till = end; } - return $http(options); + return this.doZabbixAPIRequest(data); }; From 4b4432923045740a28bd21f60c1e04d6fd80a37d Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Fri, 8 May 2015 22:13:52 +0300 Subject: [PATCH 2/8] Some refactoring. --- zabbix/datasource.js | 43 ++++++++++++++++++++----------------------- 1 file changed, 20 insertions(+), 23 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 103bc2e..3598f9b 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -35,6 +35,7 @@ function (angular, _, kbn) { // get from & to in seconds var from = kbn.parseDate(options.range.from).getTime(); var to = kbn.parseDate(options.range.to).getTime(); + // Need for find target alias var targets = options.targets; @@ -46,7 +47,6 @@ function (angular, _, kbn) { // Extract zabbix api item objects from targets var target_items = _.map(options.targets, 'item'); } else { - // No valid targets, return the empty dataset var d = $q.defer(); d.resolve({ data: [] }); @@ -56,11 +56,7 @@ function (angular, _, kbn) { from = Math.ceil(from/1000); to = Math.ceil(to/1000); - - return this.performTimeSeriesQuery(target_items, from, to).then(function (response) { - - console.log(response); /** * Response should be in the format: * data: [ @@ -165,26 +161,27 @@ function (angular, _, kbn) { var item_ids = items.map(function (item, index, array) { return item.itemid; }); + // TODO: if different value types passed? // Perform multiple api request. - var hystory_type = items[0].value_type; - - var data = { - jsonrpc: '2.0', - method: 'history.get', - params: { - output: 'extend', - history: hystory_type, - itemids: item_ids, - sortfield: 'clock', - sortorder: 'ASC', - limit: this.limitmetrics, - time_from: start, - }, - auth: this.auth, - id: 1 - }; - + var history_type = items[0].value_type; + + var data = { + jsonrpc: '2.0', + method: 'history.get', + params: { + output: 'extend', + history: history_type, + itemids: item_ids, + sortfield: 'clock', + sortorder: 'ASC', + limit: this.limitmetrics, + time_from: start, + }, + auth: this.auth, + id: 1 + }; + // Relative queries (e.g. last hour) don't include an end time if (end) { data.params.time_till = end; From 6ea38462f698171ea1121c1b8d8772442d0888b5 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Fri, 8 May 2015 22:55:05 +0300 Subject: [PATCH 3/8] Fixed update of host list and item list when host or item not selected. --- zabbix/queryCtrl.js | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/zabbix/queryCtrl.js b/zabbix/queryCtrl.js index 29b1192..e367f49 100644 --- a/zabbix/queryCtrl.js +++ b/zabbix/queryCtrl.js @@ -135,7 +135,6 @@ function (angular, _) { $scope.metric.hostGroupList = series; if ($scope.target.hostGroup) { $scope.target.hostGroup = $scope.metric.hostGroupList.filter(function (item, index, array) { - // Find selected host in metric.hostList return (item.groupid == $scope.target.hostGroup.groupid); }).pop(); @@ -150,11 +149,13 @@ function (angular, _) { $scope.updateHostList = function(groupid) { $scope.datasource.performHostSuggestQuery(groupid).then(function (series) { $scope.metric.hostList = series; - $scope.target.host = $scope.metric.hostList.filter(function (item, index, array) { - // Find selected host in metric.hostList - return (item.hostid == $scope.target.host.hostid); - }).pop(); + if ($scope.target.host) { + $scope.target.host = $scope.metric.hostList.filter(function (item, index, array) { + // Find selected host in metric.hostList + return (item.hostid == $scope.target.host.hostid); + }).pop(); + } }); }; @@ -167,7 +168,6 @@ function (angular, _) { $scope.metric.applicationList = series; if ($scope.target.application) { $scope.target.application = $scope.metric.applicationList.filter(function (item, index, array) { - // Find selected application in metric.hostList return (item.applicationid == $scope.target.application.applicationid); }).pop(); @@ -192,11 +192,12 @@ function (angular, _) { item.expandedName = expandItemName(item); } }); - $scope.target.item = $scope.metric.itemList.filter(function (item, index, array) { - - // Find selected item in metric.hostList - return (item.itemid == $scope.target.item.itemid); - }).pop(); + if ($scope.target.item) { + $scope.target.item = $scope.metric.itemList.filter(function (item, index, array) { + // Find selected item in metric.hostList + return (item.itemid == $scope.target.item.itemid); + }).pop(); + } }); } else { $scope.metric.itemList = []; From e98441d0497f42181163d9f625cfcd54dcdaab8a Mon Sep 17 00:00:00 2001 From: nucleusv Date: Sat, 9 May 2015 14:53:04 +0300 Subject: [PATCH 4/8] Update README.md --- README.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1585da6..e96ecff 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,16 @@ # grafana-zabbix Zabbix API datasource for Grafana dashboard +![alt tag](https://cloud.githubusercontent.com/assets/4932851/7454206/34bf9f8c-f27a-11e4-8e96-a73829f188c4.png) + + +Query editor allows to add metric by step-by-step selection from host group, host, application dropdown menus. + +![alt tag](https://cloud.githubusercontent.com/assets/4932851/7441162/4f6af788-f0e4-11e4-887b-34d987d00c40.png) +![alt tag](https://cloud.githubusercontent.com/assets/4932851/7441163/56f28f16-f0e4-11e4-9d46-54181c2a2e7e.png) +![alt tag](https://cloud.githubusercontent.com/assets/4932851/7441167/5f29cc94-f0e4-11e4-8d39-7580f33201f6.png) + + ## Installation ### Grafana 1.9.x @@ -30,4 +40,4 @@ Download latest release and unpack into `/plugins/dat ``` ### Grafana 2.0.x -Now in development. \ No newline at end of file +Now in development. From 8ee4dd6a5cf8ad351a7af9b0c87e39d34ab530d3 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Sat, 9 May 2015 16:05:30 +0300 Subject: [PATCH 5/8] Fixed history request for multiple value type items. --- zabbix/datasource.js | 90 ++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 28 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 3598f9b..fcdc3cf 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -39,6 +39,7 @@ function (angular, _, kbn) { // Need for find target alias var targets = options.targets; + // TODO: remove undefined targets from request // Check that all targets defined var targetsDefined = options.targets.every(function (target, index, array) { return target.item; @@ -72,9 +73,7 @@ function (angular, _, kbn) { */ // Index returned datapoints by item/metric id - var indexed_result = _.groupBy(response, function (history_item) { - return history_item.itemid; - }); + var indexed_result = _.groupBy(response, 'itemid'); // Reduce timeseries to the same size for stacking and tooltip work properly var min_length = _.min(_.map(indexed_result, function (history) { @@ -124,6 +123,9 @@ function (angular, _, kbn) { ZabbixAPIDatasource.prototype.doZabbixAPIRequest = function(request_data) { var options = { method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, url: this.url, data: request_data }; @@ -158,36 +160,68 @@ function (angular, _, kbn) { * @param items: array of zabbix api item objects */ ZabbixAPIDatasource.prototype.performTimeSeriesQuery = function(items, start, end) { - var item_ids = items.map(function (item, index, array) { - return item.itemid; + + // Group items by value type for separate requests + var items_by_value_type = _.groupBy(items, 'value_type'); + + var self = this; + var apiRequests = []; + + // Prepare requests for each value type + _.each(items_by_value_type, function (value, key, list) { + var item_ids = _.map(value, 'itemid'); + var history_type = key; + var data = { + jsonrpc: '2.0', + method: 'history.get', + params: { + output: 'extend', + history: history_type, + itemids: item_ids, + sortfield: 'clock', + sortorder: 'ASC', + limit: self.limitmetrics, + time_from: start, + }, + auth: self.auth, + id: 1 + }; + + // Relative queries (e.g. last hour) don't include an end time + if (end) { + data.params.time_till = end; + } + + apiRequests.push(self.doZabbixAPIRequest(data)); }); - // TODO: if different value types passed? - // Perform multiple api request. - var history_type = items[0].value_type; + return this.handleMultipleRequest(apiRequests); + }; - var data = { - jsonrpc: '2.0', - method: 'history.get', - params: { - output: 'extend', - history: history_type, - itemids: item_ids, - sortfield: 'clock', - sortorder: 'ASC', - limit: this.limitmetrics, - time_from: start, - }, - auth: this.auth, - id: 1 - }; - // Relative queries (e.g. last hour) don't include an end time - if (end) { - data.params.time_till = end; - } + // Handle multiple request + ZabbixAPIDatasource.prototype.handleMultipleRequest = function(apiRequests) { + var history = []; + var performedQuery = null; - return this.doZabbixAPIRequest(data); + // Build chain of api requests and put all history data into single array + _.each(apiRequests, function (apiRequest) { + if(!performedQuery) { + performedQuery = apiRequest.then(function (response) { + history = history.concat(response); + return history; + }); + } else { + performedQuery = performedQuery.then(function () { + return apiRequest.then(function (response) { + history = history.concat(response); + return history; + }); + }); + } + }); + + return performedQuery; }; From f9532059220110da6b1f9f2fe504a2b662d4f0c2 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Sun, 10 May 2015 09:23:08 +0300 Subject: [PATCH 6/8] Filter non-numeric items in item menu. --- zabbix/datasource.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index fcdc3cf..0d55f92 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -314,7 +314,10 @@ function (angular, _, kbn) { params: { output: ['name', 'key_', 'value_type', 'delay'], sortfield: 'name', - hostids: hostid + hostids: hostid, + filter: { + value_type: [0,3] + } }, auth: this.auth, id: 1 From 20029dc618990ca5a5d8bb9c15b70de7223ec37e Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Mon, 11 May 2015 22:41:38 +0300 Subject: [PATCH 7/8] Include web items in the item selection. --- zabbix/datasource.js | 1 + 1 file changed, 1 insertion(+) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 0d55f92..ce15b04 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -315,6 +315,7 @@ function (angular, _, kbn) { output: ['name', 'key_', 'value_type', 'delay'], sortfield: 'name', hostids: hostid, + webitems: true, //Include web items in the result filter: { value_type: [0,3] } From 572bba924ee6a1e6f35a7eee012f28c0f850caf8 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Mon, 11 May 2015 22:49:05 +0300 Subject: [PATCH 8/8] Return only host groups that contain hosts. --- zabbix/datasource.js | 1 + 1 file changed, 1 insertion(+) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index ce15b04..ad4ccc0 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -258,6 +258,7 @@ function (angular, _, kbn) { method: 'hostgroup.get', params: { output: ['name'], + real_hosts: true, //Return only host groups that contain hosts sortfield: 'name' }, auth: this.auth,