Fix problems fetching performance and memory issues (#724)

* request only alert message when invoking alert.get

* fetch problem alerts on demand

* problems panel: refactor
This commit is contained in:
Alexander Zobnin
2019-04-22 12:29:05 +03:00
committed by GitHub
parent e3c5d44345
commit bc889ffe30
6 changed files with 47 additions and 27 deletions

View File

@@ -421,7 +421,12 @@ export class ZabbixAPIConnector {
getEventAlerts(eventids) {
const params = {
eventids: eventids,
output: 'extend',
output: [
'eventid',
'message',
'clock',
'error'
],
selectUsers: true,
};

View File

@@ -1,7 +1,7 @@
import React, { PureComponent } from 'react';
import moment from 'moment';
import * as utils from '../../../datasource-zabbix/utils';
import { ZBXTrigger, ZBXItem, ZBXAcknowledge, ZBXHost, ZBXGroup, ZBXEvent, GFTimeRange, RTRow, ZBXTag } from '../../types';
import { ZBXTrigger, ZBXItem, ZBXAcknowledge, ZBXHost, ZBXGroup, ZBXEvent, GFTimeRange, RTRow, ZBXTag, ZBXAlert } from '../../types';
import { Modal, AckProblemData } from '../Modal';
import EventTag from '../EventTag';
import Tooltip from '../Tooltip/Tooltip';
@@ -15,12 +15,14 @@ interface ProblemDetailsProps extends RTRow<ZBXTrigger> {
timeRange: GFTimeRange;
showTimeline?: boolean;
getProblemEvents: (problem: ZBXTrigger) => Promise<ZBXEvent[]>;
getProblemAlerts: (problem: ZBXTrigger) => Promise<ZBXAlert[]>;
onProblemAck?: (problem: ZBXTrigger, data: AckProblemData) => Promise<any> | any;
onTagClick?: (tag: ZBXTag, datasource: string, ctrlKey?: boolean, shiftKey?: boolean) => void;
}
interface ProblemDetailsState {
events: ZBXEvent[];
alerts: ZBXAlert[];
show: boolean;
showAckDialog: boolean;
}
@@ -30,6 +32,7 @@ export default class ProblemDetails extends PureComponent<ProblemDetailsProps, P
super(props);
this.state = {
events: [],
alerts: [],
show: false,
showAckDialog: false,
};
@@ -39,6 +42,7 @@ export default class ProblemDetails extends PureComponent<ProblemDetailsProps, P
if (this.props.showTimeline) {
this.fetchProblemEvents();
}
this.fetchProblemAlerts();
requestAnimationFrame(() => {
this.setState({ show: true });
});
@@ -58,6 +62,14 @@ export default class ProblemDetails extends PureComponent<ProblemDetailsProps, P
});
}
fetchProblemAlerts() {
const problem = this.props.original;
this.props.getProblemAlerts(problem)
.then(alerts => {
this.setState({ alerts });
});
}
ackProblem = (data: AckProblemData) => {
const problem = this.props.original as ZBXTrigger;
return this.props.onProblemAck(problem, data).then(result => {
@@ -78,6 +90,7 @@ export default class ProblemDetails extends PureComponent<ProblemDetailsProps, P
render() {
const problem = this.props.original as ZBXTrigger;
const alerts = this.state.alerts;
const rootWidth = this.props.rootWidth;
const displayClass = this.state.show ? 'show' : '';
const wideLayout = rootWidth > 1200;
@@ -96,7 +109,7 @@ export default class ProblemDetails extends PureComponent<ProblemDetailsProps, P
</div>
{problem.items && <ProblemItems items={problem.items} />}
</div>
<ProblemStatusBar problem={problem} className={compactStatusBar && 'compact'} />
<ProblemStatusBar problem={problem} alerts={alerts} className={compactStatusBar && 'compact'} />
<div className="problem-actions">
<ProblemActionButton className="navbar-button navbar-button--settings"
icon="reply-all"

View File

@@ -1,15 +1,16 @@
import React from 'react';
import FAIcon from '../FAIcon';
import Tooltip from '../Tooltip/Tooltip';
import { ZBXTrigger } from '../../types';
import { ZBXTrigger, ZBXAlert } from '../../types';
export interface ProblemStatusBarProps {
problem: ZBXTrigger;
alerts?: ZBXAlert[];
className?: string;
}
export default function ProblemStatusBar(props: ProblemStatusBarProps) {
const { problem, className } = props;
const { problem, alerts, className } = props;
const multiEvent = problem.type === '1';
const link = problem.url && problem.url !== '';
const maintenance = problem.maintenance;
@@ -17,8 +18,8 @@ export default function ProblemStatusBar(props: ProblemStatusBarProps) {
const error = problem.error && problem.error !== '';
const stateUnknown = problem.state === '1';
const closeByTag = problem.correlation_mode === '1';
const actions = problem.alerts && problem.alerts.length !== 0;
const actionMessage = problem.alerts ? problem.alerts[0].message : '';
const actions = alerts && alerts.length !== 0;
const actionMessage = actions ? alerts[0].message : '';
return (
<div className={`problem-statusbar ${className || ''}`}>

View File

@@ -5,7 +5,7 @@ import _ from 'lodash';
import moment from 'moment';
import * as utils from '../../../datasource-zabbix/utils';
import { isNewProblem } from '../../utils';
import { ProblemsPanelOptions, ZBXTrigger, ZBXEvent, GFTimeRange, RTCell, ZBXTag, TriggerSeverity, RTResized } from '../../types';
import { ProblemsPanelOptions, ZBXTrigger, ZBXEvent, GFTimeRange, RTCell, ZBXTag, TriggerSeverity, RTResized, ZBXAlert } from '../../types';
import EventTag from '../EventTag';
import ProblemDetails from './ProblemDetails';
import { AckProblemData } from '../Modal';
@@ -18,7 +18,8 @@ export interface ProblemListProps {
timeRange?: GFTimeRange;
pageSize?: number;
fontSize?: number;
getProblemEvents: (ids: string[]) => ZBXEvent[];
getProblemEvents: (problem: ZBXTrigger) => ZBXEvent[];
getProblemAlerts: (problem: ZBXTrigger) => ZBXAlert[];
onProblemAck?: (problem: ZBXTrigger, data: AckProblemData) => void;
onTagClick?: (tag: ZBXTag, datasource: string, ctrlKey?: boolean, shiftKey?: boolean) => void;
onPageSizeChange?: (pageSize: number, pageIndex: number) => void;
@@ -159,6 +160,7 @@ export default class ProblemList extends PureComponent<ProblemListProps, Problem
timeRange={this.props.timeRange}
showTimeline={panelOptions.problemTimeline}
getProblemEvents={this.props.getProblemEvents}
getProblemAlerts={this.props.getProblemAlerts}
onProblemAck={this.handleProblemAck}
onTagClick={this.handleTagClick}
/>

View File

@@ -271,14 +271,12 @@ export class TriggerPanelCtrl extends PanelCtrl {
}));
return Promise.all([
this.datasources[ds].zabbix.getExtendedEventData(eventids),
this.datasources[ds].zabbix.getEventAlerts(eventids),
Promise.resolve(triggers)
]);
})
.then(([events, alerts, triggers]) => {
.then(([events, triggers]) => {
this.addEventTags(events, triggers);
this.addAcknowledges(events, triggers);
this.addEventAlerts(alerts, triggers);
return triggers;
})
.then(triggers => this.setMaintenanceStatus(triggers))
@@ -337,18 +335,6 @@ export class TriggerPanelCtrl extends PanelCtrl {
return triggers;
}
addEventAlerts(alerts, triggers) {
alerts.forEach(alert => {
const trigger = _.find(triggers, t => {
return t.lastEvent && alert.eventid === t.lastEvent.eventid;
});
if (trigger) {
trigger.alerts = trigger.alerts ? trigger.alerts.concat(alert) : [alert];
}
});
return triggers;
}
filterTriggersPre(triggerList, ds) {
// Filter triggers by description
let triggerFilter = this.panel.targets[ds].trigger.filter;
@@ -503,16 +489,27 @@ export class TriggerPanelCtrl extends PanelCtrl {
this.refresh();
}
getProblemEvents(trigger) {
const triggerids = [trigger.triggerid];
getProblemEvents(problem) {
const triggerids = [problem.triggerid];
const timeFrom = Math.ceil(dateMath.parse(this.range.from) / 1000);
const timeTo = Math.ceil(dateMath.parse(this.range.to) / 1000);
return this.datasourceSrv.get(trigger.datasource)
return this.datasourceSrv.get(problem.datasource)
.then(datasource => {
return datasource.zabbix.getEvents(triggerids, timeFrom, timeTo, [0, 1], PROBLEM_EVENTS_LIMIT);
});
}
getProblemAlerts(problem) {
if (!problem.lastEvent || problem.lastEvent.length === 0) {
return Promise.resolve([]);
}
const eventids = [problem.lastEvent.eventid];
return this.datasourceSrv.get(problem.datasource)
.then(datasource => {
return datasource.zabbix.getEventAlerts(eventids);
});
}
formatHostName(trigger) {
let host = "";
if (this.panel.hostField && this.panel.hostTechNameField) {
@@ -663,6 +660,7 @@ export class TriggerPanelCtrl extends PanelCtrl {
pageSize,
fontSize: fontSizeProp,
getProblemEvents: ctrl.getProblemEvents.bind(ctrl),
getProblemAlerts: ctrl.getProblemAlerts.bind(ctrl),
onPageSizeChange: ctrl.handlePageSizeChange.bind(ctrl),
onColumnResize: ctrl.handleColumnResize.bind(ctrl),
onProblemAck: (trigger, data) => {

View File

@@ -162,6 +162,7 @@ export interface ZBXAcknowledge {
}
export interface ZBXAlert {
eventid: string;
clock: string;
message: string;
error: string;