diff --git a/zabbix/datasource.js b/zabbix/datasource.js index 17a83a5..94eec2b 100644 --- a/zabbix/datasource.js +++ b/zabbix/datasource.js @@ -4,6 +4,7 @@ define([ 'lodash', 'kbn', './zabbixAPIWrapper', + './helperFunctions', './queryCtrl' ], function (angular, _, kbn) { @@ -11,7 +12,7 @@ function (angular, _, kbn) { var module = angular.module('grafana.services'); - module.factory('ZabbixAPIDatasource', function($q, backendSrv, templateSrv, ZabbixAPI) { + module.factory('ZabbixAPIDatasource', function($q, backendSrv, templateSrv, ZabbixAPI, zabbixHelperSrv) { /** * Datasource initialization. Calls when you refresh page, add @@ -71,15 +72,15 @@ function (angular, _, kbn) { // Extract zabbix groups, hosts and apps from string: // "{host1,host2,...,hostN}" --> [host1, host2, ..., hostN] - var groups = splitMetrics(groupname); - var hosts = splitMetrics(hostname); - var apps = splitMetrics(appname); + var groups = zabbixHelperSrv.splitMetrics(groupname); + var hosts = zabbixHelperSrv.splitMetrics(hostname); + var apps = zabbixHelperSrv.splitMetrics(appname); // Remove hostnames from item names and then // extract item names // "hostname: itemname" --> "itemname" var delete_hostname_pattern = /(?:\[[\w\.]+\]\:\s)/g; - var itemnames = splitMetrics(itemname.replace(delete_hostname_pattern, '')); + var itemnames = zabbixHelperSrv.splitMetrics(itemname.replace(delete_hostname_pattern, '')); // Find items by item names and perform queries var self = this; @@ -98,7 +99,7 @@ function (angular, _, kbn) { } } - if (itemnames == 'All') { + if (itemnames[0] === 'All') { // Filter items by regex if (target.itemFilter) { @@ -146,7 +147,7 @@ function (angular, _, kbn) { // Series downsampling if (timeseries.datapoints.length > options.maxDataPoints) { var ms_interval = Math.floor((to - from) / options.maxDataPoints) * 1000; - timeseries.datapoints = downsampleSeries(timeseries.datapoints, to, ms_interval); + timeseries.datapoints = zabbixHelperSrv.downsampleSeries(timeseries.datapoints, to, ms_interval); } return timeseries; }); @@ -259,7 +260,7 @@ function (angular, _, kbn) { if (part[0] === '{') { // Convert multiple mettrics to array // "{metric1,metcic2,...,metricN}" --> [metric1, metcic2,..., metricN] - parts.push(splitMetrics(part)); + parts.push(zabbixHelperSrv.splitMetrics(part)); } else { parts.push(part); } @@ -360,7 +361,7 @@ function (angular, _, kbn) { .then(function (result) { var events = []; _.each(result, function(e) { - var formatted_acknowledges = formatAcknowledges(e.acknowledges); + var formatted_acknowledges = zabbixHelperSrv.formatAcknowledges(e.acknowledges); events.push({ annotation: annotation, time: e.clock * 1000, @@ -379,97 +380,3 @@ function (angular, _, kbn) { return ZabbixAPIDatasource; }); }); - -/** - * Convert multiple mettrics to array - * "{metric1,metcic2,...,metricN}" --> [metric1, metcic2,..., metricN] - * - * @param {string} metrics "{metric1,metcic2,...,metricN}" - * @return {Array} [metric1, metcic2,..., metricN] - */ -function splitMetrics(metrics) { - var remove_brackets_pattern = /^{|}$/g; - var metric_split_pattern = /,(?!\s)/g; - return metrics.replace(remove_brackets_pattern, '').split(metric_split_pattern); -} - -/** - * 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; -} - -/** - * 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:
' - + ''; - _.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 ''; - } -} - -/** - * Downsample datapoints series - * - * @param {array} datapoints [[, ], ...] - * @param {integer} time_to Panel time to - * @param {integer} ms_interval Interval in milliseconds for grouping datapoints - * @return {array} [[, ], ...] - */ -function downsampleSeries(datapoints, time_to, ms_interval) { - var downsampledSeries = []; - var timeWindow = { - from: time_to * 1000 - ms_interval, - to: time_to * 1000 - }; - - var points_sum = 0; - var points_num = 0; - var value_avg = 0; - for (var i = datapoints.length - 1; i >= 0; i -= 1) { - if (timeWindow.from < datapoints[i][1] && datapoints[i][1] <= timeWindow.to) { - points_sum += datapoints[i][0]; - points_num++; - } - else { - value_avg = points_num ? points_sum / points_num : 0; - downsampledSeries.push([value_avg, timeWindow.to]); - - // Shift time window - timeWindow.to = timeWindow.from; - timeWindow.from -= ms_interval; - - points_sum = 0; - points_num = 0; - - // Process point again - i++; - } - } - return downsampledSeries.reverse(); -} \ No newline at end of file diff --git a/zabbix/helperFunctions.js b/zabbix/helperFunctions.js new file mode 100644 index 0000000..f316b9f --- /dev/null +++ b/zabbix/helperFunctions.js @@ -0,0 +1,107 @@ +define([ + 'angular', + 'lodash' +], +function (angular, _) { + 'use strict'; + + var module = angular.module('grafana.services'); + + module.service('zabbixHelperSrv', function() { + var self = this; + + /** + * Convert multiple mettrics to array + * "{metric1,metcic2,...,metricN}" --> [metric1, metcic2,..., metricN] + * + * @param {string} metrics "{metric1,metcic2,...,metricN}" + * @return {Array} [metric1, metcic2,..., metricN] + */ + this.splitMetrics = function(metrics) { + var remove_brackets_pattern = /^{|}$/g; + var metric_split_pattern = /,(?!\s)/g; + return metrics.replace(remove_brackets_pattern, '').split(metric_split_pattern); + }; + + /** + * 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 + */ + this.getShortTime = function(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; + }; + + /** + * Format acknowledges. + * + * @param {array} acknowledges array of Zabbix acknowledge objects + * @return {string} HTML-formatted table + */ + this.formatAcknowledges = function(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
' + self.getShortTime(time) + '' + ack.alias + + ' (' + ack.name + ' ' + ack.surname + ')' + '' + ack.message + '
'); + return formatted_acknowledges; + } else { + return ''; + } + }; + + /** + * Downsample datapoints series + * + * @param {array} datapoints [[, ], ...] + * @param {integer} time_to Panel time to + * @param {integer} ms_interval Interval in milliseconds for grouping datapoints + * @return {array} [[, ], ...] + */ + this.downsampleSeries = function(datapoints, time_to, ms_interval) { + var downsampledSeries = []; + var timeWindow = { + from: time_to * 1000 - ms_interval, + to: time_to * 1000 + }; + + var points_sum = 0; + var points_num = 0; + var value_avg = 0; + for (var i = datapoints.length - 1; i >= 0; i -= 1) { + if (timeWindow.from < datapoints[i][1] && datapoints[i][1] <= timeWindow.to) { + points_sum += datapoints[i][0]; + points_num++; + } + else { + value_avg = points_num ? points_sum / points_num : 0; + downsampledSeries.push([value_avg, timeWindow.to]); + + // Shift time window + timeWindow.to = timeWindow.from; + timeWindow.from -= ms_interval; + + points_sum = 0; + points_num = 0; + + // Process point again + i++; + } + } + return downsampledSeries.reverse(); + }; + }); +}); \ No newline at end of file diff --git a/zabbix/queryCtrl.js b/zabbix/queryCtrl.js index 5a8770d..76bf47e 100644 --- a/zabbix/queryCtrl.js +++ b/zabbix/queryCtrl.js @@ -1,6 +1,7 @@ define([ 'angular', - 'lodash' + 'lodash', + './helperFunctions' ], function (angular, _) { 'use strict'; @@ -8,7 +9,7 @@ function (angular, _) { var module = angular.module('grafana.controllers'); var targetLetters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; - module.controller('ZabbixAPIQueryCtrl', function($scope, $sce, templateSrv) { + module.controller('ZabbixAPIQueryCtrl', function($scope, $sce, templateSrv, zabbixHelperSrv) { $scope.init = function() { $scope.targetLetters = targetLetters; @@ -134,7 +135,7 @@ function (angular, _) { $scope.metric.hostList = [{name: '*', visible_name: 'All'}]; addTemplatedVariables($scope.metric.hostList); - var groups = $scope.target.group ? splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined; + var groups = $scope.target.group ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined; $scope.datasource.zabbixAPI.hostFindQuery(groups).then(function (hosts) { $scope.metric.hostList = $scope.metric.hostList.concat(hosts); }); @@ -147,8 +148,8 @@ function (angular, _) { $scope.metric.applicationList = [{name: '*', visible_name: 'All'}]; addTemplatedVariables($scope.metric.applicationList); - var groups = $scope.target.group ? splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined; - var hosts = $scope.target.host ? splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined; + var groups = $scope.target.group ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined; + var hosts = $scope.target.host ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined; $scope.datasource.zabbixAPI.appFindQuery(hosts, groups).then(function (apps) { apps = _.map(_.uniq(_.map(apps, 'name')), function (appname) { return {name: appname}; @@ -164,9 +165,9 @@ function (angular, _) { $scope.metric.itemList = [{name: 'All'}]; addTemplatedVariables($scope.metric.itemList); - var groups = $scope.target.group ? splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined; - var hosts = $scope.target.host ? splitMetrics(templateSrv.replace($scope.target.host.name)) : undefined; - var apps = $scope.target.application ? splitMetrics(templateSrv.replace($scope.target.application.name)) : undefined; + var groups = $scope.target.group ? zabbixHelperSrv.splitMetrics(templateSrv.replace($scope.target.group.name)) : undefined; + 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; $scope.datasource.zabbixAPI.itemFindQuery(groups, hosts, apps).then(function (items) { // Show only unique item names var uniq_items = _.map(_.uniq(items, function (item) { @@ -207,17 +208,3 @@ function (angular, _) { }); }); - -/** - * Convert multiple mettrics to array - * "{metric1,metcic2,...,metricN}" --> [metric1, metcic2,..., metricN] - * - * @param {string} metrics "{metric1,metcic2,...,metricN}" - * @return {Array} [metric1, metcic2,..., metricN] - */ -function splitMetrics(metrics) { - 'use strict'; - var remove_brackets_pattern = /^{|}$/g; - var metric_split_pattern = /,(?!\s)/g; - return metrics.replace(remove_brackets_pattern, '').split(metric_split_pattern); -}