fix annotations, closes #964

This commit is contained in:
Alexander Zobnin
2020-05-26 09:27:24 +03:00
parent fb56cf05ac
commit 938b3cdc05
5 changed files with 107 additions and 56 deletions

View File

@@ -576,71 +576,62 @@ export class ZabbixDatasource {
const timeFrom = Math.ceil(dateMath.parse(timeRange.from) / 1000); const timeFrom = Math.ceil(dateMath.parse(timeRange.from) / 1000);
const timeTo = Math.ceil(dateMath.parse(timeRange.to) / 1000); const timeTo = Math.ceil(dateMath.parse(timeRange.to) / 1000);
const annotation = options.annotation; const annotation = options.annotation;
const showOkEvents = annotation.showOkEvents ? c.SHOW_ALL_EVENTS : c.SHOW_OK_EVENTS;
// Show all triggers // Show all triggers
const triggersOptions = { const problemsOptions: any = {
showTriggers: c.SHOW_ALL_TRIGGERS, value: annotation.showOkEvents ? ['0', '1'] : '1',
hideHostsInMaintenance: false valueFromEvent: true,
timeFrom,
timeTo,
}; };
if (annotation.minseverity) {
const severities = [0, 1, 2, 3, 4, 5].filter(v => v >= Number(annotation.minseverity));
problemsOptions.severities = severities;
}
const groupFilter = this.replaceTemplateVars(annotation.group, {}); const groupFilter = this.replaceTemplateVars(annotation.group, {});
const hostFilter = this.replaceTemplateVars(annotation.host, {}); const hostFilter = this.replaceTemplateVars(annotation.host, {});
const appFilter = this.replaceTemplateVars(annotation.application, {}); const appFilter = this.replaceTemplateVars(annotation.application, {});
const proxyFilter = undefined; const proxyFilter = undefined;
return this.zabbix.getProblems(groupFilter, hostFilter, appFilter, proxyFilter, triggersOptions) return this.zabbix.getProblemsHistory(groupFilter, hostFilter, appFilter, proxyFilter, problemsOptions)
.then(triggers => { .then(problems => {
// Filter triggers by description // Filter triggers by description
const triggerName = this.replaceTemplateVars(annotation.trigger, {}); const problemName = this.replaceTemplateVars(annotation.trigger, {});
if (utils.isRegex(triggerName)) { if (utils.isRegex(problemName)) {
triggers = _.filter(triggers, trigger => { problems = _.filter(problems, p => {
return utils.buildRegex(triggerName).test(trigger.description); return utils.buildRegex(problemName).test(p.description);
}); });
} else if (triggerName) { } else if (problemName) {
triggers = _.filter(triggers, trigger => { problems = _.filter(problems, p => {
return trigger.description === triggerName; return p.description === problemName;
}); });
} }
// Remove events below the chose severity // Hide acknowledged events if option enabled
triggers = _.filter(triggers, trigger => { if (annotation.hideAcknowledged) {
return Number(trigger.priority) >= Number(annotation.minseverity); problems = _.filter(problems, p => {
}); return !p.acknowledges?.length;
const objectids = _.map(triggers, 'triggerid');
return this.zabbix
.getEvents(objectids, timeFrom, timeTo, showOkEvents)
.then(events => {
const indexedTriggers = _.keyBy(triggers, 'triggerid');
// Hide acknowledged events if option enabled
if (annotation.hideAcknowledged) {
events = _.filter(events, event => {
return !event.acknowledges.length;
});
}
return _.map(events, event => {
let tags;
if (annotation.showHostname) {
tags = _.map(event.hosts, 'name');
}
// Show event type (OK or Problem)
const title = Number(event.value) ? 'Problem' : 'OK';
const formattedAcknowledges = utils.formatAcknowledges(event.acknowledges);
const eventName = event.name || indexedTriggers[event.objectid].description;
return {
annotation: annotation,
time: event.clock * 1000,
title: title,
tags: tags,
text: eventName + formattedAcknowledges
};
});
}); });
}
return _.map(problems, p => {
const formattedAcknowledges = utils.formatAcknowledges(p.acknowledges);
let annotationTags: string[] = [];
if (annotation.showHostname) {
annotationTags = _.map(p.hosts, 'name');
}
return {
title: p.value === '1' ? 'Problem' : 'OK',
time: p.timestamp * 1000,
annotation: annotation,
text: p.name + formattedAcknowledges,
tags: annotationTags,
};
});
}); });
} }

View File

@@ -1,7 +1,7 @@
import _ from 'lodash'; import _ from 'lodash';
import * as utils from '../datasource-zabbix/utils'; import * as utils from '../datasource-zabbix/utils';
import { DataFrame, Field, FieldType, ArrayVector } from '@grafana/data'; import { DataFrame, Field, FieldType, ArrayVector } from '@grafana/data';
import { ZBXProblem, ZBXTrigger, ProblemDTO } from './types'; import { ZBXProblem, ZBXTrigger, ProblemDTO, ZBXEvent } from './types';
export function joinTriggersWithProblems(problems: ZBXProblem[], triggers: ZBXTrigger[]): ProblemDTO[] { export function joinTriggersWithProblems(problems: ZBXProblem[], triggers: ZBXTrigger[]): ProblemDTO[] {
const problemDTOList: ProblemDTO[] = []; const problemDTOList: ProblemDTO[] = [];
@@ -46,6 +46,54 @@ export function joinTriggersWithProblems(problems: ZBXProblem[], triggers: ZBXTr
return problemDTOList; return problemDTOList;
} }
interface JoinOptions {
valueFromEvent?: boolean;
}
export function joinTriggersWithEvents(events: ZBXEvent[], triggers: ZBXTrigger[], options?: JoinOptions): ProblemDTO[] {
const { valueFromEvent } = options;
const problemDTOList: ProblemDTO[] = [];
for (let i = 0; i < events.length; i++) {
const e = events[i];
const triggerId = Number(e.objectid);
const t = triggers[triggerId];
if (t) {
const problemDTO: ProblemDTO = {
value: valueFromEvent ? e.value : t.value,
timestamp: Number(e.clock),
triggerid: e.objectid,
eventid: e.eventid,
name: e.name,
severity: e.severity,
acknowledged: e.acknowledged,
acknowledges: e.acknowledges,
tags: e.tags,
suppressed: e.suppressed,
description: t.description,
comments: t.comments,
groups: t.groups,
hosts: t.hosts,
items: t.items,
alerts: t.alerts,
url: t.url,
expression: t.expression,
correlation_mode: t.correlation_mode,
correlation_tag: t.correlation_tag,
manual_close: t.manual_close,
state: t.state,
error: t.error,
};
problemDTOList.push(problemDTO);
}
}
return problemDTOList;
}
export function setMaintenanceStatus(triggers) { export function setMaintenanceStatus(triggers) {
_.each(triggers, (trigger) => { _.each(triggers, (trigger) => {
const maintenance_status = _.some(trigger.hosts, (host) => host.maintenance_status === '1'); const maintenance_status = _.some(trigger.hosts, (host) => host.maintenance_status === '1');
@@ -145,6 +193,8 @@ const problemsHandler = {
setAckButtonStatus, setAckButtonStatus,
filterTriggersPre, filterTriggersPre,
toDataFrame, toDataFrame,
joinTriggersWithProblems,
joinTriggersWithEvents,
}; };
export default problemsHandler; export default problemsHandler;

View File

@@ -170,13 +170,16 @@ export interface ZBXEvent {
clock: string; clock: string;
ns?: string; ns?: string;
value?: string; value?: string;
name?: string;
source?: string; source?: string;
object?: string; object?: string;
objectid?: string; objectid?: string;
acknowledged?: string;
severity?: string; severity?: string;
hosts?: ZBXHost[]; hosts?: ZBXHost[];
acknowledged?: '1' | '0';
acknowledges?: ZBXAcknowledge[]; acknowledges?: ZBXAcknowledge[];
tags?: ZBXTag[];
suppressed?: string;
} }
export interface ZBXTag { export interface ZBXTag {

View File

@@ -511,7 +511,7 @@ export class ZabbixAPIConnector {
} }
getEventsHistory(groupids, hostids, applicationids, options) { getEventsHistory(groupids, hostids, applicationids, options) {
const { timeFrom, timeTo, severities, limit } = options; const { timeFrom, timeTo, severities, limit, value } = options;
const params: any = { const params: any = {
output: 'extend', output: 'extend',
@@ -539,6 +539,10 @@ export class ZabbixAPIConnector {
params.severities = severities; params.severities = severities;
} }
if (value) {
params.value = value;
}
return this.request('event.get', params); return this.request('event.get', params);
} }

View File

@@ -9,7 +9,8 @@ import { ZabbixAPIConnector } from './connectors/zabbix_api/zabbixAPIConnector';
import { SQLConnector } from './connectors/sql/sqlConnector'; import { SQLConnector } from './connectors/sql/sqlConnector';
import { InfluxDBConnector } from './connectors/influxdb/influxdbConnector'; import { InfluxDBConnector } from './connectors/influxdb/influxdbConnector';
import { ZabbixConnector } from './types'; import { ZabbixConnector } from './types';
import { joinTriggersWithProblems } from '../problemsHandler'; import { joinTriggersWithProblems, joinTriggersWithEvents } from '../problemsHandler';
import { ProblemDTO } from '../types';
interface AppsResponse extends Array<any> { interface AppsResponse extends Array<any> {
appFilterEmpty?: boolean; appFilterEmpty?: boolean;
@@ -346,7 +347,9 @@ export class Zabbix implements ZabbixConnector {
.then(triggers => this.expandUserMacro.bind(this)(triggers, true)); .then(triggers => this.expandUserMacro.bind(this)(triggers, true));
} }
getProblemsHistory(groupFilter, hostFilter, appFilter, proxyFilter?, options?) { getProblemsHistory(groupFilter, hostFilter, appFilter, proxyFilter?, options?): Promise<ProblemDTO[]> {
const { valueFromEvent } = options;
const promises = [ const promises = [
this.getGroups(groupFilter), this.getGroups(groupFilter),
this.getHosts(groupFilter, hostFilter), this.getHosts(groupFilter, hostFilter),
@@ -375,7 +378,7 @@ export class Zabbix implements ZabbixConnector {
const triggerids = problems?.map(problem => problem.objectid); const triggerids = problems?.map(problem => problem.objectid);
return Promise.all([Promise.resolve(problems), this.zabbixAPI.getTriggersByIds(triggerids)]); return Promise.all([Promise.resolve(problems), this.zabbixAPI.getTriggersByIds(triggerids)]);
}) })
.then(([problems, triggers]) => joinTriggersWithProblems(problems, triggers)) .then(([problems, triggers]) => joinTriggersWithEvents(problems, triggers, { valueFromEvent }))
.then(triggers => this.filterTriggersByProxy(triggers, proxyFilter)) .then(triggers => this.filterTriggersByProxy(triggers, proxyFilter))
.then(triggers => this.expandUserMacro.bind(this)(triggers, true)); .then(triggers => this.expandUserMacro.bind(this)(triggers, true));
} }