protected function doAction() { $data = ['sid' => $this->getUserSID(), 'eventids' => $this->getInput('eventids'), 'message' => $this->getInput('message', ''), 'acknowledge_type' => $this->getInput('acknowledge_type', ZBX_ACKNOWLEDGE_SELECTED), 'backurl' => $this->getInput('backurl', 'tr_status.php'), 'unack_problem_events_count' => 0, 'unack_events_count' => 0]; if (count($this->getInput('eventids')) == 1) { $events = API::Event()->get(['output' => [], 'eventids' => $this->getInput('eventids'), 'source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'select_acknowledges' => ['clock', 'message', 'alias', 'name', 'surname']]); if ($events) { $data['event'] = ['acknowledges' => $events[0]['acknowledges']]; order_result($data['acknowledges'], 'clock', ZBX_SORT_DOWN); } } $events = API::Event()->get(['output' => ['objectid', 'acknowledged', 'value'], 'eventids' => $this->getInput('eventids'), 'source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER]); $triggerids = []; foreach ($events as $event) { if ($event['acknowledged'] == EVENT_ACKNOWLEDGED) { $data['unack_problem_events_count']++; $data['unack_events_count']++; } elseif ($event['value'] == TRIGGER_VALUE_FALSE) { $data['unack_problem_events_count']++; } $triggerids[$event['objectid']] = true; } $triggerids = array_keys($triggerids); $data['unack_problem_events_count'] += API::Event()->get(['countOutput' => true, 'source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'objectids' => $triggerids, 'filter' => ['acknowledged' => EVENT_NOT_ACKNOWLEDGED, 'value' => TRIGGER_VALUE_TRUE]]); $data['unack_events_count'] += API::Event()->get(['countOutput' => true, 'source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'objectids' => $triggerids, 'filter' => ['acknowledged' => EVENT_NOT_ACKNOWLEDGED]]); $response = new CControllerResponseData($data); $response->setTitle(_('Alarm acknowledgements')); $this->setResponse($response); }
protected function doAction() { $eventids = $this->getInput('eventids'); $acknowledge_type = $this->getInput('acknowledge_type'); $result = true; if ($acknowledge_type == ZBX_ACKNOWLEDGE_PROBLEM || $acknowledge_type == ZBX_ACKNOWLEDGE_ALL) { $events = API::Event()->get(['output' => ['objectid'], 'source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'eventids' => $eventids]); $triggerids = zbx_objectValues($events, 'objectid'); $filter = ['acknowledged' => EVENT_NOT_ACKNOWLEDGED]; if ($acknowledge_type == ZBX_ACKNOWLEDGE_PROBLEM) { $filter['value'] = TRIGGER_VALUE_TRUE; } while ($result) { $events = API::Event()->get(['output' => [], 'source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'objectids' => $triggerids, 'filter' => $filter, 'preservekeys' => true, 'limit' => ZBX_DB_MAX_INSERTS]); if ($events) { foreach ($eventids as $i => $eventid) { if (array_key_exists($eventid, $events)) { unset($eventids[$i]); } } $result = API::Event()->acknowledge(['eventids' => array_keys($events), 'message' => $this->getInput('message', '')]); } else { break; } } } if ($result && $eventids) { $result = API::Event()->acknowledge(['eventids' => $eventids, 'message' => $this->getInput('message', '')]); } if ($result) { $response = new CControllerResponseRedirect($this->getInput('backurl', 'tr_status.php')); $response->setMessageOk(_n('Event acknowledged', 'Events acknowledged', count($eventids))); } else { $response = new CControllerResponseRedirect('zabbix.php?action=acknowledge.edit'); $response->setFormData($this->getInputAll()); $response->setMessageError(_n('Cannot acknowledge event', 'Cannot acknowledge events', count($eventids))); } $this->setResponse($response); }
/** * Create DIV with latest problem triggers. * * If no sortfield and sortorder are defined, the sort indicater in the column name will not be displayed. * * @param array $filter['screenid'] * @param array $filter['groupids'] * @param array $filter['hostids'] * @param array $filter['maintenance'] * @param int $filter['extAck'] * @param int $filter['severity'] * @param int $filter['limit'] * @param string $filter['sortfield'] * @param string $filter['sortorder'] * @param string $filter['backUrl'] * * @return CDiv */ function make_latest_issues(array $filter = array()) { // hide the sort indicator if no sortfield and sortorder are given $showSortIndicator = isset($filter['sortfield']) || isset($filter['sortorder']); if (!isset($filter['sortfield'])) { $filter['sortfield'] = 'lastchange'; } if (!isset($filter['sortorder'])) { $filter['sortorder'] = ZBX_SORT_DOWN; } $options = array('groupids' => $filter['groupids'], 'hostids' => isset($filter['hostids']) ? $filter['hostids'] : null, 'monitored' => true, 'maintenance' => $filter['maintenance'], 'filter' => array('priority' => $filter['severity'], 'value' => TRIGGER_VALUE_TRUE)); $triggers = API::Trigger()->get(array_merge($options, array('withLastEventUnacknowledged' => isset($filter['extAck']) && $filter['extAck'] == EXTACK_OPTION_UNACK ? true : null, 'skipDependent' => true, 'output' => array('triggerid', 'state', 'error', 'url', 'expression', 'description', 'priority', 'lastchange'), 'selectHosts' => array('hostid', 'name'), 'selectLastEvent' => array('eventid', 'acknowledged', 'objectid', 'clock', 'ns'), 'sortfield' => $filter['sortfield'], 'sortorder' => $filter['sortorder'], 'limit' => isset($filter['limit']) ? $filter['limit'] : DEFAULT_LATEST_ISSUES_CNT))); // don't use withLastEventUnacknowledged and skipDependent because of performance issues $triggersTotalCount = API::Trigger()->get(array_merge($options, array('countOutput' => true))); // get acknowledges $eventIds = array(); foreach ($triggers as $trigger) { if ($trigger['lastEvent']) { $eventIds[] = $trigger['lastEvent']['eventid']; } } if ($eventIds) { $eventAcknowledges = API::Event()->get(array('eventids' => $eventIds, 'select_acknowledges' => API_OUTPUT_EXTEND, 'preservekeys' => true)); } foreach ($triggers as $tnum => $trigger) { // if trigger is lost (broken expression) we skip it if (empty($trigger['hosts'])) { unset($triggers[$tnum]); continue; } $host = reset($trigger['hosts']); $trigger['hostid'] = $host['hostid']; $trigger['hostname'] = $host['name']; if ($trigger['lastEvent']) { $trigger['lastEvent']['acknowledges'] = isset($eventAcknowledges[$trigger['lastEvent']['eventid']]) ? $eventAcknowledges[$trigger['lastEvent']['eventid']]['acknowledges'] : null; } $triggers[$tnum] = $trigger; } $hostIds = zbx_objectValues($triggers, 'hostid'); // get hosts $hosts = API::Host()->get(array('hostids' => $hostIds, 'output' => array('hostid', 'name', 'status', 'maintenance_status', 'maintenance_type', 'maintenanceid'), 'selectScreens' => API_OUTPUT_COUNT, 'preservekeys' => true)); // actions $actions = getEventActionsStatHints($eventIds); // ack params $ackParams = isset($filter['screenid']) ? array('screenid' => $filter['screenid']) : array(); $config = select_config(); // indicator of sort field if ($showSortIndicator) { $sortDiv = new CDiv(SPACE, $filter['sortorder'] === ZBX_SORT_DOWN ? 'icon_sortdown default_cursor' : 'icon_sortup default_cursor'); $sortDiv->addStyle('float: left'); $hostHeaderDiv = new CDiv(array(_('Host'), SPACE)); $hostHeaderDiv->addStyle('float: left'); $issueHeaderDiv = new CDiv(array(_('Issue'), SPACE)); $issueHeaderDiv->addStyle('float: left'); $lastChangeHeaderDiv = new CDiv(array(_('Time'), SPACE)); $lastChangeHeaderDiv->addStyle('float: left'); } $table = new CTableInfo(_('No events found.')); $table->setHeader(array(is_show_all_nodes() ? _('Node') : null, $showSortIndicator && $filter['sortfield'] === 'hostname' ? array($hostHeaderDiv, $sortDiv) : _('Host'), $showSortIndicator && $filter['sortfield'] === 'priority' ? array($issueHeaderDiv, $sortDiv) : _('Issue'), $showSortIndicator && $filter['sortfield'] === 'lastchange' ? array($lastChangeHeaderDiv, $sortDiv) : _('Last change'), _('Age'), _('Info'), $config['event_ack_enable'] ? _('Ack') : null, _('Actions'))); $scripts = API::Script()->getScriptsByHosts($hostIds); // triggers foreach ($triggers as $trigger) { $host = $hosts[$trigger['hostid']]; $hostName = new CSpan($host['name'], 'link_menu'); $hostName->setMenuPopup(getMenuPopupHost($host, $scripts[$host['hostid']])); // add maintenance icon with hint if host is in maintenance $maintenanceIcon = null; if ($host['maintenance_status']) { $maintenanceIcon = new CDiv(null, 'icon-maintenance-abs'); // get maintenance $maintenances = API::Maintenance()->get(array('maintenanceids' => $host['maintenanceid'], 'output' => API_OUTPUT_EXTEND, 'limit' => 1)); if ($maintenance = reset($maintenances)) { $hint = $maintenance['name'] . ' [' . ($host['maintenance_type'] ? _('Maintenance without data collection') : _('Maintenance with data collection')) . ']'; if (isset($maintenance['description'])) { // double quotes mandatory $hint .= "\n" . $maintenance['description']; } $maintenanceIcon->setHint($hint); $maintenanceIcon->addClass('pointer'); } $hostName->addClass('left-to-icon-maintenance-abs'); } $hostDiv = new CDiv(array($hostName, $maintenanceIcon), 'maintenance-abs-cont'); // unknown triggers $unknown = SPACE; if ($trigger['state'] == TRIGGER_STATE_UNKNOWN) { $unknown = new CDiv(SPACE, 'status_icon iconunknown'); $unknown->setHint($trigger['error'], '', 'on'); } // trigger has events if ($trigger['lastEvent']) { // description $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, array('clock' => $trigger['lastEvent']['clock'], 'ns' => $trigger['lastEvent']['ns']))); // ack $ack = getEventAckState($trigger['lastEvent'], empty($filter['backUrl']) ? true : $filter['backUrl'], true, $ackParams); } else { // description $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, array('clock' => $trigger['lastchange'], 'ns' => '999999999'))); // ack $ack = new CSpan(_('No events'), 'unknown'); } // description if (!zbx_empty($trigger['url'])) { $description = new CLink($description, resolveTriggerUrl($trigger), null, null, true); } else { $description = new CSpan($description, 'pointer'); } $description = new CCol($description, getSeverityStyle($trigger['priority'])); if ($trigger['lastEvent']) { $description->setHint(make_popup_eventlist($trigger['triggerid'], $trigger['lastEvent']['eventid']), '', '', false); } // clock $clock = new CLink(zbx_date2str(_('d M Y H:i:s'), $trigger['lastchange']), 'events.php?triggerid=' . $trigger['triggerid'] . '&source=0&show_unknown=1&nav_time=' . $trigger['lastchange']); // actions $actionHint = $trigger['lastEvent'] && isset($actions[$trigger['lastEvent']['eventid']]) ? $actions[$trigger['lastEvent']['eventid']] : SPACE; $table->addRow(array(get_node_name_by_elid($trigger['triggerid']), $hostDiv, $description, $clock, zbx_date2age($trigger['lastchange']), $unknown, $ack, $actionHint)); } // initialize blinking zbx_add_post_js('jqBlink.blink();'); $script = new CJSScript(get_js("jQuery('#hat_lastiss_footer').html('" . _s('Updated: %s', zbx_date2str(_('H:i:s'))) . "')")); $infoDiv = new CDiv(_n('%1$d of %2$d issue is shown', '%1$d of %2$d issues are shown', count($triggers), $triggersTotalCount)); $infoDiv->addStyle('text-align: right; padding-right: 3px;'); return new CDiv(array($table, $infoDiv, $script)); }
function getLastEvents($options) { if (!isset($options['limit'])) { $options['limit'] = 15; } $triggerOptions = array('filter' => array(), 'skipDependent' => 1, 'selectHosts' => array('hostid', 'host'), 'output' => API_OUTPUT_EXTEND, 'sortfield' => 'lastchange', 'sortorder' => ZBX_SORT_DOWN, 'limit' => $options['triggerLimit']); $eventOptions = array('source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'output' => API_OUTPUT_EXTEND, 'sortfield' => array('clock', 'eventid'), 'sortorder' => ZBX_SORT_DOWN); if (isset($options['eventLimit'])) { $eventOptions['limit'] = $options['eventLimit']; } if (isset($options['nodeids'])) { $triggerOptions['nodeids'] = $options['nodeids']; } if (isset($options['priority'])) { $triggerOptions['filter']['priority'] = $options['priority']; } if (isset($options['monitored'])) { $triggerOptions['monitored'] = $options['monitored']; } if (isset($options['lastChangeSince'])) { $triggerOptions['lastChangeSince'] = $options['lastChangeSince']; $eventOptions['time_from'] = $options['lastChangeSince']; } if (isset($options['value'])) { $triggerOptions['filter']['value'] = $options['value']; $eventOptions['value'] = $options['value']; } // triggers $triggers = API::Trigger()->get($triggerOptions); $triggers = zbx_toHash($triggers, 'triggerid'); // events $eventOptions['objectids'] = zbx_objectValues($triggers, 'triggerid'); $events = API::Event()->get($eventOptions); $sortClock = array(); $sortEvent = array(); foreach ($events as $enum => $event) { if (!isset($triggers[$event['objectid']])) { continue; } $events[$enum]['trigger'] = $triggers[$event['objectid']]; $events[$enum]['host'] = reset($events[$enum]['trigger']['hosts']); $sortClock[$enum] = $event['clock']; $sortEvent[$enum] = $event['eventid']; //expanding description for the state where event was $merged_event = array_merge($event, $triggers[$event['objectid']]); $events[$enum]['trigger']['description'] = CMacrosResolverHelper::resolveEventDescription($merged_event); } array_multisort($sortClock, SORT_DESC, $sortEvent, SORT_DESC, $events); return $events; }
/** * Create DIV with latest problem triggers. * * If no sortfield and sortorder are defined, the sort indicater in the column name will not be displayed. * * @param array $filter['groupids'] * @param array $filter['hostids'] * @param array $filter['maintenance'] * @param int $filter['extAck'] * @param int $filter['severity'] * @param int $filter['limit'] * @param string $filter['sortfield'] * @param string $filter['sortorder'] * @param string $backurl * * @return CDiv */ function make_latest_issues(array $filter = [], $backurl) { // hide the sort indicator if no sortfield and sortorder are given $show_sort_indicator = isset($filter['sortfield']) || isset($filter['sortorder']); if (isset($filter['sortfield']) && $filter['sortfield'] !== 'lastchange') { $sort_field = [$filter['sortfield'], 'lastchange']; $sort_order = [$filter['sortorder'], ZBX_SORT_DOWN]; } else { $sort_field = ['lastchange']; $sort_order = [ZBX_SORT_DOWN]; } $options = ['groupids' => $filter['groupids'], 'hostids' => isset($filter['hostids']) ? $filter['hostids'] : null, 'monitored' => true, 'maintenance' => $filter['maintenance'], 'search' => $filter['trigger_name'] !== '' ? ['description' => $filter['trigger_name']] : null, 'filter' => ['priority' => $filter['severity'], 'value' => TRIGGER_VALUE_TRUE]]; $triggers = API::Trigger()->get(array_merge($options, ['output' => ['triggerid', 'expression', 'description', 'url', 'priority', 'lastchange', 'comments', 'error', 'state'], 'selectHosts' => ['hostid'], 'selectLastEvent' => ['eventid', 'acknowledged', 'objectid', 'clock', 'ns'], 'withLastEventUnacknowledged' => isset($filter['extAck']) && $filter['extAck'] == EXTACK_OPTION_UNACK ? true : null, 'skipDependent' => true, 'sortfield' => $sort_field, 'sortorder' => $sort_order, 'limit' => isset($filter['limit']) ? $filter['limit'] : DEFAULT_LATEST_ISSUES_CNT, 'preservekeys' => true, 'expandComment' => true])); $triggers = CMacrosResolverHelper::resolveTriggerUrls($triggers); // don't use withLastEventUnacknowledged and skipDependent because of performance issues $triggers_total_count = API::Trigger()->get(array_merge($options, ['countOutput' => true])); // get acknowledges $hostids = []; $eventids = []; foreach ($triggers as $trigger) { foreach ($trigger['hosts'] as $host) { $hostids[$host['hostid']] = true; } if ($trigger['lastEvent']) { $eventids[] = $trigger['lastEvent']['eventid']; } } $config = select_config(); if ($config['event_ack_enable'] && $eventids) { $event_acknowledges = API::Event()->get(['output' => ['eventid'], 'eventids' => $eventids, 'select_acknowledges' => API_OUTPUT_EXTEND, 'preservekeys' => true]); } // actions $actions = makeEventsActions($eventids); // indicator of sort field if ($show_sort_indicator) { $sort_div = (new CDiv())->addClass($filter['sortorder'] === ZBX_SORT_DOWN ? ZBX_STYLE_ARROW_DOWN : ZBX_STYLE_ARROW_UP); } $table = (new CTableInfo())->setHeader([$show_sort_indicator && $filter['sortfield'] === 'hostname' ? [_('Host'), $sort_div] : _('Host'), $show_sort_indicator && $filter['sortfield'] === 'priority' ? [_('Issue'), $sort_div] : _('Issue'), $show_sort_indicator && $filter['sortfield'] === 'lastchange' ? [_('Last change'), $sort_div] : _('Last change'), _('Age'), _('Info'), $config['event_ack_enable'] ? _('Ack') : null, _('Actions')]); $hostids = array_keys($hostids); $scripts = API::Script()->getScriptsByHosts($hostids); // get hosts $hosts = API::Host()->get(['hostids' => $hostids, 'output' => ['hostid', 'name', 'status', 'maintenance_status', 'maintenance_type', 'maintenanceid'], 'selectGraphs' => API_OUTPUT_COUNT, 'selectScreens' => API_OUTPUT_COUNT, 'preservekeys' => true]); $maintenanceids = []; foreach ($hosts as $host) { if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { $maintenanceids[$host['maintenanceid']] = true; } } if ($maintenanceids) { $maintenances = API::Maintenance()->get(['maintenanceids' => array_keys($maintenanceids), 'output' => ['name', 'description'], 'preservekeys' => true]); } // triggers foreach ($triggers as $trigger) { $host_list = []; foreach ($trigger['hosts'] as $trigger_host) { $host = $hosts[$trigger_host['hostid']]; $host_name = (new CSpan($host['name']))->addClass(ZBX_STYLE_LINK_ACTION)->setMenuPopup(CMenuPopupHelper::getHost($host, $scripts[$host['hostid']])); if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { $maintenance_icon = (new CSpan())->addClass(ZBX_STYLE_ICON_MAINT)->addClass(ZBX_STYLE_CURSOR_POINTER); if (array_key_exists($host['maintenanceid'], $maintenances)) { $maintenance = $maintenances[$host['maintenanceid']]; $hint = $maintenance['name'] . ' [' . ($host['maintenance_type'] ? _('Maintenance without data collection') : _('Maintenance with data collection')) . ']'; if ($maintenance['description']) { $hint .= "\n" . $maintenance['description']; } $maintenance_icon->setHint($hint); } $host_name = (new CSpan([$host_name, $maintenance_icon]))->addClass(ZBX_STYLE_REL_CONTAINER); } $host_list[] = $host_name; $host_list[] = ', '; } array_pop($host_list); // unknown triggers $unknown = ''; if ($trigger['state'] == TRIGGER_STATE_UNKNOWN) { $unknown = makeUnknownIcon($trigger['error']); } // trigger has events if ($trigger['lastEvent']) { // description $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, ['clock' => $trigger['lastEvent']['clock'], 'ns' => $trigger['lastEvent']['ns']])); } else { // description $description = CMacrosResolverHelper::resolveEventDescription(zbx_array_merge($trigger, ['clock' => $trigger['lastchange'], 'ns' => '999999999'])); } if ($config['event_ack_enable']) { if ($trigger['lastEvent']) { $trigger['lastEvent']['acknowledges'] = $event_acknowledges[$trigger['lastEvent']['eventid']]['acknowledges']; $ack = getEventAckState($trigger['lastEvent'], $backurl); } else { $ack = (new CSpan(_('No events')))->addClass(ZBX_STYLE_GREY); } } else { $ack = null; } // description if ($trigger['lastEvent'] || $trigger['comments'] !== '' || $trigger['url'] !== '') { $description = (new CSpan($description))->setHint(make_popup_eventlist($trigger, $backurl), '', true, 'max-width: 500px')->addClass(ZBX_STYLE_LINK_ACTION); } $description = (new CCol($description))->addClass(getSeverityStyle($trigger['priority'])); // clock $clock = new CLink(zbx_date2str(DATE_TIME_FORMAT_SECONDS, $trigger['lastchange']), 'events.php?filter_set=1&triggerid=' . $trigger['triggerid'] . '&period=' . ZBX_PERIOD_DEFAULT . '&stime=' . date(TIMESTAMP_FORMAT, $trigger['lastchange'])); // actions $action_hint = $trigger['lastEvent'] && isset($actions[$trigger['lastEvent']['eventid']]) ? $actions[$trigger['lastEvent']['eventid']] : SPACE; $table->addRow([new CCol($host_list), $description, $clock, zbx_date2age($trigger['lastchange']), $unknown, $ack, (new CCol($action_hint))->addClass(ZBX_STYLE_NOWRAP)]); } // initialize blinking zbx_add_post_js('jqBlink.blink();'); $info = _n('%1$d of %2$d issue is shown', '%1$d of %2$d issues are shown', count($triggers), $triggers_total_count); return [$table, $info]; }
require_once dirname(__FILE__) . '/include/page_header.php'; define('PAGE_SIZE', 100); // VAR TYPE OPTIONAL FLAGS VALIDATION EXCEPTION $fields = ['triggerid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, PAGE_TYPE_HTML . '==' . $page['type']], 'eventid' => [T_ZBX_INT, O_OPT, P_SYS, DB_ID, PAGE_TYPE_HTML . '==' . $page['type']], 'fullscreen' => [T_ZBX_INT, O_OPT, P_SYS, IN('0,1'), null], 'widget' => [T_ZBX_STR, O_OPT, P_ACT, IN('"' . WIDGET_HAT_EVENTACK . '","' . WIDGET_HAT_EVENTACTIONMSGS . '","' . WIDGET_HAT_EVENTACTIONMCMDS . '","' . WIDGET_HAT_EVENTLIST . '"'), null], 'state' => [T_ZBX_INT, O_OPT, P_ACT, IN('0,1'), null]]; check_fields($fields); /* * Ajax */ if (hasRequest('widget') && hasRequest('state')) { CProfile::update('web.tr_events.hats.' . getRequest('widget') . '.state', getRequest('state'), PROFILE_TYPE_INT); } if ($page['type'] == PAGE_TYPE_JS || $page['type'] == PAGE_TYPE_HTML_BLOCK) { require_once dirname(__FILE__) . '/include/page_footer.php'; exit; } // triggers $triggers = API::Trigger()->get(['output' => API_OUTPUT_EXTEND, 'selectHosts' => API_OUTPUT_EXTEND, 'triggerids' => getRequest('triggerid')]); if (!$triggers) { access_deny(); } $trigger = reset($triggers); // events $events = API::Event()->get(['output' => API_OUTPUT_EXTEND, 'select_alerts' => API_OUTPUT_EXTEND, 'select_acknowledges' => API_OUTPUT_EXTEND, 'selectHosts' => API_OUTPUT_EXTEND, 'source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'eventids' => getRequest('eventid'), 'objectids' => getRequest('triggerid')]); $event = reset($events); /* * Display */ $config = select_config(); $eventTab = (new CTable())->addRow([new CDiv([(new CUiWidget(WIDGET_HAT_TRIGGERDETAILS, make_trigger_details($trigger)))->setHeader(_('Event source details')), (new CUiWidget(WIDGET_HAT_EVENTDETAILS, make_event_details($event, $trigger, $page['file'] . '?triggerid=' . getRequest('triggerid') . '&eventid=' . getRequest('eventid'))))->setHeader(_('Event details'))]), new CDiv([$config['event_ack_enable'] ? (new CCollapsibleUiWidget(WIDGET_HAT_EVENTACK, makeAckTab($event['acknowledges'])))->setExpanded((bool) CProfile::get('web.tr_events.hats.' . WIDGET_HAT_EVENTACK . '.state', true))->setHeader(_('Acknowledges'), [], false, 'tr_events.php') : null, (new CCollapsibleUiWidget(WIDGET_HAT_EVENTACTIONMSGS, getActionMessages($event['alerts'])))->setExpanded((bool) CProfile::get('web.tr_events.hats.' . WIDGET_HAT_EVENTACTIONMSGS . '.state', true))->setHeader(_('Message actions'), [], false, 'tr_events.php'), (new CCollapsibleUiWidget(WIDGET_HAT_EVENTACTIONMCMDS, getActionCommands($event['alerts'])))->setExpanded((bool) CProfile::get('web.tr_events.hats.' . WIDGET_HAT_EVENTACTIONMCMDS . '.state', true))->setHeader(_('Command actions'), [], false, 'tr_events.php'), (new CCollapsibleUiWidget(WIDGET_HAT_EVENTLIST, make_small_eventlist($event, $page['file'] . '?triggerid=' . getRequest('triggerid') . '&eventid=' . getRequest('eventid'))))->setExpanded((bool) CProfile::get('web.tr_events.hats.' . WIDGET_HAT_EVENTLIST . '.state', true))->setHeader(_('Event list [previous 20]'), [], false, 'tr_events.php')])]); $eventWidget = (new CWidget())->setTitle(_('Event details'))->setControls((new CList())->addItem(get_icon('fullscreen', ['fullscreen' => getRequest('fullscreen')])))->addItem($eventTab)->show(); require_once dirname(__FILE__) . '/include/page_footer.php';
$event = reset($events); $eventTriggerName = CMacrosResolverHelper::resolveTriggerName($event['relatedObject']); $eventAcknowledged = $event['acknowledged']; } $_REQUEST['events'] = $_REQUEST['eventid']; } if (isset($_REQUEST['save']) || isset($_REQUEST['saveandreturn'])) { if ($bulk) { $_REQUEST['message'] .= $_REQUEST['message'] == '' ? '' : "\n\r" . _('----[BULK ACKNOWLEDGE]----'); } if (isset($_REQUEST['events'])) { $_REQUEST['events'] = zbx_toObject($_REQUEST['events'], 'eventid'); } elseif (isset($_REQUEST['triggers'])) { $_REQUEST['events'] = API::Event()->get(array('source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'objectids' => $_REQUEST['triggers'], 'output' => array('eventid'), 'acknowledged' => EVENT_NOT_ACKNOWLEDGED)); } $acknowledgeEvent = API::Event()->acknowledge(array('eventids' => zbx_objectValues($_REQUEST['events'], 'eventid'), 'message' => $_REQUEST['message'])); show_messages($acknowledgeEvent, _('Event acknowledged'), _('Cannot acknowledge event')); if ($acknowledgeEvent) { $eventAcknowledged = true; add_audit(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_TRIGGER, _('Acknowledge added') . ' [' . ($bulk ? ' BULK ACKNOWLEDGE ' : $eventTriggerName) . ']' . ' [' . $_REQUEST['message'] . ']'); } if (isset($_REQUEST['saveandreturn'])) { ob_end_clean(); if (in_array($_REQUEST['backurl'], array('tr_events.php', 'events.php'))) { redirect($_REQUEST['backurl'] . '?eventid=' . $_REQUEST['eventid'] . '&triggerid=' . $_REQUEST['triggerid']); } elseif ($_REQUEST['backurl'] == 'screenedit.php') { redirect($_REQUEST['backurl'] . '?screenid=' . $_REQUEST['screenid']); } elseif ($_REQUEST['backurl'] == 'screens.php') { redirect($_REQUEST['backurl'] . '?elementid=' . $_REQUEST['screenid']); } else { redirect($_REQUEST['backurl']);
protected function addRelatedObjects(array $options, array $result) { $result = parent::addRelatedObjects($options, $result); $triggerids = array_keys($result); // adding trigger dependencies if ($options['selectDependencies'] !== null && $options['selectDependencies'] != API_OUTPUT_COUNT) { $res = DBselect('SELECT td.triggerid_up,td.triggerid_down' . ' FROM trigger_depends td' . ' WHERE ' . dbConditionInt('td.triggerid_down', $triggerids)); $relationMap = new CRelationMap(); while ($relation = DBfetch($res)) { $relationMap->addRelation($relation['triggerid_down'], $relation['triggerid_up']); } $dependencies = $this->get(array('triggerids' => $relationMap->getRelatedIds(), 'output' => $options['selectDependencies'], 'expandData' => true, 'preservekeys' => true)); $result = $relationMap->mapMany($result, $dependencies, 'dependencies'); } // adding items if ($options['selectItems'] !== null && $options['selectItems'] != API_OUTPUT_COUNT) { $relationMap = $this->createRelationMap($result, 'triggerid', 'itemid', 'functions'); $items = API::Item()->get(array('nodeids' => $options['nodeids'], 'output' => $options['selectItems'], 'itemids' => $relationMap->getRelatedIds(), 'webitems' => true, 'nopermissions' => true, 'preservekeys' => true)); $result = $relationMap->mapMany($result, $items, 'items'); } // adding discoveryrule if ($options['selectDiscoveryRule'] !== null && $options['selectDiscoveryRule'] != API_OUTPUT_COUNT) { $dbRules = DBselect('SELECT id.parent_itemid,td.triggerid' . ' FROM trigger_discovery td,item_discovery id,functions f' . ' WHERE ' . dbConditionInt('td.triggerid', $triggerids) . ' AND td.parent_triggerid=f.triggerid' . ' AND f.itemid=id.itemid'); $relationMap = new CRelationMap(); while ($rule = DBfetch($dbRules)) { $relationMap->addRelation($rule['triggerid'], $rule['parent_itemid']); } $discoveryRules = API::DiscoveryRule()->get(array('output' => $options['selectDiscoveryRule'], 'nodeids' => $options['nodeids'], 'itemids' => $relationMap->getRelatedIds(), 'nopermissions' => true, 'preservekeys' => true)); $result = $relationMap->mapOne($result, $discoveryRules, 'discoveryRule'); } // adding last event if ($options['selectLastEvent'] !== null) { foreach ($result as $triggerId => $trigger) { $lastEvent = API::Event()->get(array('source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'objectids' => $triggerId, 'output' => $options['selectLastEvent'], 'nopermissions' => true, 'sortfield' => array('clock', 'eventid'), 'sortorder' => ZBX_SORT_DOWN, 'limit' => 1)); $result[$triggerId]['lastEvent'] = $lastEvent ? reset($lastEvent) : array(); } } return $result; }
* Because events in slices are sorted descending by eventid (i.e. bigger eventid), * first event in next slice must have eventid that is previous to last eventid in current slice. */ $lastEvent = end($allEventsSlice); $eventOptions['eventid_till'] = $lastEvent['eventid'] - 1; } /* * At this point it is possible that more than $config['search_limit'] events are selected, * therefore at most only first $config['search_limit'] + 1 events will be used for pagination. */ $events = array_slice($events, 0, $config['search_limit'] + 1); // get paging $url = (new CUrl('events.php'))->setArgument('fullscreen', getRequest('fullscreen'))->setArgument('groupid', $pageFilter->groupid)->setArgument('hostid', $pageFilter->hostid); $paging = getPagingLine($events, ZBX_SORT_DOWN, $url); // query event with extend data $events = API::Event()->get(['source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'eventids' => zbx_objectValues($events, 'eventid'), 'output' => API_OUTPUT_EXTEND, 'select_acknowledges' => API_OUTPUT_COUNT, 'sortfield' => ['clock', 'eventid'], 'sortorder' => ZBX_SORT_DOWN, 'nopermissions' => true]); $triggers = API::Trigger()->get(['output' => ['triggerid', 'description', 'expression', 'priority', 'flags', 'url'], 'selectHosts' => ['hostid', 'name', 'status'], 'selectItems' => ['itemid', 'hostid', 'name', 'key_', 'value_type'], 'triggerids' => zbx_objectValues($events, 'objectid'), 'preservekeys' => true]); $triggers = CMacrosResolverHelper::resolveTriggerUrls($triggers); // fetch hosts $hosts = []; foreach ($triggers as &$trigger) { $hosts[] = reset($trigger['hosts']); // Add already filtered read and read-write 'groupid' and 'hostid' to pass to menu pop-up "Events" link. $trigger['groupid'] = $pageFilter->groupid; $trigger['hostid'] = $pageFilter->hostid; } unset($trigger); $hostids = zbx_objectValues($hosts, 'hostid'); $hosts = API::Host()->get(['output' => ['name', 'hostid', 'status'], 'hostids' => $hostids, 'selectGraphs' => API_OUTPUT_COUNT, 'selectScreens' => API_OUTPUT_COUNT, 'preservekeys' => true]); // fetch scripts for the host JS menu if (!$csvExport && $pageFilter->hostid == 0) {
$triggers[$tnum]['hasEvents'] = isset($allEventCounts[$trigger['triggerid']]); } } } } if ($showEvents != EVENTS_OPTION_NOEVENT) { $options = array('source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'nodeids' => get_current_nodeid(), 'objectids' => zbx_objectValues($triggers, 'triggerid'), 'output' => API_OUTPUT_EXTEND, 'select_acknowledges' => API_OUTPUT_COUNT, 'time_from' => time() - $config['event_expire'] * SEC_PER_DAY, 'time_till' => time(), 'sortfield' => array('clock', 'eventid'), 'sortorder' => ZBX_SORT_DOWN); switch ($showEvents) { case EVENTS_OPTION_ALL: break; case EVENTS_OPTION_NOT_ACK: $options['acknowledged'] = false; $options['value'] = TRIGGER_VALUE_TRUE; break; } $events = API::Event()->get($options); foreach ($events as $event) { $triggers[$event['objectid']]['events'][] = $event; } } // get host ids $hostIds = array(); foreach ($triggers as $tnum => $trigger) { foreach ($trigger['hosts'] as $host) { $hostIds[$host['hostid']] = $host['hostid']; } } // get hosts $hosts = API::Host()->get(array('hostids' => $hostIds, 'preservekeys' => true, 'selectScreens' => API_OUTPUT_COUNT)); // get host scripts $scriptsByHosts = API::Script()->getScriptsByHosts($hostIds);
$event_trigger = reset($event['triggers']); $event_acknowledged = $event['acknowledged']; $_REQUEST['events'] = $_REQUEST['eventid']; } if (isset($_REQUEST['save']) || isset($_REQUEST['saveandreturn'])) { if ($bulk) { $_REQUEST['message'] .= $_REQUEST['message'] == '' ? '' : "\n\r" . _('----[BULK ACKNOWLEDGE]----'); } if (isset($_REQUEST['events'])) { $_REQUEST['events'] = zbx_toObject($_REQUEST['events'], 'eventid'); } elseif (isset($_REQUEST['triggers'])) { $options = array('output' => API_OUTPUT_SHORTEN, 'acknowledged' => 0, 'triggerids' => $_REQUEST['triggers'], 'filter' => array('value_changed' => TRIGGER_VALUE_CHANGED_YES)); $_REQUEST['events'] = API::Event()->get($options); } $eventsData = array('eventids' => zbx_objectValues($_REQUEST['events'], 'eventid'), 'message' => $_REQUEST['message']); $result = API::Event()->acknowledge($eventsData); show_messages($result, _('Event acknowledged'), _('Cannot acknowledge event')); if ($result) { $event_acknowledged = true; add_audit(AUDIT_ACTION_UPDATE, AUDIT_RESOURCE_TRIGGER, _('Acknowledge added') . ' [' . $bulk ? ' BULK ACKNOWLEDGE ' : $event_trigger . ']' . ' [' . $_REQUEST['message'] . ']'); } if (isset($_REQUEST['saveandreturn'])) { ob_end_clean(); if ($_REQUEST['backurl'] == 'tr_events.php') { redirect($_REQUEST['backurl'] . '?eventid=' . $_REQUEST['eventid'] . '&triggerid=' . $_REQUEST['triggerid']); } elseif ($_REQUEST['backurl'] == 'screenedit.php') { redirect($_REQUEST['backurl'] . '?screenid=' . $_REQUEST['screenid']); } elseif ($_REQUEST['backurl'] == 'screens.php') { redirect($_REQUEST['backurl'] . '?elementid=' . $_REQUEST['screenid']); } else { redirect($_REQUEST['backurl']);