/** * 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 make_small_eventlist($startEvent) { $config = select_config(); $table = new CTableInfo(_('No events found.')); $table->setHeader(array(_('Time'), _('Status'), _('Duration'), _('Age'), $config['event_ack_enable'] ? _('Ack') : null, _('Actions'))); $clock = $startEvent['clock']; $events = API::Event()->get(array('source' => EVENT_SOURCE_TRIGGERS, 'object' => EVENT_OBJECT_TRIGGER, 'objectids' => $startEvent['objectid'], 'eventid_till' => $startEvent['eventid'], 'output' => API_OUTPUT_EXTEND, 'select_acknowledges' => API_OUTPUT_COUNT, 'sortfield' => array('clock', 'eventid'), 'sortorder' => ZBX_SORT_DOWN, 'limit' => 20)); $sortFields = array(array('field' => 'clock', 'order' => ZBX_SORT_DOWN), array('field' => 'eventid', 'order' => ZBX_SORT_DOWN)); CArrayHelper::sort($events, $sortFields); $actions = getEventActionsStatHints(zbx_objectValues($events, 'eventid')); foreach ($events as $event) { $lclock = $clock; $duration = zbx_date2age($lclock, $event['clock']); $clock = $event['clock']; if (bccomp($startEvent['eventid'], $event['eventid']) == 0 && ($nextevent = get_next_event($event, $events))) { $duration = zbx_date2age($nextevent['clock'], $clock); } elseif (bccomp($startEvent['eventid'], $event['eventid']) == 0) { $duration = zbx_date2age($clock); } $eventStatusSpan = new CSpan(trigger_value2str($event['value'])); // add colors and blinking to span depending on configuration and trigger parameters addTriggerValueStyle($eventStatusSpan, $event['value'], $event['clock'], $event['acknowledged']); $ack = getEventAckState($event, true); $table->addRow(array(new CLink(zbx_date2str(_('d M Y H:i:s'), $event['clock']), 'tr_events.php?triggerid=' . $event['objectid'] . '&eventid=' . $event['eventid'], 'action'), $eventStatusSpan, $duration, zbx_date2age($event['clock']), $config['event_ack_enable'] ? $ack : null, isset($actions[$event['eventid']]) ? $actions[$event['eventid']] : SPACE)); } return $table; }