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:
@@ -421,7 +421,12 @@ export class ZabbixAPIConnector {
|
||||
getEventAlerts(eventids) {
|
||||
const params = {
|
||||
eventids: eventids,
|
||||
output: 'extend',
|
||||
output: [
|
||||
'eventid',
|
||||
'message',
|
||||
'clock',
|
||||
'error'
|
||||
],
|
||||
selectUsers: true,
|
||||
};
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 || ''}`}>
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -162,6 +162,7 @@ export interface ZBXAcknowledge {
|
||||
}
|
||||
|
||||
export interface ZBXAlert {
|
||||
eventid: string;
|
||||
clock: string;
|
||||
message: string;
|
||||
error: string;
|
||||
|
||||
Reference in New Issue
Block a user