Initial alerting feature. This implementation doesn't use Grafana alerting,

instead it get triggers for particular metrics and sets panel's alert state.
This commit is contained in:
Alexander Zobnin
2017-03-05 13:12:11 +03:00
parent 5192e8648d
commit f805213b02
15 changed files with 349 additions and 22 deletions

View File

@@ -1,5 +1,5 @@
//import angular from 'angular';
import _ from 'lodash';
import $ from 'jquery';
import * as dateMath from 'app/core/utils/datemath';
import * as utils from './utils';
import * as migrations from './migrations';
@@ -12,9 +12,10 @@ import {ZabbixAPIError} from './zabbixAPICore.service.js';
class ZabbixAPIDatasource {
/** @ngInject */
constructor(instanceSettings, templateSrv, alertSrv, Zabbix) {
constructor(instanceSettings, templateSrv, alertSrv, dashboardSrv, Zabbix) {
this.templateSrv = templateSrv;
this.alertSrv = alertSrv;
this.dashboardSrv = dashboardSrv;
// General data source settings
this.name = instanceSettings.name;
@@ -56,6 +57,11 @@ class ZabbixAPIDatasource {
let useTrendsFrom = Math.ceil(dateMath.parse('now-' + this.trendsFrom) / 1000);
let useTrends = (timeFrom <= useTrendsFrom) && this.trends;
// Get alerts for current panel
this.alertQuery(options).then(alert => {
this.setPanelAlertState(options.panelId, alert.state);
});
// Create request for each target
let promises = _.map(options.targets, target => {
// Prevent changes of original object
@@ -394,6 +400,72 @@ class ZabbixAPIDatasource {
});
}
alertQuery(options) {
let enabled_targets = filterEnabledTargets(options.targets);
let getPanelItems = _.map(enabled_targets, target => {
return this.zabbix.getItemsFromTarget(target, {itemtype: 'num'});
});
return Promise.all(getPanelItems)
.then(results => {
let items = _.flatten(results);
let itemids = _.map(items, 'itemid');
return this.zabbix.getAlerts(itemids);
})
.then(triggers => {
if (!triggers || triggers.length === 0) {
return {};
}
let state = 'ok';
let firedTriggers = _.filter(triggers, {value: '1'});
if (firedTriggers.length) {
state = 'alerting';
}
return {
panelId: options.panelId,
state: state
};
});
}
setPanelAlertState(panelId, alertState) {
let panelContainers = _.filter($('.panel-container'), elem => {
return elem.clientHeight && elem.clientWidth;
});
let panelModels = _.flatten(_.map(this.dashboardSrv.dash.rows, row => {
if (row.collapse) {
return [];
} else {
return row.panels;
}
}));
let panelIndex = _.findIndex(panelModels, panel => {
return panel.id === panelId;
});
if (panelIndex >= 0) {
if (alertState) {
if (alertState === 'alerting') {
let alertClass = "panel-has-alert panel-alert-state--" + alertState;
$(panelContainers[panelIndex]).addClass(alertClass);
}
if (alertState === 'ok') {
let alertClass = "panel-alert-state--" + alertState;
$(panelContainers[panelIndex]).addClass(alertClass);
$(panelContainers[panelIndex]).removeClass("panel-has-alert");
}
} else {
let alertClass = "panel-has-alert panel-alert-state--ok panel-alert-state--alerting";
$(panelContainers[panelIndex]).removeClass(alertClass);
}
}
}
// Replace template variables
replaceTargetVariables(target, options) {
let parts = ['group', 'host', 'application', 'item'];
@@ -505,6 +577,12 @@ function sequence(funcsArray) {
};
}
function filterEnabledTargets(targets) {
return _.filter(targets, target => {
return !(target.hide || !target.group || !target.host || !target.item);
});
}
export {ZabbixAPIDatasource, zabbixTemplateFormat};
// Fix for backward compatibility with lodash 2.4

View File

@@ -19,9 +19,11 @@ describe('ZabbixDatasource', () => {
};
ctx.templateSrv = {};
ctx.alertSrv = {};
ctx.dashboardSrv = {};
ctx.zabbix = () => {};
ctx.ds = new Datasource(ctx.instanceSettings, ctx.templateSrv, ctx.alertSrv, ctx.zabbix);
ctx.ds = new Datasource(ctx.instanceSettings, ctx.templateSrv, ctx.alertSrv, ctx.dashboardSrv, ctx.zabbix);
ctx.ds.alertQuery = () => Q.when([]);
});
describe('When querying data', () => {

View File

@@ -30,6 +30,7 @@ function ZabbixFactory(zabbixAPIService, ZabbixCachingProxy) {
this.getTrend = this.zabbixAPI.getTrend.bind(this.zabbixAPI);
this.getEvents = this.zabbixAPI.getEvents.bind(this.zabbixAPI);
this.getAlerts = this.zabbixAPI.getAlerts.bind(this.zabbixAPI);
this.getAcknowledges = this.zabbixAPI.getAcknowledges.bind(this.zabbixAPI);
this.getITService = this.zabbixAPI.getITService.bind(this.zabbixAPI);
this.getSLA = this.zabbixAPI.getSLA.bind(this.zabbixAPI);

View File

@@ -401,6 +401,29 @@ function ZabbixAPIServiceFactory(alertSrv, zabbixAPICoreService) {
});
}
getAlerts(itemids, timeFrom, timeTo) {
var params = {
output: 'extend',
itemids: itemids,
expandDescription: true,
expandData: true,
expandComment: true,
monitored: true,
skipDependent: true,
//only_true: true,
// filter: {
// value: 1
// },
selectLastEvent: 'extend'
};
if (timeFrom || timeTo) {
params.lastChangeSince = timeFrom;
params.lastChangeTill = timeTo;
}
return this.request('trigger.get', params);
}
}
return ZabbixAPI;