diff --git a/.jshintrc b/.jshintrc
index 36c9c9f..fe86382 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -5,6 +5,7 @@
"curly": true,
"eqnull": true,
"strict": true,
+ "module": true,
"devel": true,
"eqeqeq": true,
"forin": false,
diff --git a/Gruntfile.js b/Gruntfile.js
index 2c8f35a..9823176 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -17,6 +17,8 @@ module.exports = function(grunt) {
'**/*',
'!**/datasource.js',
'!**/module.js',
+ '!**/queryCtrl.js',
+ '!**/utils.js',
'!**/*.scss'
],
dest: 'dist/src'
@@ -47,8 +49,10 @@ module.exports = function(grunt) {
cwd: 'src',
expand: true,
src: [
- '**/**/datasource.js',
'**/**/module.js',
+ '**/**/datasource.js',
+ '**/**/queryCtrl.js',
+ '**/**/utils.js',
],
dest: 'dist/src',
ext:'.js'
diff --git a/src/datasource-zabbix/datasource.js b/src/datasource-zabbix/datasource.js
index f9699f3..24e755d 100644
--- a/src/datasource-zabbix/datasource.js
+++ b/src/datasource-zabbix/datasource.js
@@ -1,7 +1,7 @@
//import angular from 'angular';
import _ from 'lodash';
-import {parse as dateMathParse} from 'app/core/utils/datemath';
-import Utils from './utils';
+import * as dateMath from 'app/core/utils/datemath';
+import * as utils from './utils';
import metricFunctions from './metricFunctions';
import {zabbixHelperSrv} from './helperFunctions';
import {ZabbixAPI} from './zabbixAPI';
@@ -29,7 +29,7 @@ export class ZabbixAPIDatasource {
// Set cache update interval
var ttl = instanceSettings.jsonData.cacheTTL || '1h';
- this.cacheTTL = Utils.parseInterval(ttl);
+ this.cacheTTL = utils.parseInterval(ttl);
// Initialize Zabbix API
this.zabbixAPI = new ZabbixAPI(this.url, this.username, this.password, this.basicAuth, this.withCredentials);
@@ -103,9 +103,9 @@ export class ZabbixAPIDatasource {
var self = this;
// get from & to in seconds
- var from = Math.ceil(dateMathParse(options.range.from) / 1000);
- var to = Math.ceil(dateMathParse(options.range.to) / 1000);
- var useTrendsFrom = Math.ceil(dateMathParse('now-' + this.trendsFrom) / 1000);
+ var from = Math.ceil(dateMath.parse(options.range.from) / 1000);
+ var to = Math.ceil(dateMath.parse(options.range.to) / 1000);
+ var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);
// Create request for each target
var promises = _.map(options.targets, function(target) {
@@ -330,8 +330,8 @@ export class ZabbixAPIDatasource {
/////////////////
annotationQuery(options) {
- var from = Math.ceil(dateMathParse(options.rangeRaw.from) / 1000);
- var to = Math.ceil(dateMathParse(options.rangeRaw.to) / 1000);
+ var from = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);
+ var to = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);
var annotation = options.annotation;
var self = this;
var showEvents = annotation.showOkEvents ? [0, 1] : 1;
@@ -347,9 +347,9 @@ export class ZabbixAPIDatasource {
.then(function(triggers) {
// Filter triggers by description
- if (Utils.isRegex(annotation.trigger)) {
+ if (utils.isRegex(annotation.trigger)) {
triggers = _.filter(triggers, function(trigger) {
- return Utils.buildRegex(annotation.trigger).test(trigger.description);
+ return utils.buildRegex(annotation.trigger).test(trigger.description);
});
} else if (annotation.trigger) {
triggers = _.filter(triggers, function(trigger) {
@@ -393,7 +393,7 @@ export class ZabbixAPIDatasource {
// Show event type (OK or Problem)
title += Number(e.value) ? 'Problem' : 'OK';
- var formatted_acknowledges = Utils.formatAcknowledges(e.acknowledges);
+ var formatted_acknowledges = utils.formatAcknowledges(e.acknowledges);
return {
annotation: annotation,
time: e.clock * 1000,
diff --git a/src/datasource-zabbix/queryCtrl.js b/src/datasource-zabbix/queryCtrl.js
index 6f927c3..935fc7a 100644
--- a/src/datasource-zabbix/queryCtrl.js
+++ b/src/datasource-zabbix/queryCtrl.js
@@ -1,242 +1,237 @@
-define([
+/*define([
'app/plugins/sdk',
'angular',
'lodash',
'./metricFunctions',
'./utils'
-],
-function (sdk, angular, _, metricFunctions, utils) {
- 'use strict';
+],*/
- var ZabbixQueryCtrl = (function(_super) {
+import {QueryCtrl} from 'app/plugins/sdk';
+import _ from 'lodash';
+import * as utils from './utils';
+import metricFunctions from './metricFunctions';
- // ZabbixQueryCtrl constructor
- function ZabbixQueryCtrl($scope, $injector, $sce, $q, templateSrv) {
+export class ZabbixQueryCtrl extends QueryCtrl {
- // Call superclass constructor
- _super.call(this, $scope, $injector);
+ // ZabbixQueryCtrl constructor
+ constructor($scope, $injector, $sce, $q, templateSrv) {
- this.editorModes = {
- 0: 'num',
- 1: 'itservice',
- 2: 'text'
+ // Call superclass constructor
+ super($scope, $injector);
+
+ this.editorModes = {
+ 0: 'num',
+ 1: 'itservice',
+ 2: 'text'
+ };
+
+ // Map functions for bs-typeahead
+ this.getGroupNames = _.partial(getMetricNames, this, 'groupList');
+ this.getHostNames = _.partial(getMetricNames, this, 'filteredHosts');
+ this.getApplicationNames = _.partial(getMetricNames, this, 'filteredApplications');
+ this.getItemNames = _.partial(getMetricNames, this, 'filteredItems');
+
+ this.init = function() {
+
+ this.templateSrv = templateSrv;
+ var target = this.target;
+
+ var scopeDefaults = {
+ metric: {}
};
+ _.defaults(this, scopeDefaults);
- // Map functions for bs-typeahead
- this.getGroupNames = _.partial(getMetricNames, this, 'groupList');
- this.getHostNames = _.partial(getMetricNames, this, 'filteredHosts');
- this.getApplicationNames = _.partial(getMetricNames, this, 'filteredApplications');
- this.getItemNames = _.partial(getMetricNames, this, 'filteredItems');
-
- this.init = function() {
-
- this.templateSrv = templateSrv;
- var target = this.target;
-
- var scopeDefaults = {
- metric: {}
- };
- _.defaults(this, scopeDefaults);
-
- // Load default values
- var targetDefaults = {
- mode: 0,
- group: { filter: "" },
- host: { filter: "" },
- application: { filter: "" },
- item: { filter: "" },
- functions: [],
- };
- _.defaults(target, targetDefaults);
-
- // Create function instances from saved JSON
- target.functions = _.map(target.functions, function(func) {
- return metricFunctions.createFuncInstance(func.def, func.params);
- });
-
- if (target.mode === 0 ||
- target.mode === 2) {
-
- this.downsampleFunctionList = [
- {name: "avg", value: "avg"},
- {name: "min", value: "min"},
- {name: "max", value: "max"}
- ];
-
- // Set avg by default
- if (!target.downsampleFunction) {
- target.downsampleFunction = this.downsampleFunctionList[0];
- }
-
- this.initFilters();
- }
- else if (target.mode === 1) {
- 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();
- }
+ // Load default values
+ var targetDefaults = {
+ mode: 0,
+ group: { filter: "" },
+ host: { filter: "" },
+ application: { filter: "" },
+ item: { filter: "" },
+ functions: [],
};
+ _.defaults(target, targetDefaults);
- this.init();
- }
-
- ZabbixQueryCtrl.templateUrl = 'partials/query.editor.html';
-
- ZabbixQueryCtrl.prototype = Object.create(_super.prototype);
- ZabbixQueryCtrl.prototype.constructor = ZabbixQueryCtrl;
-
- var p = ZabbixQueryCtrl.prototype;
-
- p.initFilters = function () {
- this.filterGroups();
- this.filterHosts();
- this.filterApplications();
- this.filterItems();
- };
-
- p.filterHosts = function () {
- var self = this;
- var groupFilter = this.templateSrv.replace(this.target.group.filter);
- this.datasource.queryProcessor.filterHosts(groupFilter).then(function(hosts) {
- self.metric.filteredHosts = hosts;
+ // Create function instances from saved JSON
+ target.functions = _.map(target.functions, function(func) {
+ return metricFunctions.createFuncInstance(func.def, func.params);
});
- };
- p.filterGroups = function() {
- var self = this;
- this.datasource.queryProcessor.filterGroups().then(function(groups) {
- self.metric.groupList = groups;
- });
- };
+ if (target.mode === 0 ||
+ target.mode === 2) {
- p.filterApplications = function () {
- var self = this;
- var groupFilter = this.templateSrv.replace(this.target.group.filter);
- var hostFilter = this.templateSrv.replace(this.target.host.filter);
- this.datasource.queryProcessor.filterApplications(groupFilter, hostFilter)
- .then(function(apps) {
- self.metric.filteredApplications = apps;
- });
- };
+ this.downsampleFunctionList = [
+ {name: "avg", value: "avg"},
+ {name: "min", value: "min"},
+ {name: "max", value: "max"}
+ ];
- p.filterItems = function () {
- var self = this;
- var item_type = this.editorModes[this.target.mode];
- var groupFilter = this.templateSrv.replace(this.target.group.filter);
- var hostFilter = this.templateSrv.replace(this.target.host.filter);
- var appFilter = this.templateSrv.replace(this.target.application.filter);
- this.datasource.queryProcessor.filterItems(groupFilter, hostFilter, appFilter,
- item_type, this.target.showDisabledItems).then(function(items) {
- self.metric.filteredItems = items;
- });
- };
+ // Set avg by default
+ if (!target.downsampleFunction) {
+ target.downsampleFunction = this.downsampleFunctionList[0];
+ }
- p.onTargetPartChange = function (targetPart) {
- var regexStyle = {'color': '#CCA300'};
- targetPart.isRegex = utils.isRegex(targetPart.filter);
- targetPart.style = targetPart.isRegex ? regexStyle : {};
- };
-
- p.onTargetBlur = function() {
- this.initFilters();
- this.parseTarget();
- this.panelCtrl.refresh();
- };
-
- p.parseTarget = function() {
- // Parse target
- };
-
- // Validate target and set validation info
- p.validateTarget = function () {};
-
- p.targetChanged = function() {
- this.panelCtrl.refresh();
- };
-
- p.addFunction = function(funcDef) {
- var newFunc = metricFunctions.createFuncInstance(funcDef);
- newFunc.added = true;
- this.target.functions.push(newFunc);
-
- this.moveAliasFuncLast();
-
- if (newFunc.params.length && newFunc.added ||
- newFunc.def.params.length === 0) {
- this.targetChanged();
+ this.initFilters();
+ }
+ else if (target.mode === 1) {
+ 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();
}
};
- p.removeFunction = function(func) {
- this.target.functions = _.without(this.target.functions, func);
- this.targetChanged();
- };
-
- p.moveAliasFuncLast = function() {
- var aliasFunc = _.find(this.target.functions, function(func) {
- return func.def.name === 'alias' ||
- func.def.name === 'aliasByNode' ||
- func.def.name === 'aliasByMetric';
- });
-
- if (aliasFunc) {
- this.target.functions = _.without(this.target.functions, aliasFunc);
- this.target.functions.push(aliasFunc);
- }
- };
-
- /**
- * Switch query editor to specified mode.
- * Modes:
- * 0 - items
- * 1 - IT services
- * 2 - Text metrics
- */
- p.switchEditorMode = function (mode) {
- this.target.mode = mode;
- this.init();
- };
-
- /////////////////
- // IT Services //
- /////////////////
-
- /**
- * Update list of IT services
- */
- p.updateITServiceList = function () {
- var self = this;
- this.datasource.zabbixAPI.getITService().then(function (iteservices) {
- self.itserviceList = [];
- self.itserviceList = self.itserviceList.concat(iteservices);
- });
- };
-
- /**
- * Call when IT service is selected.
- */
- p.selectITService = function () {
- if (!_.isEqual(this.oldTarget, this.target) && _.isEmpty(this.target.errors)) {
- this.oldTarget = angular.copy(this.target);
- this.panelCtrl.refresh();
- }
- };
-
- return ZabbixQueryCtrl;
-
- })(sdk.QueryCtrl);
-
- return ZabbixQueryCtrl;
-
- // Get list of metric names for bs-typeahead directive
- function getMetricNames(scope, metricList) {
- return _.uniq(_.map(scope.metric[metricList], 'name'));
+ this.init();
}
-});
\ No newline at end of file
+ initFilters() {
+ this.filterGroups();
+ this.filterHosts();
+ this.filterApplications();
+ this.filterItems();
+ }
+
+ filterHosts() {
+ var self = this;
+ var groupFilter = this.templateSrv.replace(this.target.group.filter);
+ this.datasource.queryProcessor.filterHosts(groupFilter).then(function(hosts) {
+ self.metric.filteredHosts = hosts;
+ });
+ }
+
+ filterGroups() {
+ var self = this;
+ this.datasource.queryProcessor.filterGroups().then(function(groups) {
+ self.metric.groupList = groups;
+ });
+ }
+
+ filterApplications() {
+ var self = this;
+ var groupFilter = this.templateSrv.replace(this.target.group.filter);
+ var hostFilter = this.templateSrv.replace(this.target.host.filter);
+ this.datasource.queryProcessor.filterApplications(groupFilter, hostFilter)
+ .then(function(apps) {
+ self.metric.filteredApplications = apps;
+ });
+ }
+
+ filterItems() {
+ var self = this;
+ var item_type = this.editorModes[this.target.mode];
+ var groupFilter = this.templateSrv.replace(this.target.group.filter);
+ var hostFilter = this.templateSrv.replace(this.target.host.filter);
+ var appFilter = this.templateSrv.replace(this.target.application.filter);
+ this.datasource.queryProcessor.filterItems(groupFilter, hostFilter, appFilter,
+ item_type, this.target.showDisabledItems).then(function(items) {
+ self.metric.filteredItems = items;
+ });
+ }
+
+ onTargetPartChange(targetPart) {
+ var regexStyle = {'color': '#CCA300'};
+ targetPart.isRegex = utils.isRegex(targetPart.filter);
+ targetPart.style = targetPart.isRegex ? regexStyle : {};
+ }
+
+ onTargetBlur() {
+ this.initFilters();
+ this.parseTarget();
+ this.panelCtrl.refresh();
+ }
+
+ parseTarget() {
+ // Parse target
+ }
+
+ // Validate target and set validation info
+ validateTarget() {
+ // validate
+ }
+
+ targetChanged() {
+ this.panelCtrl.refresh();
+ }
+
+ addFunction(funcDef) {
+ var newFunc = metricFunctions.createFuncInstance(funcDef);
+ newFunc.added = true;
+ this.target.functions.push(newFunc);
+
+ this.moveAliasFuncLast();
+
+ if (newFunc.params.length && newFunc.added ||
+ newFunc.def.params.length === 0) {
+ this.targetChanged();
+ }
+ }
+
+ removeFunction(func) {
+ this.target.functions = _.without(this.target.functions, func);
+ this.targetChanged();
+ }
+
+ moveAliasFuncLast() {
+ var aliasFunc = _.find(this.target.functions, function(func) {
+ return func.def.name === 'alias' ||
+ func.def.name === 'aliasByNode' ||
+ func.def.name === 'aliasByMetric';
+ });
+
+ if (aliasFunc) {
+ this.target.functions = _.without(this.target.functions, aliasFunc);
+ this.target.functions.push(aliasFunc);
+ }
+ }
+
+ /**
+ * Switch query editor to specified mode.
+ * Modes:
+ * 0 - items
+ * 1 - IT services
+ * 2 - Text metrics
+ */
+ switchEditorMode(mode) {
+ this.target.mode = mode;
+ this.init();
+ }
+
+ /////////////////
+ // IT Services //
+ /////////////////
+
+ /**
+ * Update list of IT services
+ */
+ updateITServiceList() {
+ var self = this;
+ this.datasource.zabbixAPI.getITService().then(function (iteservices) {
+ self.itserviceList = [];
+ self.itserviceList = self.itserviceList.concat(iteservices);
+ });
+ }
+
+ /**
+ * Call when IT service is selected.
+ */
+ selectITService() {
+ if (!_.isEqual(this.oldTarget, this.target) && _.isEmpty(this.target.errors)) {
+ this.oldTarget = angular.copy(this.target);
+ this.panelCtrl.refresh();
+ }
+ }
+
+}
+
+// Set templateUrl as static property
+ZabbixQueryCtrl.templateUrl = 'partials/query.editor.html';
+
+// Get list of metric names for bs-typeahead directive
+function getMetricNames(scope, metricList) {
+ return _.uniq(_.map(scope.metric[metricList], 'name'));
+}
\ No newline at end of file
diff --git a/src/datasource-zabbix/utils.js b/src/datasource-zabbix/utils.js
index c92c616..ff36135 100644
--- a/src/datasource-zabbix/utils.js
+++ b/src/datasource-zabbix/utils.js
@@ -1,77 +1,67 @@
-define([
- 'lodash',
- 'moment'
-],
-function (_, moment) {
- 'use strict';
+import _ from 'lodash';
+import moment from 'moment';
- function Utils() {
- /**
- * Expand Zabbix item name
- *
- * @param {string} name item name, ie "CPU $2 time"
- * @param {string} key item key, ie system.cpu.util[,system,avg1]
- * @return {string} expanded name, ie "CPU system time"
- */
- this.expandItemName = function(name, key) {
+/**
+ * Expand Zabbix item name
+ *
+ * @param {string} name item name, ie "CPU $2 time"
+ * @param {string} key item key, ie system.cpu.util[,system,avg1]
+ * @return {string} expanded name, ie "CPU system time"
+ */
+export function expandItemName(name, key) {
- // extract params from key:
- // "system.cpu.util[,system,avg1]" --> ["", "system", "avg1"]
- var key_params = key.substring(key.indexOf('[') + 1, key.lastIndexOf(']')).split(',');
-
- // replace item parameters
- for (var i = key_params.length; i >= 1; i--) {
- name = name.replace('$' + i, key_params[i - 1]);
- }
- return name;
- };
-
- // Pattern for testing regex
- var regexPattern = /^\/(.*)\/([gmi]*)$/m;
-
- this.isRegex = function (str) {
- return regexPattern.test(str);
- };
-
- this.buildRegex = function (str) {
- var matches = str.match(regexPattern);
- var pattern = matches[1];
- var flags = matches[2] !== "" ? matches[2] : undefined;
- return new RegExp(pattern, flags);
- };
-
- this.parseInterval = function(interval) {
- var intervalPattern = /(^[\d]+)(y|M|w|d|h|m|s)/g;
- var momentInterval = intervalPattern.exec(interval);
- return moment.duration(Number(momentInterval[1]), momentInterval[2]).valueOf();
- };
-
- /**
- * 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:
| Time | '
- + 'User | Comments |
';
- _.each(_.map(acknowledges, function (ack) {
- var timestamp = moment.unix(ack.clock);
- return '| ' + timestamp.format("DD MMM YYYY HH:mm:ss") + ' | ' + ack.alias
- + ' (' + ack.name + ' ' + ack.surname + ')' + ' | ' + ack.message + ' |
';
- }), function (ack) {
- formatted_acknowledges = formatted_acknowledges.concat(ack);
- });
- formatted_acknowledges = formatted_acknowledges.concat('
');
- return formatted_acknowledges;
- } else {
- return '';
- }
- };
+ // extract params from key:
+ // "system.cpu.util[,system,avg1]" --> ["", "system", "avg1"]
+ var key_params = key.substring(key.indexOf('[') + 1, key.lastIndexOf(']')).split(',');
+ // replace item parameters
+ for (var i = key_params.length; i >= 1; i--) {
+ name = name.replace('$' + i, key_params[i - 1]);
}
+ return name;
+}
- return new Utils();
-});
\ No newline at end of file
+// Pattern for testing regex
+var regexPattern = /^\/(.*)\/([gmi]*)$/m;
+
+export function isRegex(str) {
+ return regexPattern.test(str);
+}
+
+export function buildRegex(str) {
+ var matches = str.match(regexPattern);
+ var pattern = matches[1];
+ var flags = matches[2] !== "" ? matches[2] : undefined;
+ return new RegExp(pattern, flags);
+}
+
+export function parseInterval(interval) {
+ var intervalPattern = /(^[\d]+)(y|M|w|d|h|m|s)/g;
+ var momentInterval = intervalPattern.exec(interval);
+ return moment.duration(Number(momentInterval[1]), momentInterval[2]).valueOf();
+}
+
+/**
+ * Format acknowledges.
+ *
+ * @param {array} acknowledges array of Zabbix acknowledge objects
+ * @return {string} HTML-formatted table
+ */
+export function formatAcknowledges(acknowledges) {
+ if (acknowledges.length) {
+ var formatted_acknowledges = '
Acknowledges:
| Time | '
+ + 'User | Comments |
';
+ _.each(_.map(acknowledges, function (ack) {
+ var timestamp = moment.unix(ack.clock);
+ return '| ' + timestamp.format("DD MMM YYYY HH:mm:ss") + ' | ' + ack.alias
+ + ' (' + ack.name + ' ' + ack.surname + ')' + ' | ' + ack.message + ' |
';
+ }), function (ack) {
+ formatted_acknowledges = formatted_acknowledges.concat(ack);
+ });
+ formatted_acknowledges = formatted_acknowledges.concat('
');
+ return formatted_acknowledges;
+ } else {
+ return '';
+ }
+}