Triggers query mode, allow to get active triggers count, #141

This commit is contained in:
Alexander Zobnin
2017-10-22 14:30:54 +03:00
parent dacc3f3576
commit 6c64f21b1a
26 changed files with 458 additions and 88 deletions

View File

@@ -3,7 +3,7 @@
System.register([], function (_export, _context) { System.register([], function (_export, _context) {
"use strict"; "use strict";
var MODE_METRICS, MODE_ITSERVICE, MODE_TEXT, MODE_ITEMID, SEV_NOT_CLASSIFIED, SEV_INFORMATION, SEV_WARNING, SEV_AVERAGE, SEV_HIGH, SEV_DISASTER, SHOW_ALL_TRIGGERS, SHOW_ALL_EVENTS, SHOW_OK_EVENTS, DATAPOINT_VALUE, DATAPOINT_TS; var MODE_METRICS, MODE_ITSERVICE, MODE_TEXT, MODE_ITEMID, MODE_TRIGGERS, SEV_NOT_CLASSIFIED, SEV_INFORMATION, SEV_WARNING, SEV_AVERAGE, SEV_HIGH, SEV_DISASTER, SHOW_ALL_TRIGGERS, SHOW_ALL_EVENTS, SHOW_OK_EVENTS, DATAPOINT_VALUE, DATAPOINT_TS;
return { return {
setters: [], setters: [],
execute: function () { execute: function () {
@@ -23,6 +23,10 @@ System.register([], function (_export, _context) {
_export("MODE_ITEMID", MODE_ITEMID); _export("MODE_ITEMID", MODE_ITEMID);
_export("MODE_TRIGGERS", MODE_TRIGGERS = 4);
_export("MODE_TRIGGERS", MODE_TRIGGERS);
_export("SEV_NOT_CLASSIFIED", SEV_NOT_CLASSIFIED = 0); _export("SEV_NOT_CLASSIFIED", SEV_NOT_CLASSIFIED = 0);
_export("SEV_NOT_CLASSIFIED", SEV_NOT_CLASSIFIED); _export("SEV_NOT_CLASSIFIED", SEV_NOT_CLASSIFIED);

View File

@@ -1 +1 @@
{"version":3,"sources":["../../src/datasource-zabbix/constants.js"],"names":["MODE_METRICS","MODE_ITSERVICE","MODE_TEXT","MODE_ITEMID","SEV_NOT_CLASSIFIED","SEV_INFORMATION","SEV_WARNING","SEV_AVERAGE","SEV_HIGH","SEV_DISASTER","SHOW_ALL_TRIGGERS","SHOW_ALL_EVENTS","SHOW_OK_EVENTS","DATAPOINT_VALUE","DATAPOINT_TS"],"mappings":";;;;;;;;;8BACaA,Y,GAAe,C;;;;gCACfC,c,GAAiB,C;;;;2BACjBC,S,GAAY,C;;;;6BACZC,W,GAAc,C;;;;oCAGdC,kB,GAAqB,C;;;;iCACrBC,e,GAAkB,C;;;;6BAClBC,W,GAAc,C;;;;6BACdC,W,GAAc,C;;;;0BACdC,Q,GAAW,C;;;;8BACXC,Y,GAAe,C;;;;mCAEfC,iB,GAAoB,CAAC,CAAD,EAAI,CAAJ,C;;;;iCACpBC,e,GAAkB,CAAC,CAAD,EAAI,CAAJ,C;;;;gCAClBC,c,GAAiB,C;;;;iCAGjBC,e,GAAkB,C;;;;8BAClBC,Y,GAAe,C","file":"constants.js","sourcesContent":["// Editor modes\nexport const MODE_METRICS = 0;\nexport const MODE_ITSERVICE = 1;\nexport const MODE_TEXT = 2;\nexport const MODE_ITEMID = 3;\n\n// Triggers severity\nexport const SEV_NOT_CLASSIFIED = 0;\nexport const SEV_INFORMATION = 1;\nexport const SEV_WARNING = 2;\nexport const SEV_AVERAGE = 3;\nexport const SEV_HIGH = 4;\nexport const SEV_DISASTER = 5;\n\nexport const SHOW_ALL_TRIGGERS = [0, 1];\nexport const SHOW_ALL_EVENTS = [0, 1];\nexport const SHOW_OK_EVENTS = 1;\n\n// Data point\nexport const DATAPOINT_VALUE = 0;\nexport const DATAPOINT_TS = 1;\n"]} {"version":3,"sources":["../../src/datasource-zabbix/constants.js"],"names":["MODE_METRICS","MODE_ITSERVICE","MODE_TEXT","MODE_ITEMID","MODE_TRIGGERS","SEV_NOT_CLASSIFIED","SEV_INFORMATION","SEV_WARNING","SEV_AVERAGE","SEV_HIGH","SEV_DISASTER","SHOW_ALL_TRIGGERS","SHOW_ALL_EVENTS","SHOW_OK_EVENTS","DATAPOINT_VALUE","DATAPOINT_TS"],"mappings":";;;;;;;;;8BACaA,Y,GAAe,C;;;;gCACfC,c,GAAiB,C;;;;2BACjBC,S,GAAY,C;;;;6BACZC,W,GAAc,C;;;;+BACdC,a,GAAgB,C;;;;oCAGhBC,kB,GAAqB,C;;;;iCACrBC,e,GAAkB,C;;;;6BAClBC,W,GAAc,C;;;;6BACdC,W,GAAc,C;;;;0BACdC,Q,GAAW,C;;;;8BACXC,Y,GAAe,C;;;;mCAEfC,iB,GAAoB,CAAC,CAAD,EAAI,CAAJ,C;;;;iCACpBC,e,GAAkB,CAAC,CAAD,EAAI,CAAJ,C;;;;gCAClBC,c,GAAiB,C;;;;iCAGjBC,e,GAAkB,C;;;;8BAClBC,Y,GAAe,C","file":"constants.js","sourcesContent":["// Editor modes\nexport const MODE_METRICS = 0;\nexport const MODE_ITSERVICE = 1;\nexport const MODE_TEXT = 2;\nexport const MODE_ITEMID = 3;\nexport const MODE_TRIGGERS = 4;\n\n// Triggers severity\nexport const SEV_NOT_CLASSIFIED = 0;\nexport const SEV_INFORMATION = 1;\nexport const SEV_WARNING = 2;\nexport const SEV_AVERAGE = 3;\nexport const SEV_HIGH = 4;\nexport const SEV_DISASTER = 5;\n\nexport const SHOW_ALL_TRIGGERS = [0, 1];\nexport const SHOW_ALL_EVENTS = [0, 1];\nexport const SHOW_OK_EVENTS = 1;\n\n// Data point\nexport const DATAPOINT_VALUE = 0;\nexport const DATAPOINT_TS = 1;\n"]}

View File

@@ -337,6 +337,10 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
} else if (target.mode === c.MODE_ITSERVICE) { } else if (target.mode === c.MODE_ITSERVICE) {
// IT services mode // IT services mode
return _this.queryITServiceData(target, timeRange, options); return _this.queryITServiceData(target, timeRange, options);
} else if (target.mode === c.MODE_TRIGGERS) {
return _this.queryTriggersData(target, timeRange);
} else {
return [];
} }
}); });
@@ -558,18 +562,43 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
}); });
}); });
} }
}, {
key: 'queryTriggersData',
value: function queryTriggersData(target, timeRange) {
var _this7 = this;
var _timeRange3 = _slicedToArray(timeRange, 2),
timeFrom = _timeRange3[0],
timeTo = _timeRange3[1];
return this.zabbix.getHostsFromTarget(target).then(function (results) {
var _results = _slicedToArray(results, 2),
hosts = _results[0],
apps = _results[1];
if (hosts.length) {
var hostids = _.map(hosts, 'hostid');
var appids = _.map(apps, 'applicationid');
return _this7.zabbix.getHostAlerts(hostids, appids, target.minSeverity, target.options.countTriggers, timeFrom, timeTo).then(function (triggers) {
return responseHandler.handleTriggersResponse(triggers, timeRange);
});
} else {
return Promise.resolve([]);
}
});
}
}, { }, {
key: 'testDatasource', key: 'testDatasource',
value: function testDatasource() { value: function testDatasource() {
var _this7 = this; var _this8 = this;
var zabbixVersion = void 0; var zabbixVersion = void 0;
return this.zabbix.getVersion().then(function (version) { return this.zabbix.getVersion().then(function (version) {
zabbixVersion = version; zabbixVersion = version;
return _this7.zabbix.login(); return _this8.zabbix.login();
}).then(function () { }).then(function () {
if (_this7.enableDirectDBConnection) { if (_this8.enableDirectDBConnection) {
return _this7.zabbix.dbConnector.testSQLDataSource(); return _this8.zabbix.dbConnector.testSQLDataSource();
} else { } else {
return Promise.resolve(); return Promise.resolve();
} }
@@ -604,14 +633,14 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
}, { }, {
key: 'metricFindQuery', key: 'metricFindQuery',
value: function metricFindQuery(query) { value: function metricFindQuery(query) {
var _this8 = this; var _this9 = this;
var result = void 0; var result = void 0;
var parts = []; var parts = [];
// Split query. Query structure: group.host.app.item // Split query. Query structure: group.host.app.item
_.each(utils.splitTemplateQuery(query), function (part) { _.each(utils.splitTemplateQuery(query), function (part) {
part = _this8.replaceTemplateVars(part, {}); part = _this9.replaceTemplateVars(part, {});
// Replace wildcard to regex // Replace wildcard to regex
if (part === '*') { if (part === '*') {
@@ -648,7 +677,7 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
}, { }, {
key: 'annotationQuery', key: 'annotationQuery',
value: function annotationQuery(options) { value: function annotationQuery(options) {
var _this9 = this; var _this10 = this;
var timeFrom = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000); var timeFrom = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);
var timeTo = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000); var timeTo = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);
@@ -666,7 +695,7 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
return getTriggers.then(function (triggers) { return getTriggers.then(function (triggers) {
// Filter triggers by description // Filter triggers by description
var triggerName = _this9.replaceTemplateVars(annotation.trigger, {}); var triggerName = _this10.replaceTemplateVars(annotation.trigger, {});
if (utils.isRegex(triggerName)) { if (utils.isRegex(triggerName)) {
triggers = _.filter(triggers, function (trigger) { triggers = _.filter(triggers, function (trigger) {
return utils.buildRegex(triggerName).test(trigger.description); return utils.buildRegex(triggerName).test(trigger.description);
@@ -683,7 +712,7 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
}); });
var objectids = _.map(triggers, 'triggerid'); var objectids = _.map(triggers, 'triggerid');
return _this9.zabbix.getEvents(objectids, timeFrom, timeTo, showOkEvents).then(function (events) { return _this10.zabbix.getEvents(objectids, timeFrom, timeTo, showOkEvents).then(function (events) {
var indexedTriggers = _.keyBy(triggers, 'triggerid'); var indexedTriggers = _.keyBy(triggers, 'triggerid');
// Hide acknowledged events if option enabled // Hide acknowledged events if option enabled
@@ -717,23 +746,23 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
}, { }, {
key: 'alertQuery', key: 'alertQuery',
value: function alertQuery(options) { value: function alertQuery(options) {
var _this10 = this; var _this11 = this;
var enabled_targets = filterEnabledTargets(options.targets); var enabled_targets = filterEnabledTargets(options.targets);
var getPanelItems = _.map(enabled_targets, function (t) { var getPanelItems = _.map(enabled_targets, function (t) {
var target = _.cloneDeep(t); var target = _.cloneDeep(t);
_this10.replaceTargetVariables(target, options); _this11.replaceTargetVariables(target, options);
return _this10.zabbix.getItemsFromTarget(target, { itemtype: 'num' }); return _this11.zabbix.getItemsFromTarget(target, { itemtype: 'num' });
}); });
return Promise.all(getPanelItems).then(function (results) { return Promise.all(getPanelItems).then(function (results) {
var items = _.flatten(results); var items = _.flatten(results);
var itemids = _.map(items, 'itemid'); var itemids = _.map(items, 'itemid');
return _this10.zabbix.getAlerts(itemids); return _this11.zabbix.getAlerts(itemids);
}).then(function (triggers) { }).then(function (triggers) {
triggers = _.filter(triggers, function (trigger) { triggers = _.filter(triggers, function (trigger) {
return trigger.priority >= _this10.alertingMinSeverity; return trigger.priority >= _this11.alertingMinSeverity;
}); });
if (!triggers || triggers.length === 0) { if (!triggers || triggers.length === 0) {
@@ -761,12 +790,12 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
}, { }, {
key: 'replaceTargetVariables', key: 'replaceTargetVariables',
value: function replaceTargetVariables(target, options) { value: function replaceTargetVariables(target, options) {
var _this11 = this; var _this12 = this;
var parts = ['group', 'host', 'application', 'item']; var parts = ['group', 'host', 'application', 'item'];
_.forEach(parts, function (p) { _.forEach(parts, function (p) {
if (target[p] && target[p].filter) { if (target[p] && target[p].filter) {
target[p].filter = _this11.replaceTemplateVars(target[p].filter, options.scopedVars); target[p].filter = _this12.replaceTemplateVars(target[p].filter, options.scopedVars);
} }
}); });
target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars); target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars);
@@ -774,9 +803,9 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
_.forEach(target.functions, function (func) { _.forEach(target.functions, function (func) {
func.params = _.map(func.params, function (param) { func.params = _.map(func.params, function (param) {
if (typeof param === 'number') { if (typeof param === 'number') {
return +_this11.templateSrv.replace(param.toString(), options.scopedVars); return +_this12.templateSrv.replace(param.toString(), options.scopedVars);
} else { } else {
return _this11.templateSrv.replace(param, options.scopedVars); return _this12.templateSrv.replace(param, options.scopedVars);
} }
}); });
}); });
@@ -784,9 +813,9 @@ System.register(['lodash', 'app/core/utils/datemath', './utils', './migrations',
}, { }, {
key: 'isUseTrends', key: 'isUseTrends',
value: function isUseTrends(timeRange) { value: function isUseTrends(timeRange) {
var _timeRange3 = _slicedToArray(timeRange, 2), var _timeRange4 = _slicedToArray(timeRange, 2),
timeFrom = _timeRange3[0], timeFrom = _timeRange4[0],
timeTo = _timeRange3[1]; timeTo = _timeRange4[1];
var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000); var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);
var useTrendsRange = Math.ceil(utils.parseInterval(this.trendsRange) / 1000); var useTrendsRange = Math.ceil(utils.parseInterval(this.trendsRange) / 1000);

File diff suppressed because one or more lines are too long

View File

@@ -48,7 +48,7 @@
</div> </div>
</div> </div>
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT"> <div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT || ctrl.target.mode == editorMode.TRIGGERS">
<!-- Select Group --> <!-- Select Group -->
<div class="gf-form max-width-20"> <div class="gf-form max-width-20">
<label class="gf-form-label query-keyword width-7">Group</label> <label class="gf-form-label query-keyword width-7">Group</label>
@@ -66,7 +66,7 @@
</div> </div>
<!-- Select Host --> <!-- Select Host -->
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label query-keyword width-7">Host</label> <label class="gf-form-label query-keyword width-8">Host</label>
<input type="text" <input type="text"
ng-model="ctrl.target.host.filter" ng-model="ctrl.target.host.filter"
bs-typeahead="ctrl.getHostNames" bs-typeahead="ctrl.getHostNames"
@@ -85,7 +85,7 @@
</div> </div>
</div> </div>
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT"> <div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT || ctrl.target.mode == editorMode.TRIGGERS">
<!-- Select Application --> <!-- Select Application -->
<div class="gf-form max-width-20"> <div class="gf-form max-width-20">
<label class="gf-form-label query-keyword width-7">Application</label> <label class="gf-form-label query-keyword width-7">Application</label>
@@ -103,8 +103,8 @@
</div> </div>
<!-- Select Item --> <!-- Select Item -->
<div class="gf-form"> <div class="gf-form" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT">
<label class="gf-form-label query-keyword width-7">Item</label> <label class="gf-form-label query-keyword width-8">Item</label>
<input type="text" <input type="text"
ng-model="ctrl.target.item.filter" ng-model="ctrl.target.item.filter"
bs-typeahead="ctrl.getItemNames" bs-typeahead="ctrl.getItemNames"
@@ -117,6 +117,18 @@
'zbx-regex': ctrl.isRegex(ctrl.target.item.filter) 'zbx-regex': ctrl.isRegex(ctrl.target.item.filter)
}"> }">
</div> </div>
<div class="gf-form max-width-20" ng-show="ctrl.target.mode == editorMode.TRIGGERS">
<label class="gf-form-label query-keyword width-8">Min Severity</label>
<div class="gf-form-select-wrapper width-20">
<select class="gf-form-input"
ng-change="ctrl.onTargetBlur()"
ng-model="ctrl.target.minSeverity"
ng-options="s.val as s.text for s in ctrl.triggerSeverity">
</select>
</div>
</div>
<div class="gf-form gf-form--grow"> <div class="gf-form gf-form--grow">
<label class="gf-form-label gf-form-label--grow"> <label class="gf-form-label gf-form-label--grow">
<a ng-click="ctrl.toggleQueryOptions()"> <a ng-click="ctrl.toggleQueryOptions()">
@@ -130,13 +142,20 @@
<!-- Query options --> <!-- Query options -->
<div class="gf-form-group" ng-if="ctrl.showQueryOptions"> <div class="gf-form-group" ng-if="ctrl.showQueryOptions">
<div class="gf-form offset-width-7"> <div class="gf-form offset-width-7" ng-hide="ctrl.target.mode == editorMode.TRIGGERS">
<gf-form-switch class="gf-form" <gf-form-switch class="gf-form"
label="Show disabled items" label="Show disabled items"
checked="ctrl.target.options.showDisabledItems" checked="ctrl.target.options.showDisabledItems"
on-change="ctrl.onQueryOptionChange()"> on-change="ctrl.onQueryOptionChange()">
</gf-form-switch> </gf-form-switch>
</div> </div>
<div class="gf-form offset-width-7" ng-show="ctrl.target.mode == editorMode.TRIGGERS">
<gf-form-switch class="gf-form"
label="Count triggers"
checked="ctrl.target.options.countTriggers"
on-change="ctrl.onQueryOptionChange()">
</gf-form-switch>
</div>
</div> </div>
<!-- Item IDs editor mode --> <!-- Item IDs editor mode -->

View File

@@ -83,17 +83,20 @@ System.register(['app/plugins/sdk', 'lodash', './constants', './utils', './metri
_this.replaceTemplateVars = _this.datasource.replaceTemplateVars; _this.replaceTemplateVars = _this.datasource.replaceTemplateVars;
_this.templateSrv = templateSrv; _this.templateSrv = templateSrv;
_this.editorModes = [{ value: 'num', text: 'Metrics', mode: c.MODE_METRICS }, { value: 'text', text: 'Text', mode: c.MODE_TEXT }, { value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE }, { value: 'itemid', text: 'Item ID', mode: c.MODE_ITEMID }]; _this.editorModes = [{ value: 'num', text: 'Metrics', mode: c.MODE_METRICS }, { value: 'text', text: 'Text', mode: c.MODE_TEXT }, { value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE }, { value: 'itemid', text: 'Item ID', mode: c.MODE_ITEMID }, { value: 'triggers', text: 'Triggers', mode: c.MODE_TRIGGERS }];
_this.$scope.editorMode = { _this.$scope.editorMode = {
METRICS: c.MODE_METRICS, METRICS: c.MODE_METRICS,
TEXT: c.MODE_TEXT, TEXT: c.MODE_TEXT,
ITSERVICE: c.MODE_ITSERVICE, ITSERVICE: c.MODE_ITSERVICE,
ITEMID: c.MODE_ITEMID ITEMID: c.MODE_ITEMID,
TRIGGERS: c.MODE_TRIGGERS
}; };
_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.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.triggerSeverity = [{ val: 0, text: 'Not classified' }, { val: 1, text: 'Information' }, { val: 2, text: 'Warning' }, { val: 3, text: 'Average' }, { val: 4, text: 'High' }, { val: 5, text: 'Disaster' }];
// Map functions for bs-typeahead // Map functions for bs-typeahead
_this.getGroupNames = _.bind(_this.getMetricNames, _this, 'groupList'); _this.getGroupNames = _.bind(_this.getMetricNames, _this, 'groupList');
_this.getHostNames = _.bind(_this.getMetricNames, _this, 'hostList', true); _this.getHostNames = _.bind(_this.getMetricNames, _this, 'hostList', true);
@@ -133,8 +136,10 @@ System.register(['app/plugins/sdk', 'lodash', './constants', './utils', './metri
'application': { 'filter': "" }, 'application': { 'filter': "" },
'item': { 'filter': "" }, 'item': { 'filter': "" },
'functions': [], 'functions': [],
'minSeverity': 3,
'options': { 'options': {
'showDisabledItems': false 'showDisabledItems': false,
'countTriggers': true
} }
}; };
_.defaults(target, targetDefaults); _.defaults(target, targetDefaults);
@@ -144,8 +149,7 @@ System.register(['app/plugins/sdk', 'lodash', './constants', './utils', './metri
return metricFunctions.createFuncInstance(func.def, func.params); return metricFunctions.createFuncInstance(func.def, func.params);
}); });
if (target.mode === c.MODE_METRICS || target.mode === c.MODE_TEXT) { if (target.mode === c.MODE_METRICS || target.mode === c.MODE_TEXT || target.mode === c.MODE_TRIGGERS) {
this.initFilters(); this.initFilters();
} else if (target.mode === c.MODE_ITSERVICE) { } else if (target.mode === c.MODE_ITSERVICE) {
_.defaults(target, { slaProperty: { name: "SLA", property: "sla" } }); _.defaults(target, { slaProperty: { name: "SLA", property: "sla" } });
@@ -154,6 +158,7 @@ System.register(['app/plugins/sdk', 'lodash', './constants', './utils', './metri
}; };
_this.init(); _this.init();
_this.queryOptionsText = _this.renderQueryOptionsText();
return _this; return _this;
} }
@@ -355,7 +360,8 @@ System.register(['app/plugins/sdk', 'lodash', './constants', './utils', './metri
key: 'renderQueryOptionsText', key: 'renderQueryOptionsText',
value: function renderQueryOptionsText() { value: function renderQueryOptionsText() {
var optionsMap = { var optionsMap = {
showDisabledItems: "Show disabled items" showDisabledItems: "Show disabled items",
countTriggers: "Count Triggers"
}; };
var options = []; var options = [];
_.forOwn(this.target.options, function (value, key) { _.forOwn(this.target.options, function (value, key) {

File diff suppressed because one or more lines are too long

View File

@@ -98,10 +98,21 @@ System.register(['lodash'], function (_export, _context) {
} }
} }
function convertHistoryPoint(point) { function handleTriggersResponse(triggers, timeRange) {
if (_.isNumber(triggers)) {
return {
target: "triggers count",
datapoints: [[triggers, timeRange[1]]]
};
} else {
return triggers;
}
}function convertHistoryPoint(point) {
// Value must be a number for properly work // Value must be a number for properly work
return [Number(point.value), point.clock * 1000 + Math.round(point.ns / 1000000)]; return [Number(point.value), point.clock * 1000 + Math.round(point.ns / 1000000)];
}function convertTrendPoint(valueType, point) { }
function convertTrendPoint(valueType, point) {
var value; var value;
switch (valueType) { switch (valueType) {
case "min": case "min":
@@ -124,9 +135,7 @@ System.register(['lodash'], function (_export, _context) {
} }
return [Number(value), point.clock * 1000]; return [Number(value), point.clock * 1000];
} }return {
return {
setters: [function (_lodash) { setters: [function (_lodash) {
_ = _lodash.default; _ = _lodash.default;
}], }],
@@ -136,7 +145,8 @@ System.register(['lodash'], function (_export, _context) {
convertHistory: convertHistory, convertHistory: convertHistory,
handleTrends: handleTrends, handleTrends: handleTrends,
handleText: handleText, handleText: handleText,
handleSLAResponse: handleSLAResponse handleSLAResponse: handleSLAResponse,
handleTriggersResponse: handleTriggersResponse
}); });
// Fix for backward compatibility with lodash 2.4 // Fix for backward compatibility with lodash 2.4

File diff suppressed because one or more lines are too long

View File

@@ -3,7 +3,7 @@
System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './zabbixCachingProxy.service.js', './zabbixDBConnector'], function (_export, _context) { System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './zabbixCachingProxy.service.js', './zabbixDBConnector'], function (_export, _context) {
"use strict"; "use strict";
var angular, _, utils, _createClass; var angular, _, utils, _slicedToArray, _createClass;
function _toConsumableArray(arr) { function _toConsumableArray(arr) {
if (Array.isArray(arr)) { if (Array.isArray(arr)) {
@@ -69,6 +69,7 @@ System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './za
this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI); this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI);
this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI); this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI);
this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI); this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI);
this.getHostAlerts = this.zabbixAPI.getHostAlerts.bind(this.zabbixAPI);
this.getAcknowledges = this.zabbixAPI.getAcknowledges.bind(this.zabbixAPI); this.getAcknowledges = this.zabbixAPI.getAcknowledges.bind(this.zabbixAPI);
this.getITService = this.zabbixAPI.getITService.bind(this.zabbixAPI); this.getITService = this.zabbixAPI.getITService.bind(this.zabbixAPI);
this.getSLA = this.zabbixAPI.getSLA.bind(this.zabbixAPI); this.getSLA = this.zabbixAPI.getSLA.bind(this.zabbixAPI);
@@ -85,6 +86,24 @@ System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './za
}); });
return this.getItems.apply(this, _toConsumableArray(filters).concat([options])); return this.getItems.apply(this, _toConsumableArray(filters).concat([options]));
} }
}, {
key: 'getHostsFromTarget',
value: function getHostsFromTarget(target) {
var parts = ['group', 'host', 'application'];
var filters = _.map(parts, function (p) {
return target[p].filter;
});
return Promise.all([this.getHosts.apply(this, _toConsumableArray(filters)), this.getApps.apply(this, _toConsumableArray(filters))]).then(function (results) {
var _results = _slicedToArray(results, 2),
hosts = _results[0],
apps = _results[1];
if (apps.appFilterEmpty) {
apps = [];
}
return [hosts, apps];
});
}
}, { }, {
key: 'getAllGroups', key: 'getAllGroups',
value: function getAllGroups() { value: function getAllGroups() {
@@ -302,6 +321,44 @@ System.register(['angular', 'lodash', './utils', './zabbixAPI.service.js', './za
utils = _utils; utils = _utils;
}, function (_zabbixAPIServiceJs) {}, function (_zabbixCachingProxyServiceJs) {}, function (_zabbixDBConnector) {}], }, function (_zabbixAPIServiceJs) {}, function (_zabbixCachingProxyServiceJs) {}, function (_zabbixDBConnector) {}],
execute: function () { execute: function () {
_slicedToArray = function () {
function sliceIterator(arr, i) {
var _arr = [];
var _n = true;
var _d = false;
var _e = undefined;
try {
for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally {
try {
if (!_n && _i["return"]) _i["return"]();
} finally {
if (_d) throw _e;
}
}
return _arr;
}
return function (arr, i) {
if (Array.isArray(arr)) {
return arr;
} else if (Symbol.iterator in Object(arr)) {
return sliceIterator(arr, i);
} else {
throw new TypeError("Invalid attempt to destructure non-iterable instance");
}
};
}();
_createClass = function () { _createClass = function () {
function defineProperties(target, props) { function defineProperties(target, props) {
for (var i = 0; i < props.length; i++) { for (var i = 0; i < props.length; i++) {

File diff suppressed because one or more lines are too long

View File

@@ -411,6 +411,37 @@ System.register(['angular', 'lodash', './utils', './zabbixAPICore.service'], fun
params.lastChangeTill = timeTo; params.lastChangeTill = timeTo;
} }
return this.request('trigger.get', params);
}
}, {
key: 'getHostAlerts',
value: function getHostAlerts(hostids, applicationids, minSeverity, count, timeFrom, timeTo) {
var params = {
output: 'extend',
hostids: hostids,
min_severity: minSeverity,
filter: { value: 1 },
expandDescription: true,
expandData: true,
expandComment: true,
monitored: true,
skipDependent: true,
selectLastEvent: 'extend'
};
if (count) {
params.countOutput = true;
}
if (applicationids && applicationids.length) {
params.applicationids = applicationids;
}
if (timeFrom || timeTo) {
params.lastChangeSince = timeFrom;
params.lastChangeTill = timeTo;
}
return this.request('trigger.get', params); return this.request('trigger.get', params);
} }
}]); }]);

File diff suppressed because one or more lines are too long

View File

@@ -8,6 +8,7 @@ var MODE_METRICS = exports.MODE_METRICS = 0;
var MODE_ITSERVICE = exports.MODE_ITSERVICE = 1; var MODE_ITSERVICE = exports.MODE_ITSERVICE = 1;
var MODE_TEXT = exports.MODE_TEXT = 2; var MODE_TEXT = exports.MODE_TEXT = 2;
var MODE_ITEMID = exports.MODE_ITEMID = 3; var MODE_ITEMID = exports.MODE_ITEMID = 3;
var MODE_TRIGGERS = exports.MODE_TRIGGERS = 4;
// Triggers severity // Triggers severity
var SEV_NOT_CLASSIFIED = exports.SEV_NOT_CLASSIFIED = 0; var SEV_NOT_CLASSIFIED = exports.SEV_NOT_CLASSIFIED = 0;

View File

@@ -190,6 +190,10 @@ var ZabbixAPIDatasource = function () {
} else if (target.mode === c.MODE_ITSERVICE) { } else if (target.mode === c.MODE_ITSERVICE) {
// IT services mode // IT services mode
return _this.queryITServiceData(target, timeRange, options); return _this.queryITServiceData(target, timeRange, options);
} else if (target.mode === c.MODE_TRIGGERS) {
return _this.queryTriggersData(target, timeRange);
} else {
return [];
} }
}); });
@@ -436,6 +440,31 @@ var ZabbixAPIDatasource = function () {
}); });
}); });
} }
}, {
key: 'queryTriggersData',
value: function queryTriggersData(target, timeRange) {
var _this7 = this;
var _timeRange3 = _slicedToArray(timeRange, 2),
timeFrom = _timeRange3[0],
timeTo = _timeRange3[1];
return this.zabbix.getHostsFromTarget(target).then(function (results) {
var _results = _slicedToArray(results, 2),
hosts = _results[0],
apps = _results[1];
if (hosts.length) {
var hostids = _lodash2.default.map(hosts, 'hostid');
var appids = _lodash2.default.map(apps, 'applicationid');
return _this7.zabbix.getHostAlerts(hostids, appids, target.minSeverity, target.options.countTriggers, timeFrom, timeTo).then(function (triggers) {
return _responseHandler2.default.handleTriggersResponse(triggers, timeRange);
});
} else {
return Promise.resolve([]);
}
});
}
/** /**
* Test connection to Zabbix API * Test connection to Zabbix API
@@ -445,15 +474,15 @@ var ZabbixAPIDatasource = function () {
}, { }, {
key: 'testDatasource', key: 'testDatasource',
value: function testDatasource() { value: function testDatasource() {
var _this7 = this; var _this8 = this;
var zabbixVersion = void 0; var zabbixVersion = void 0;
return this.zabbix.getVersion().then(function (version) { return this.zabbix.getVersion().then(function (version) {
zabbixVersion = version; zabbixVersion = version;
return _this7.zabbix.login(); return _this8.zabbix.login();
}).then(function () { }).then(function () {
if (_this7.enableDirectDBConnection) { if (_this8.enableDirectDBConnection) {
return _this7.zabbix.dbConnector.testSQLDataSource(); return _this8.zabbix.dbConnector.testSQLDataSource();
} else { } else {
return Promise.resolve(); return Promise.resolve();
} }
@@ -501,14 +530,14 @@ var ZabbixAPIDatasource = function () {
}, { }, {
key: 'metricFindQuery', key: 'metricFindQuery',
value: function metricFindQuery(query) { value: function metricFindQuery(query) {
var _this8 = this; var _this9 = this;
var result = void 0; var result = void 0;
var parts = []; var parts = [];
// Split query. Query structure: group.host.app.item // Split query. Query structure: group.host.app.item
_lodash2.default.each(utils.splitTemplateQuery(query), function (part) { _lodash2.default.each(utils.splitTemplateQuery(query), function (part) {
part = _this8.replaceTemplateVars(part, {}); part = _this9.replaceTemplateVars(part, {});
// Replace wildcard to regex // Replace wildcard to regex
if (part === '*') { if (part === '*') {
@@ -550,7 +579,7 @@ var ZabbixAPIDatasource = function () {
}, { }, {
key: 'annotationQuery', key: 'annotationQuery',
value: function annotationQuery(options) { value: function annotationQuery(options) {
var _this9 = this; var _this10 = this;
var timeFrom = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000); var timeFrom = Math.ceil(dateMath.parse(options.rangeRaw.from) / 1000);
var timeTo = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000); var timeTo = Math.ceil(dateMath.parse(options.rangeRaw.to) / 1000);
@@ -568,7 +597,7 @@ var ZabbixAPIDatasource = function () {
return getTriggers.then(function (triggers) { return getTriggers.then(function (triggers) {
// Filter triggers by description // Filter triggers by description
var triggerName = _this9.replaceTemplateVars(annotation.trigger, {}); var triggerName = _this10.replaceTemplateVars(annotation.trigger, {});
if (utils.isRegex(triggerName)) { if (utils.isRegex(triggerName)) {
triggers = _lodash2.default.filter(triggers, function (trigger) { triggers = _lodash2.default.filter(triggers, function (trigger) {
return utils.buildRegex(triggerName).test(trigger.description); return utils.buildRegex(triggerName).test(trigger.description);
@@ -585,7 +614,7 @@ var ZabbixAPIDatasource = function () {
}); });
var objectids = _lodash2.default.map(triggers, 'triggerid'); var objectids = _lodash2.default.map(triggers, 'triggerid');
return _this9.zabbix.getEvents(objectids, timeFrom, timeTo, showOkEvents).then(function (events) { return _this10.zabbix.getEvents(objectids, timeFrom, timeTo, showOkEvents).then(function (events) {
var indexedTriggers = _lodash2.default.keyBy(triggers, 'triggerid'); var indexedTriggers = _lodash2.default.keyBy(triggers, 'triggerid');
// Hide acknowledged events if option enabled // Hide acknowledged events if option enabled
@@ -626,23 +655,23 @@ var ZabbixAPIDatasource = function () {
}, { }, {
key: 'alertQuery', key: 'alertQuery',
value: function alertQuery(options) { value: function alertQuery(options) {
var _this10 = this; var _this11 = this;
var enabled_targets = filterEnabledTargets(options.targets); var enabled_targets = filterEnabledTargets(options.targets);
var getPanelItems = _lodash2.default.map(enabled_targets, function (t) { var getPanelItems = _lodash2.default.map(enabled_targets, function (t) {
var target = _lodash2.default.cloneDeep(t); var target = _lodash2.default.cloneDeep(t);
_this10.replaceTargetVariables(target, options); _this11.replaceTargetVariables(target, options);
return _this10.zabbix.getItemsFromTarget(target, { itemtype: 'num' }); return _this11.zabbix.getItemsFromTarget(target, { itemtype: 'num' });
}); });
return Promise.all(getPanelItems).then(function (results) { return Promise.all(getPanelItems).then(function (results) {
var items = _lodash2.default.flatten(results); var items = _lodash2.default.flatten(results);
var itemids = _lodash2.default.map(items, 'itemid'); var itemids = _lodash2.default.map(items, 'itemid');
return _this10.zabbix.getAlerts(itemids); return _this11.zabbix.getAlerts(itemids);
}).then(function (triggers) { }).then(function (triggers) {
triggers = _lodash2.default.filter(triggers, function (trigger) { triggers = _lodash2.default.filter(triggers, function (trigger) {
return trigger.priority >= _this10.alertingMinSeverity; return trigger.priority >= _this11.alertingMinSeverity;
}); });
if (!triggers || triggers.length === 0) { if (!triggers || triggers.length === 0) {
@@ -673,12 +702,12 @@ var ZabbixAPIDatasource = function () {
}, { }, {
key: 'replaceTargetVariables', key: 'replaceTargetVariables',
value: function replaceTargetVariables(target, options) { value: function replaceTargetVariables(target, options) {
var _this11 = this; var _this12 = this;
var parts = ['group', 'host', 'application', 'item']; var parts = ['group', 'host', 'application', 'item'];
_lodash2.default.forEach(parts, function (p) { _lodash2.default.forEach(parts, function (p) {
if (target[p] && target[p].filter) { if (target[p] && target[p].filter) {
target[p].filter = _this11.replaceTemplateVars(target[p].filter, options.scopedVars); target[p].filter = _this12.replaceTemplateVars(target[p].filter, options.scopedVars);
} }
}); });
target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars); target.textFilter = this.replaceTemplateVars(target.textFilter, options.scopedVars);
@@ -686,9 +715,9 @@ var ZabbixAPIDatasource = function () {
_lodash2.default.forEach(target.functions, function (func) { _lodash2.default.forEach(target.functions, function (func) {
func.params = _lodash2.default.map(func.params, function (param) { func.params = _lodash2.default.map(func.params, function (param) {
if (typeof param === 'number') { if (typeof param === 'number') {
return +_this11.templateSrv.replace(param.toString(), options.scopedVars); return +_this12.templateSrv.replace(param.toString(), options.scopedVars);
} else { } else {
return _this11.templateSrv.replace(param, options.scopedVars); return _this12.templateSrv.replace(param, options.scopedVars);
} }
}); });
}); });
@@ -696,9 +725,9 @@ var ZabbixAPIDatasource = function () {
}, { }, {
key: 'isUseTrends', key: 'isUseTrends',
value: function isUseTrends(timeRange) { value: function isUseTrends(timeRange) {
var _timeRange3 = _slicedToArray(timeRange, 2), var _timeRange4 = _slicedToArray(timeRange, 2),
timeFrom = _timeRange3[0], timeFrom = _timeRange4[0],
timeTo = _timeRange3[1]; timeTo = _timeRange4[1];
var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000); var useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);
var useTrendsRange = Math.ceil(utils.parseInterval(this.trendsRange) / 1000); var useTrendsRange = Math.ceil(utils.parseInterval(this.trendsRange) / 1000);

View File

@@ -60,17 +60,20 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
_this.replaceTemplateVars = _this.datasource.replaceTemplateVars; _this.replaceTemplateVars = _this.datasource.replaceTemplateVars;
_this.templateSrv = templateSrv; _this.templateSrv = templateSrv;
_this.editorModes = [{ value: 'num', text: 'Metrics', mode: c.MODE_METRICS }, { value: 'text', text: 'Text', mode: c.MODE_TEXT }, { value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE }, { value: 'itemid', text: 'Item ID', mode: c.MODE_ITEMID }]; _this.editorModes = [{ value: 'num', text: 'Metrics', mode: c.MODE_METRICS }, { value: 'text', text: 'Text', mode: c.MODE_TEXT }, { value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE }, { value: 'itemid', text: 'Item ID', mode: c.MODE_ITEMID }, { value: 'triggers', text: 'Triggers', mode: c.MODE_TRIGGERS }];
_this.$scope.editorMode = { _this.$scope.editorMode = {
METRICS: c.MODE_METRICS, METRICS: c.MODE_METRICS,
TEXT: c.MODE_TEXT, TEXT: c.MODE_TEXT,
ITSERVICE: c.MODE_ITSERVICE, ITSERVICE: c.MODE_ITSERVICE,
ITEMID: c.MODE_ITEMID ITEMID: c.MODE_ITEMID,
TRIGGERS: c.MODE_TRIGGERS
}; };
_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.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.triggerSeverity = [{ val: 0, text: 'Not classified' }, { val: 1, text: 'Information' }, { val: 2, text: 'Warning' }, { val: 3, text: 'Average' }, { val: 4, text: 'High' }, { val: 5, text: 'Disaster' }];
// Map functions for bs-typeahead // Map functions for bs-typeahead
_this.getGroupNames = _lodash2.default.bind(_this.getMetricNames, _this, 'groupList'); _this.getGroupNames = _lodash2.default.bind(_this.getMetricNames, _this, 'groupList');
_this.getHostNames = _lodash2.default.bind(_this.getMetricNames, _this, 'hostList', true); _this.getHostNames = _lodash2.default.bind(_this.getMetricNames, _this, 'hostList', true);
@@ -110,8 +113,10 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
'application': { 'filter': "" }, 'application': { 'filter': "" },
'item': { 'filter': "" }, 'item': { 'filter': "" },
'functions': [], 'functions': [],
'minSeverity': 3,
'options': { 'options': {
'showDisabledItems': false 'showDisabledItems': false,
'countTriggers': true
} }
}; };
_lodash2.default.defaults(target, targetDefaults); _lodash2.default.defaults(target, targetDefaults);
@@ -121,8 +126,7 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
return metricFunctions.createFuncInstance(func.def, func.params); return metricFunctions.createFuncInstance(func.def, func.params);
}); });
if (target.mode === c.MODE_METRICS || target.mode === c.MODE_TEXT) { if (target.mode === c.MODE_METRICS || target.mode === c.MODE_TEXT || target.mode === c.MODE_TRIGGERS) {
this.initFilters(); this.initFilters();
} else if (target.mode === c.MODE_ITSERVICE) { } else if (target.mode === c.MODE_ITSERVICE) {
_lodash2.default.defaults(target, { slaProperty: { name: "SLA", property: "sla" } }); _lodash2.default.defaults(target, { slaProperty: { name: "SLA", property: "sla" } });
@@ -131,6 +135,7 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
}; };
_this.init(); _this.init();
_this.queryOptionsText = _this.renderQueryOptionsText();
return _this; return _this;
} }
@@ -340,7 +345,8 @@ var ZabbixQueryController = exports.ZabbixQueryController = function (_QueryCtrl
key: 'renderQueryOptionsText', key: 'renderQueryOptionsText',
value: function renderQueryOptionsText() { value: function renderQueryOptionsText() {
var optionsMap = { var optionsMap = {
showDisabledItems: "Show disabled items" showDisabledItems: "Show disabled items",
countTriggers: "Count Triggers"
}; };
var options = []; var options = [];
_lodash2.default.forOwn(this.target.options, function (value, key) { _lodash2.default.forOwn(this.target.options, function (value, key) {

View File

@@ -109,6 +109,17 @@ function handleSLAResponse(itservice, slaProperty, slaObject) {
} }
} }
function handleTriggersResponse(triggers, timeRange) {
if (_lodash2.default.isNumber(triggers)) {
return {
target: "triggers count",
datapoints: [[triggers, timeRange[1]]]
};
} else {
return triggers;
}
}
function convertHistoryPoint(point) { function convertHistoryPoint(point) {
// Value must be a number for properly work // Value must be a number for properly work
return [Number(point.value), point.clock * 1000 + Math.round(point.ns / 1000000)]; return [Number(point.value), point.clock * 1000 + Math.round(point.ns / 1000000)];
@@ -144,7 +155,8 @@ exports.default = {
convertHistory: convertHistory, convertHistory: convertHistory,
handleTrends: handleTrends, handleTrends: handleTrends,
handleText: handleText, handleText: handleText,
handleSLAResponse: handleSLAResponse handleSLAResponse: handleSLAResponse,
handleTriggersResponse: handleTriggersResponse
}; };
// Fix for backward compatibility with lodash 2.4 // Fix for backward compatibility with lodash 2.4

View File

@@ -1,5 +1,7 @@
'use strict'; 'use strict';
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _angular = require('angular'); var _angular = require('angular');
@@ -74,6 +76,7 @@ function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector)
this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI); this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI);
this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI); this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI);
this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI); this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI);
this.getHostAlerts = this.zabbixAPI.getHostAlerts.bind(this.zabbixAPI);
this.getAcknowledges = this.zabbixAPI.getAcknowledges.bind(this.zabbixAPI); this.getAcknowledges = this.zabbixAPI.getAcknowledges.bind(this.zabbixAPI);
this.getITService = this.zabbixAPI.getITService.bind(this.zabbixAPI); this.getITService = this.zabbixAPI.getITService.bind(this.zabbixAPI);
this.getSLA = this.zabbixAPI.getSLA.bind(this.zabbixAPI); this.getSLA = this.zabbixAPI.getSLA.bind(this.zabbixAPI);
@@ -90,6 +93,24 @@ function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector)
}); });
return this.getItems.apply(this, _toConsumableArray(filters).concat([options])); return this.getItems.apply(this, _toConsumableArray(filters).concat([options]));
} }
}, {
key: 'getHostsFromTarget',
value: function getHostsFromTarget(target) {
var parts = ['group', 'host', 'application'];
var filters = _lodash2.default.map(parts, function (p) {
return target[p].filter;
});
return Promise.all([this.getHosts.apply(this, _toConsumableArray(filters)), this.getApps.apply(this, _toConsumableArray(filters))]).then(function (results) {
var _results = _slicedToArray(results, 2),
hosts = _results[0],
apps = _results[1];
if (apps.appFilterEmpty) {
apps = [];
}
return [hosts, apps];
});
}
}, { }, {
key: 'getAllGroups', key: 'getAllGroups',
value: function getAllGroups() { value: function getAllGroups() {

View File

@@ -483,6 +483,37 @@ function ZabbixAPIServiceFactory(alertSrv, zabbixAPICoreService) {
params.lastChangeTill = timeTo; params.lastChangeTill = timeTo;
} }
return this.request('trigger.get', params);
}
}, {
key: 'getHostAlerts',
value: function getHostAlerts(hostids, applicationids, minSeverity, count, timeFrom, timeTo) {
var params = {
output: 'extend',
hostids: hostids,
min_severity: minSeverity,
filter: { value: 1 },
expandDescription: true,
expandData: true,
expandComment: true,
monitored: true,
skipDependent: true,
selectLastEvent: 'extend'
};
if (count) {
params.countOutput = true;
}
if (applicationids && applicationids.length) {
params.applicationids = applicationids;
}
if (timeFrom || timeTo) {
params.lastChangeSince = timeFrom;
params.lastChangeTill = timeTo;
}
return this.request('trigger.get', params); return this.request('trigger.get', params);
} }
}]); }]);

View File

@@ -3,6 +3,7 @@ export const MODE_METRICS = 0;
export const MODE_ITSERVICE = 1; export const MODE_ITSERVICE = 1;
export const MODE_TEXT = 2; export const MODE_TEXT = 2;
export const MODE_ITEMID = 3; export const MODE_ITEMID = 3;
export const MODE_TRIGGERS = 4;
// Triggers severity // Triggers severity
export const SEV_NOT_CLASSIFIED = 0; export const SEV_NOT_CLASSIFIED = 0;

View File

@@ -136,6 +136,10 @@ class ZabbixAPIDatasource {
} else if (target.mode === c.MODE_ITSERVICE) { } else if (target.mode === c.MODE_ITSERVICE) {
// IT services mode // IT services mode
return this.queryITServiceData(target, timeRange, options); return this.queryITServiceData(target, timeRange, options);
} else if (target.mode === c.MODE_TRIGGERS) {
return this.queryTriggersData(target, timeRange);
} else {
return [];
} }
}); });
@@ -350,6 +354,24 @@ class ZabbixAPIDatasource {
}); });
} }
queryTriggersData(target, timeRange) {
let [timeFrom, timeTo] = timeRange;
return this.zabbix.getHostsFromTarget(target)
.then((results) => {
let [hosts, apps] = results;
if (hosts.length) {
let hostids = _.map(hosts, 'hostid');
let appids = _.map(apps, 'applicationid');
return this.zabbix.getHostAlerts(hostids, appids, target.minSeverity, target.options.countTriggers, timeFrom, timeTo)
.then((triggers) => {
return responseHandler.handleTriggersResponse(triggers, timeRange);
});
} else {
return Promise.resolve([]);
}
});
}
/** /**
* Test connection to Zabbix API * Test connection to Zabbix API
* @return {object} Connection status and Zabbix API version * @return {object} Connection status and Zabbix API version

View File

@@ -48,7 +48,7 @@
</div> </div>
</div> </div>
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT"> <div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT || ctrl.target.mode == editorMode.TRIGGERS">
<!-- Select Group --> <!-- Select Group -->
<div class="gf-form max-width-20"> <div class="gf-form max-width-20">
<label class="gf-form-label query-keyword width-7">Group</label> <label class="gf-form-label query-keyword width-7">Group</label>
@@ -66,7 +66,7 @@
</div> </div>
<!-- Select Host --> <!-- Select Host -->
<div class="gf-form"> <div class="gf-form">
<label class="gf-form-label query-keyword width-7">Host</label> <label class="gf-form-label query-keyword width-8">Host</label>
<input type="text" <input type="text"
ng-model="ctrl.target.host.filter" ng-model="ctrl.target.host.filter"
bs-typeahead="ctrl.getHostNames" bs-typeahead="ctrl.getHostNames"
@@ -85,7 +85,7 @@
</div> </div>
</div> </div>
<div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT"> <div class="gf-form-inline" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT || ctrl.target.mode == editorMode.TRIGGERS">
<!-- Select Application --> <!-- Select Application -->
<div class="gf-form max-width-20"> <div class="gf-form max-width-20">
<label class="gf-form-label query-keyword width-7">Application</label> <label class="gf-form-label query-keyword width-7">Application</label>
@@ -103,8 +103,8 @@
</div> </div>
<!-- Select Item --> <!-- Select Item -->
<div class="gf-form"> <div class="gf-form" ng-show="ctrl.target.mode == editorMode.METRICS || ctrl.target.mode == editorMode.TEXT">
<label class="gf-form-label query-keyword width-7">Item</label> <label class="gf-form-label query-keyword width-8">Item</label>
<input type="text" <input type="text"
ng-model="ctrl.target.item.filter" ng-model="ctrl.target.item.filter"
bs-typeahead="ctrl.getItemNames" bs-typeahead="ctrl.getItemNames"
@@ -117,6 +117,18 @@
'zbx-regex': ctrl.isRegex(ctrl.target.item.filter) 'zbx-regex': ctrl.isRegex(ctrl.target.item.filter)
}"> }">
</div> </div>
<div class="gf-form max-width-20" ng-show="ctrl.target.mode == editorMode.TRIGGERS">
<label class="gf-form-label query-keyword width-8">Min Severity</label>
<div class="gf-form-select-wrapper width-20">
<select class="gf-form-input"
ng-change="ctrl.onTargetBlur()"
ng-model="ctrl.target.minSeverity"
ng-options="s.val as s.text for s in ctrl.triggerSeverity">
</select>
</div>
</div>
<div class="gf-form gf-form--grow"> <div class="gf-form gf-form--grow">
<label class="gf-form-label gf-form-label--grow"> <label class="gf-form-label gf-form-label--grow">
<a ng-click="ctrl.toggleQueryOptions()"> <a ng-click="ctrl.toggleQueryOptions()">
@@ -130,13 +142,20 @@
<!-- Query options --> <!-- Query options -->
<div class="gf-form-group" ng-if="ctrl.showQueryOptions"> <div class="gf-form-group" ng-if="ctrl.showQueryOptions">
<div class="gf-form offset-width-7"> <div class="gf-form offset-width-7" ng-hide="ctrl.target.mode == editorMode.TRIGGERS">
<gf-form-switch class="gf-form" <gf-form-switch class="gf-form"
label="Show disabled items" label="Show disabled items"
checked="ctrl.target.options.showDisabledItems" checked="ctrl.target.options.showDisabledItems"
on-change="ctrl.onQueryOptionChange()"> on-change="ctrl.onQueryOptionChange()">
</gf-form-switch> </gf-form-switch>
</div> </div>
<div class="gf-form offset-width-7" ng-show="ctrl.target.mode == editorMode.TRIGGERS">
<gf-form-switch class="gf-form"
label="Count triggers"
checked="ctrl.target.options.countTriggers"
on-change="ctrl.onQueryOptionChange()">
</gf-form-switch>
</div>
</div> </div>
<!-- Item IDs editor mode --> <!-- Item IDs editor mode -->

View File

@@ -25,14 +25,16 @@ export class ZabbixQueryController extends QueryCtrl {
{value: 'num', text: 'Metrics', mode: c.MODE_METRICS}, {value: 'num', text: 'Metrics', mode: c.MODE_METRICS},
{value: 'text', text: 'Text', mode: c.MODE_TEXT}, {value: 'text', text: 'Text', mode: c.MODE_TEXT},
{value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE}, {value: 'itservice', text: 'IT Services', mode: c.MODE_ITSERVICE},
{value: 'itemid', text: 'Item ID', mode: c.MODE_ITEMID} {value: 'itemid', text: 'Item ID', mode: c.MODE_ITEMID},
{value: 'triggers', text: 'Triggers', mode: c.MODE_TRIGGERS}
]; ];
this.$scope.editorMode = { this.$scope.editorMode = {
METRICS: c.MODE_METRICS, METRICS: c.MODE_METRICS,
TEXT: c.MODE_TEXT, TEXT: c.MODE_TEXT,
ITSERVICE: c.MODE_ITSERVICE, ITSERVICE: c.MODE_ITSERVICE,
ITEMID: c.MODE_ITEMID ITEMID: c.MODE_ITEMID,
TRIGGERS: c.MODE_TRIGGERS
}; };
this.slaPropertyList = [ this.slaPropertyList = [
@@ -43,6 +45,12 @@ export class ZabbixQueryController extends QueryCtrl {
{name: "Down time", property: "downtimeTime"} {name: "Down time", property: "downtimeTime"}
]; ];
this.triggerSeverity = [
{val: 0, text: 'Not classified'}, {val: 1, text:'Information'},
{val: 2, text: 'Warning'}, {val: 3, text: 'Average'},
{val: 4, text: 'High'}, {val: 5, text: 'Disaster'}
];
// Map functions for bs-typeahead // Map functions for bs-typeahead
this.getGroupNames = _.bind(this.getMetricNames, this, 'groupList'); this.getGroupNames = _.bind(this.getMetricNames, this, 'groupList');
this.getHostNames = _.bind(this.getMetricNames, this, 'hostList', true); this.getHostNames = _.bind(this.getMetricNames, this, 'hostList', true);
@@ -80,8 +88,10 @@ export class ZabbixQueryController extends QueryCtrl {
'application': { 'filter': "" }, 'application': { 'filter': "" },
'item': { 'filter': "" }, 'item': { 'filter': "" },
'functions': [], 'functions': [],
'minSeverity': 3,
'options': { 'options': {
'showDisabledItems': false 'showDisabledItems': false,
'countTriggers': true
} }
}; };
_.defaults(target, targetDefaults); _.defaults(target, targetDefaults);
@@ -92,8 +102,8 @@ export class ZabbixQueryController extends QueryCtrl {
}); });
if (target.mode === c.MODE_METRICS || if (target.mode === c.MODE_METRICS ||
target.mode === c.MODE_TEXT) { target.mode === c.MODE_TEXT ||
target.mode === c.MODE_TRIGGERS) {
this.initFilters(); this.initFilters();
} }
else if (target.mode === c.MODE_ITSERVICE) { else if (target.mode === c.MODE_ITSERVICE) {
@@ -103,6 +113,7 @@ export class ZabbixQueryController extends QueryCtrl {
}; };
this.init(); this.init();
this.queryOptionsText = this.renderQueryOptionsText();
} }
initFilters() { initFilters() {
@@ -282,7 +293,8 @@ export class ZabbixQueryController extends QueryCtrl {
renderQueryOptionsText() { renderQueryOptionsText() {
var optionsMap = { var optionsMap = {
showDisabledItems: "Show disabled items" showDisabledItems: "Show disabled items",
countTriggers: "Count Triggers"
}; };
var options = []; var options = [];
_.forOwn(this.target.options, (value, key) => { _.forOwn(this.target.options, (value, key) => {

View File

@@ -100,6 +100,19 @@ function handleSLAResponse(itservice, slaProperty, slaObject) {
} }
} }
function handleTriggersResponse(triggers, timeRange) {
if (_.isNumber(triggers)) {
return {
target: "triggers count",
datapoints: [
[triggers, timeRange[1]]
]
};
} else {
return triggers;
}
}
function convertHistoryPoint(point) { function convertHistoryPoint(point) {
// Value must be a number for properly work // Value must be a number for properly work
return [ return [
@@ -141,7 +154,8 @@ export default {
convertHistory: convertHistory, convertHistory: convertHistory,
handleTrends: handleTrends, handleTrends: handleTrends,
handleText: handleText, handleText: handleText,
handleSLAResponse: handleSLAResponse handleSLAResponse: handleSLAResponse,
handleTriggersResponse: handleTriggersResponse
}; };
// Fix for backward compatibility with lodash 2.4 // Fix for backward compatibility with lodash 2.4

View File

@@ -46,6 +46,7 @@ function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector)
this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI); this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI);
this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI); this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI);
this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI); this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI);
this.getHostAlerts = this.zabbixAPI.getHostAlerts.bind(this.zabbixAPI);
this.getAcknowledges = this.zabbixAPI.getAcknowledges.bind(this.zabbixAPI); this.getAcknowledges = this.zabbixAPI.getAcknowledges.bind(this.zabbixAPI);
this.getITService = this.zabbixAPI.getITService.bind(this.zabbixAPI); this.getITService = this.zabbixAPI.getITService.bind(this.zabbixAPI);
this.getSLA = this.zabbixAPI.getSLA.bind(this.zabbixAPI); this.getSLA = this.zabbixAPI.getSLA.bind(this.zabbixAPI);
@@ -59,6 +60,21 @@ function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy, ZabbixDBConnector)
return this.getItems(...filters, options); return this.getItems(...filters, options);
} }
getHostsFromTarget(target) {
let parts = ['group', 'host', 'application'];
let filters = _.map(parts, p => target[p].filter);
return Promise.all([
this.getHosts(...filters),
this.getApps(...filters),
]).then((results) => {
let [hosts, apps] = results;
if (apps.appFilterEmpty) {
apps = [];
}
return [hosts, apps];
});
}
getAllGroups() { getAllGroups() {
return this.cachingProxy.getGroups(); return this.cachingProxy.getGroups();
} }

View File

@@ -433,6 +433,36 @@ function ZabbixAPIServiceFactory(alertSrv, zabbixAPICoreService) {
return this.request('trigger.get', params); return this.request('trigger.get', params);
} }
getHostAlerts(hostids, applicationids, minSeverity, count, timeFrom, timeTo) {
var params = {
output: 'extend',
hostids: hostids,
min_severity: minSeverity,
filter: { value: 1 },
expandDescription: true,
expandData: true,
expandComment: true,
monitored: true,
skipDependent: true,
selectLastEvent: 'extend'
};
if (count) {
params.countOutput = true;
}
if (applicationids && applicationids.length) {
params.applicationids = applicationids;
}
if (timeFrom || timeTo) {
params.lastChangeSince = timeFrom;
params.lastChangeTill = timeTo;
}
return this.request('trigger.get', params);
}
} }
return ZabbixAPI; return ZabbixAPI;