From 4fca46ef6a91539463be0650ed3253e840db2ce9 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 11 Jun 2015 01:35:59 +0300 Subject: [PATCH 01/10] Add acknowledges to annotations. Add wildcards to triggers search. --- zabbix/datasource.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index d5f601f..577368b 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -617,31 +617,37 @@ function (angular, _, kbn) { search: { 'description': annotation.query }, + searchWildcardsEnabled: true, + expandDescription: true }; return this.performZabbixAPIRequest('trigger.get', params) .then(function (result) { if(result) { - var obs = {}; - obs = _.indexBy(result, 'triggerid'); - + var objects = _.indexBy(result, 'triggerid'); var params = { output: 'extend', - sortorder: 'DESC', time_from: from, time_till: to, - objectids: _.keys(obs) + objectids: _.keys(objects), + select_acknowledges: 'extend' }; return self.performZabbixAPIRequest('event.get', params) .then(function (result) { var events = []; _.each(result, function(e) { + var formatted_acknowledges = '\n'; + var acknowledges = _.each(_.map(e.acknowledges, function (ack) { + return ack.name + ' ' + ack.surname + '(' + ack.alias + '): ' + ack.message; + }), function (ack) { + formatted_acknowledges = formatted_acknowledges.concat(ack, '\n') + }); events.push({ annotation: annotation, time: e.clock * 1000, - title: obs[e.objectid].description, - text: e.eventid, + title: Number(e.value) ? 'Problem' : 'OK', + text: objects[e.objectid].description + (acknowledges.length ? formatted_acknowledges : ''), }); }); return events; From c3bf7d038dd1ac8936fac314bfb6188a08847fed Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 11 Jun 2015 11:01:01 +0300 Subject: [PATCH 02/10] Add zabbix acknowledges to annotations. --- zabbix/datasource.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 577368b..23004fb 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -637,12 +637,13 @@ function (angular, _, kbn) { .then(function (result) { var events = []; _.each(result, function(e) { - var formatted_acknowledges = '\n'; + var formatted_acknowledges = '
'; var acknowledges = _.each(_.map(e.acknowledges, function (ack) { - return ack.name + ' ' + ack.surname + '(' + ack.alias + '): ' + ack.message; + return '' + ack.name + ' ' + ack.surname + ' (' + ack.alias + '): ' + ack.message; }), function (ack) { - formatted_acknowledges = formatted_acknowledges.concat(ack, '\n') + formatted_acknowledges = formatted_acknowledges.concat(ack, '
') }); + events.push({ annotation: annotation, time: e.clock * 1000, From 015cb875fae3d81f1202c4abba5f7a35073e3a55 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 11 Jun 2015 13:19:04 +0300 Subject: [PATCH 03/10] Format acknowledges as table. --- zabbix/datasource.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 23004fb..cb04753 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -637,12 +637,13 @@ function (angular, _, kbn) { .then(function (result) { var events = []; _.each(result, function(e) { - var formatted_acknowledges = '
'; + var formatted_acknowledges = "

Acknowledges:
"; var acknowledges = _.each(_.map(e.acknowledges, function (ack) { - return '' + ack.name + ' ' + ack.surname + ' (' + ack.alias + '): ' + ack.message; + return ''; }), function (ack) { - formatted_acknowledges = formatted_acknowledges.concat(ack, '
') + formatted_acknowledges = formatted_acknowledges.concat(ack) }); + formatted_acknowledges = formatted_acknowledges.concat('
TimeUserMessage
' + ack.clock + '' + ack.name + ' ' + ack.surname + ' (' + ack.alias + ')' + '' + ack.message + '
') events.push({ annotation: annotation, From ad32942b8a1af898523807f1ae253b9fd35a1f3c Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 11 Jun 2015 14:22:10 +0300 Subject: [PATCH 04/10] Add time to acknowledges. --- zabbix/datasource.js | 47 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index cb04753..283295e 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -637,19 +637,12 @@ function (angular, _, kbn) { .then(function (result) { var events = []; _.each(result, function(e) { - var formatted_acknowledges = "

Acknowledges:
"; - var acknowledges = _.each(_.map(e.acknowledges, function (ack) { - return ''; - }), function (ack) { - formatted_acknowledges = formatted_acknowledges.concat(ack) - }); - formatted_acknowledges = formatted_acknowledges.concat('
TimeUserMessage
' + ack.clock + '' + ack.name + ' ' + ack.surname + ' (' + ack.alias + ')' + '' + ack.message + '
') - + var formatted_acknowledges = formatAcknowledges(e.acknowledges);; events.push({ annotation: annotation, time: e.clock * 1000, title: Number(e.value) ? 'Problem' : 'OK', - text: objects[e.objectid].description + (acknowledges.length ? formatted_acknowledges : ''), + text: objects[e.objectid].description + formatted_acknowledges, }); }); return events; @@ -699,4 +692,38 @@ function expandItemName(item) { name = name.replace('$' + i, key_params[i - 1]); }; return name; -}; \ No newline at end of file +} + + +/** + * Convert Date object to local time in format + * YYYY-MM-DD HH:mm:ss + * + * @param {Date} date Date object + * @return {string} formatted local time YYYY-MM-DD HH:mm:ss + */ +function getShortTime(date) { + var MM = date.getMonth() < 10 ? '0' + date.getMonth() : date.getMonth(); + var DD = date.getDate() < 10 ? '0' + date.getDate() : date.getDate(); + var HH = date.getHours() < 10 ? '0' + date.getHours() : date.getHours(); + var mm = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes(); + var ss = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds(); + return date.getFullYear() + '-' + MM + '-' + DD + ' ' + HH + ':' + mm + ':' + ss; +} + + +function formatAcknowledges(acknowledges) { + if (acknowledges.length) { + var formatted_acknowledges = '

Acknowledges:
'; + _.each(_.map(acknowledges, function (ack) { + var time = new Date(ack.clock * 1000); + return ''; + }), function (ack) { + formatted_acknowledges = formatted_acknowledges.concat(ack) + }); + formatted_acknowledges = formatted_acknowledges.concat('
TimeUserComments
' + getShortTime(time) + '' + ack.alias + ' (' + ack.name+ ' ' + ack.surname + ')' + '' + ack.message + '
') + return formatted_acknowledges; + } else { + return ''; + } +} \ No newline at end of file From 33bf0c38e737b9196131cf23efaedf3040d6ad62 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 11 Jun 2015 18:21:56 +0300 Subject: [PATCH 05/10] Add Show OK events option. --- zabbix/datasource.js | 13 ++++++++++++- zabbix/partials/annotations.editor.html | 10 +++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 283295e..ff249c4 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -633,6 +633,11 @@ function (angular, _, kbn) { select_acknowledges: 'extend' }; + // Show problem events only + if (!annotation.showOkEvents) { + params.value = 1; + } + return self.performZabbixAPIRequest('event.get', params) .then(function (result) { var events = []; @@ -712,9 +717,15 @@ function getShortTime(date) { } +/** + * Format acknowledges. + * + * @param {array} acknowledges array of Zabbix acknowledge objects + * @return {string} HTML-formatted table + */ function formatAcknowledges(acknowledges) { if (acknowledges.length) { - var formatted_acknowledges = '

Acknowledges:
'; + var formatted_acknowledges = '

Acknowledges:
TimeUserComments
'; _.each(_.map(acknowledges, function (ack) { var time = new Date(ack.clock * 1000); return ''; diff --git a/zabbix/partials/annotations.editor.html b/zabbix/partials/annotations.editor.html index eb65f53..1ca3d78 100644 --- a/zabbix/partials/annotations.editor.html +++ b/zabbix/partials/annotations.editor.html @@ -2,7 +2,15 @@
Zabbix trigger Example: Lack of free swap space
- +
+ +
+
+
Options
+ + +
+
From f610c0306b244934c1abeef4919b9db9ed3b25a2 Mon Sep 17 00:00:00 2001 From: Alexander Zobnin Date: Thu, 11 Jun 2015 18:45:14 +0300 Subject: [PATCH 06/10] Fixed showOkEvents. --- zabbix/partials/annotations.editor.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zabbix/partials/annotations.editor.html b/zabbix/partials/annotations.editor.html index 1ca3d78..1dcfe6f 100644 --- a/zabbix/partials/annotations.editor.html +++ b/zabbix/partials/annotations.editor.html @@ -10,7 +10,7 @@
Options
- - + +
From c58aae7f10c2ed2d6030fa152c93966b1f44f0f8 Mon Sep 17 00:00:00 2001 From: alexanderzobnin Date: Thu, 18 Jun 2015 13:01:42 +0300 Subject: [PATCH 07/10] iss #16 Add methods for get and handle trends. --- zabbix/datasource.js | 56 ++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 54 insertions(+), 2 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index ff249c4..62212d9 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -93,8 +93,8 @@ function (angular, _, kbn) { return []; } else { items = _.flatten(items); - return self.performTimeSeriesQuery(items, from, to) - .then(_.partial(self.handleHistoryResponse, items)); + return self.getTrends(items, from, to) + .then(_.partial(self.handleTrendResponse, items)); } }); }, this); @@ -142,6 +142,58 @@ function (angular, _, kbn) { }; + ZabbixAPIDatasource.prototype.getTrends = function(items, start, end) { + // Group items by value type + var grouped_items = _.groupBy(items, 'value_type'); + + // Perform request for each value type + return $q.all(_.map(grouped_items, function (items, value_type) { + var itemids = _.map(items, 'itemid'); + var params = { + output: 'extend', + trend: value_type, + itemids: itemids, + sortfield: 'clock', + sortorder: 'ASC', + time_from: start + }; + + // Relative queries (e.g. last hour) don't include an end time + if (end) { + params.time_till = end; + } + + return this.performZabbixAPIRequest('trend.get', params); + }, this)).then(function (results) { + return _.flatten(results); + }); + }; + + + ZabbixAPIDatasource.prototype.handleTrendResponse = function(items, trends) { + + // Group items and trends by itemid + var indexed_items = _.indexBy(items, 'itemid'); + var grouped_history = _.groupBy(trends, 'itemid'); + + return $q.when(_.map(grouped_history, function (trends, itemid) { + var item = indexed_items[itemid]; + var series = { + target: (item.hosts ? item.hosts[0].name+': ' : '') + expandItemName(item), + datapoints: _.map(trends, function (p) { + + // Value must be a number for properly work + var value = Number(p.value_avg); + return [value, p.clock * 1000]; + }) + }; + return series; + })).then(function (result) { + return _.sortBy(result, 'target'); + }); + }; + + /** * Convert Zabbix API data to Grafana format * From a7e322bfebda5c3bb7f2648994a4a2e442b50054 Mon Sep 17 00:00:00 2001 From: alexanderzobnin Date: Thu, 18 Jun 2015 13:26:39 +0300 Subject: [PATCH 08/10] iss #16 Add auto selection between history and trends. --- zabbix/datasource.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 62212d9..f03fc51 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -44,6 +44,7 @@ function (angular, _, kbn) { // get from & to in seconds var from = Math.ceil(kbn.parseDate(options.range.from).getTime() / 1000); var to = Math.ceil(kbn.parseDate(options.range.to).getTime() / 1000); + var getTrendsFrom = Math.ceil(kbn.parseDate('now-7d').getTime() / 1000); // Create request for each target var promises = _.map(options.targets, function(target) { @@ -93,8 +94,14 @@ function (angular, _, kbn) { return []; } else { items = _.flatten(items); - return self.getTrends(items, from, to) - .then(_.partial(self.handleTrendResponse, items)); + + if (from > getTrendsFrom) { + return self.performTimeSeriesQuery(items, from, to) + .then(_.partial(self.handleHistoryResponse, items)); + } else { + return self.getTrends(items, from, to) + .then(_.partial(self.handleTrendResponse, items)); + } } }); }, this); From 2a60256b83c3fa93f24bf9a5b3b328267b2f975c Mon Sep 17 00:00:00 2001 From: alexanderzobnin Date: Thu, 18 Jun 2015 14:25:28 +0300 Subject: [PATCH 09/10] iss #16 Add trendsFrom option to specify trend use period. --- zabbix/datasource.js | 7 +++++-- zabbix/plugin.json | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index f03fc51..b3b146d 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -25,6 +25,9 @@ function (angular, _, kbn) { this.username = datasource.meta.username; this.password = datasource.meta.password; + // Use trends instead history since specified time + this.trendsFrom = datasource.meta.trendsFrom || '7d'; + // Limit metrics per panel for templated request this.limitmetrics = datasource.meta.limitmetrics || 50; } @@ -44,7 +47,7 @@ function (angular, _, kbn) { // get from & to in seconds var from = Math.ceil(kbn.parseDate(options.range.from).getTime() / 1000); var to = Math.ceil(kbn.parseDate(options.range.to).getTime() / 1000); - var getTrendsFrom = Math.ceil(kbn.parseDate('now-7d').getTime() / 1000); + var useTrendsFrom = Math.ceil(kbn.parseDate('now-' + this.trendsFrom).getTime() / 1000); // Create request for each target var promises = _.map(options.targets, function(target) { @@ -95,7 +98,7 @@ function (angular, _, kbn) { } else { items = _.flatten(items); - if (from > getTrendsFrom) { + if (from > useTrendsFrom) { return self.performTimeSeriesQuery(items, from, to) .then(_.partial(self.handleHistoryResponse, items)); } else { diff --git a/zabbix/plugin.json b/zabbix/plugin.json index 75f81cf..55c9dcf 100644 --- a/zabbix/plugin.json +++ b/zabbix/plugin.json @@ -16,6 +16,7 @@ "username": "guest", "password": "", + "trendsFrom": "7d", "limitmetrics": 50, "metrics": true, From 7bc57786975776680bc3f7e95deea041cb837a9e Mon Sep 17 00:00:00 2001 From: alexanderzobnin Date: Thu, 18 Jun 2015 17:40:50 +0300 Subject: [PATCH 10/10] Add "trends" option to activate trend api support. --- zabbix/datasource.js | 9 +++++---- zabbix/plugin.json | 2 ++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/zabbix/datasource.js b/zabbix/datasource.js index b427d8c..ddbdc1c 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -26,6 +26,7 @@ function (angular, _, kbn) { this.password = datasource.meta.password; // Use trends instead history since specified time + this.trends = datasource.meta.trends; this.trendsFrom = datasource.meta.trendsFrom || '7d'; // Limit metrics per panel for templated request @@ -98,12 +99,12 @@ function (angular, _, kbn) { } else { items = _.flatten(items); - if (from > useTrendsFrom) { - return self.performTimeSeriesQuery(items, from, to) - .then(_.partial(self.handleHistoryResponse, items)); - } else { + if ((from < useTrendsFrom) && self.trends) { return self.getTrends(items, from, to) .then(_.partial(self.handleTrendResponse, items)); + } else { + return self.performTimeSeriesQuery(items, from, to) + .then(_.partial(self.handleHistoryResponse, items)); } } }); diff --git a/zabbix/plugin.json b/zabbix/plugin.json index 55c9dcf..5d10ced 100644 --- a/zabbix/plugin.json +++ b/zabbix/plugin.json @@ -16,7 +16,9 @@ "username": "guest", "password": "", + "trends": true, "trendsFrom": "7d", + "limitmetrics": 50, "metrics": true,
TimeUserComments
' + getShortTime(time) + '' + ack.alias + ' (' + ack.name+ ' ' + ack.surname + ')' + '' + ack.message + '