/** * Prepare map elements data. * Calculate problem triggers and priorities. Populate map elements with automatic icon mapping, acknowledging and * recent change markers. * * @param array $sysmap * @param int $options * @param int $options['severity_min'] Minimum trigger severity, default value is maximal (Disaster) * * @return array */ function getSelementsInfo($sysmap, array $options = array()) { if (!isset($options['severity_min'])) { $options['severity_min'] = TRIGGER_SEVERITY_NOT_CLASSIFIED; } $config = select_config(); $showUnacknowledged = $config['event_ack_enable'] ? $sysmap['show_unack'] : EXTACK_OPTION_ALL; $triggerIdToSelementIds = array(); $subSysmapTriggerIdToSelementIds = array(); $hostGroupIdToSelementIds = array(); $hostIdToSelementIds = array(); if ($sysmap['sysmapid']) { $iconMap = API::IconMap()->get(array('sysmapids' => $sysmap['sysmapid'], 'selectMappings' => API_OUTPUT_EXTEND, 'output' => API_OUTPUT_EXTEND)); $iconMap = reset($iconMap); } $hostsToGetInventories = array(); $selements = $sysmap['selements']; $selementIdToSubSysmaps = array(); foreach ($selements as $selementId => &$selement) { $selement['hosts'] = array(); $selement['triggers'] = array(); switch ($selement['elementtype']) { case SYSMAP_ELEMENT_TYPE_MAP: $sysmapIds = array($selement['elementid']); while (!empty($sysmapIds)) { $subSysmaps = API::Map()->get(array('sysmapids' => $sysmapIds, 'output' => array('sysmapid'), 'selectSelements' => API_OUTPUT_EXTEND, 'nopermissions' => true, 'preservekeys' => true)); if (!isset($selementIdToSubSysmaps[$selementId])) { $selementIdToSubSysmaps[$selementId] = array(); } $selementIdToSubSysmaps[$selementId] += $subSysmaps; $sysmapIds = array(); foreach ($subSysmaps as $subSysmap) { foreach ($subSysmap['selements'] as $subSysmapSelement) { switch ($subSysmapSelement['elementtype']) { case SYSMAP_ELEMENT_TYPE_MAP: $sysmapIds[] = $subSysmapSelement['elementid']; break; case SYSMAP_ELEMENT_TYPE_HOST_GROUP: $hostGroupIdToSelementIds[$subSysmapSelement['elementid']][$selementId] = $selementId; break; case SYSMAP_ELEMENT_TYPE_HOST: $hostIdToSelementIds[$subSysmapSelement['elementid']][$selementId] = $selementId; break; case SYSMAP_ELEMENT_TYPE_TRIGGER: $subSysmapTriggerIdToSelementIds[$subSysmapSelement['elementid']][$selementId] = $selementId; break; } } } } break; case SYSMAP_ELEMENT_TYPE_HOST_GROUP: $hostGroupId = $selement['elementid']; $hostGroupIdToSelementIds[$hostGroupId][$selementId] = $selementId; break; case SYSMAP_ELEMENT_TYPE_HOST: $hostId = $selement['elementid']; $hostIdToSelementIds[$hostId][$selementId] = $selementId; // if we have icon map applied, we need to get inventories for all hosts, // where automatic icon selection is enabled. if ($sysmap['iconmapid'] && $selement['use_iconmap']) { $hostsToGetInventories[] = $hostId; } break; case SYSMAP_ELEMENT_TYPE_TRIGGER: $triggerId = $selement['elementid']; $triggerIdToSelementIds[$triggerId][$selementId] = $selementId; break; } } unset($selement); // get host inventories if ($sysmap['iconmapid']) { $hostInventories = API::Host()->get(array('hostids' => $hostsToGetInventories, 'output' => array('hostid'), 'nopermissions' => true, 'preservekeys' => true, 'selectInventory' => API_OUTPUT_EXTEND)); } $allHosts = array(); if (!empty($hostIdToSelementIds)) { $hosts = API::Host()->get(array('hostids' => array_keys($hostIdToSelementIds), 'output' => array('name', 'status', 'maintenance_status', 'maintenanceid'), 'nopermissions' => true, 'preservekeys' => true)); $allHosts = array_merge($allHosts, $hosts); foreach ($hosts as $hostId => $host) { foreach ($hostIdToSelementIds[$hostId] as $selementId) { $selements[$selementId]['hosts'][$hostId] = $hostId; } } } $hostsFromHostGroups = array(); if (!empty($hostGroupIdToSelementIds)) { $hostsFromHostGroups = API::Host()->get(array('groupids' => array_keys($hostGroupIdToSelementIds), 'output' => array('name', 'status', 'maintenance_status', 'maintenanceid'), 'selectGroups' => array('groupid'), 'nopermissions' => true, 'preservekeys' => true)); foreach ($hostsFromHostGroups as $hostId => $host) { foreach ($host['groups'] as $group) { $groupId = $group['groupid']; if (isset($hostGroupIdToSelementIds[$groupId])) { foreach ($hostGroupIdToSelementIds[$groupId] as $selementId) { $selement =& $selements[$selementId]; $selement['hosts'][$hostId] = $hostId; // add hosts to hosts_map for trigger selection; if (!isset($hostIdToSelementIds[$hostId])) { $hostIdToSelementIds[$hostId] = array(); } $hostIdToSelementIds[$hostId][$selementId] = $selementId; unset($selement); } } } } $allHosts = array_merge($allHosts, $hostsFromHostGroups); } $allHosts = zbx_toHash($allHosts, 'hostid'); // get triggers data, triggers from current map, select all $allTriggers = array(); if (!empty($triggerIdToSelementIds)) { $triggerOptions = array('output' => array('triggerid', 'status', 'value', 'priority', 'lastchange', 'description', 'expression'), 'triggerids' => array_keys($triggerIdToSelementIds), 'filter' => array('state' => null), 'nopermissions' => true, 'preservekeys' => true); if ($showUnacknowledged) { $triggerOptions['selectLastEvent'] = array('acknowledged'); } $triggers = API::Trigger()->get($triggerOptions); $allTriggers = array_merge($allTriggers, $triggers); foreach ($triggers as $triggerId => $trigger) { foreach ($triggerIdToSelementIds[$triggerId] as $selementId) { $selements[$selementId]['triggers'][$triggerId] = $triggerId; } } } // triggers from submaps, skip dependent if (!empty($subSysmapTriggerIdToSelementIds)) { $triggerOptions = array('output' => array('triggerid', 'status', 'value', 'priority', 'lastchange', 'description', 'expression'), 'triggerids' => array_keys($subSysmapTriggerIdToSelementIds), 'filter' => array('state' => null), 'skipDependent' => true, 'nopermissions' => true, 'preservekeys' => true, 'only_true' => true); if ($showUnacknowledged) { $triggerOptions['selectLastEvent'] = array('acknowledged'); } $triggers = API::Trigger()->get($triggerOptions); $allTriggers = array_merge($allTriggers, $triggers); foreach ($triggers as $triggerId => $trigger) { foreach ($subSysmapTriggerIdToSelementIds[$triggerId] as $selementId) { $selements[$selementId]['triggers'][$triggerId] = $triggerId; } } } $monitoredHostIds = array(); foreach ($allHosts as $hostId => $host) { if ($host['status'] == HOST_STATUS_MONITORED) { $monitoredHostIds[$hostId] = $hostId; } } // triggers from all hosts/hostgroups, skip dependent if ($monitoredHostIds) { $triggerOptions = array('output' => array('triggerid', 'status', 'value', 'priority', 'lastchange', 'description', 'expression'), 'selectHosts' => array('hostid'), 'selectItems' => array('itemid'), 'hostids' => $monitoredHostIds, 'filter' => array('state' => null), 'monitored' => true, 'skipDependent' => true, 'nopermissions' => true, 'preservekeys' => true, 'only_true' => true); if ($showUnacknowledged) { $triggerOptions['selectLastEvent'] = array('acknowledged'); } $triggersFromMonitoredHosts = API::Trigger()->get($triggerOptions); foreach ($triggersFromMonitoredHosts as $triggerId => $trigger) { foreach ($trigger['hosts'] as $host) { $hostId = $host['hostid']; if (isset($hostIdToSelementIds[$hostId])) { foreach ($hostIdToSelementIds[$hostId] as $selementId) { $selements[$selementId]['triggers'][$triggerId] = $triggerId; } } } } $subSysmapHostApplicationFilters = getSelementHostApplicationFilters($selements, $selementIdToSubSysmaps, $hostsFromHostGroups); $selements = filterSysmapTriggers($selements, $subSysmapHostApplicationFilters, $triggersFromMonitoredHosts, $subSysmapTriggerIdToSelementIds); $allTriggers = array_merge($allTriggers, $triggersFromMonitoredHosts); } $allTriggers = zbx_toHash($allTriggers, 'triggerid'); $info = array(); foreach ($selements as $selementId => $selement) { $i = array('disabled' => 0, 'maintenance' => 0, 'problem' => 0, 'problem_unack' => 0, 'priority' => 0, 'trigger_disabled' => 0, 'latelyChanged' => false, 'ack' => true); foreach ($selement['hosts'] as $hostId) { $host = $allHosts[$hostId]; $last_hostid = $hostId; if ($host['status'] == HOST_STATUS_NOT_MONITORED) { $i['disabled']++; } elseif ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { $i['maintenance']++; } } foreach ($selement['triggers'] as $triggerId) { $trigger = $allTriggers[$triggerId]; if ($options['severity_min'] <= $trigger['priority']) { if ($trigger['status'] == TRIGGER_STATUS_DISABLED) { $i['trigger_disabled']++; } else { if ($trigger['value'] == TRIGGER_VALUE_TRUE) { $i['problem']++; $lastProblemId = $triggerId; if ($i['priority'] < $trigger['priority']) { $i['priority'] = $trigger['priority']; } } if ($showUnacknowledged && $trigger['lastEvent'] && !$trigger['lastEvent']['acknowledged']) { $i['problem_unack']++; } $i['latelyChanged'] |= time() - $trigger['lastchange'] < $config['blink_period']; } } } $i['ack'] = (bool) (!$i['problem_unack']); if ($sysmap['expandproblem'] && $i['problem'] == 1) { if (!isset($lastProblemId)) { $lastProblemId = null; } $i['problem_title'] = CMacrosResolverHelper::resolveTriggerName($allTriggers[$lastProblemId]); } if ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST && $i['maintenance'] == 1) { $mnt = get_maintenance_by_maintenanceid($allHosts[$last_hostid]['maintenanceid']); $i['maintenance_title'] = $mnt['name']; } // replace default icons if (!$selement['iconid_on']) { $selement['iconid_on'] = $selement['iconid_off']; } if (!$selement['iconid_maintenance']) { $selement['iconid_maintenance'] = $selement['iconid_off']; } if (!$selement['iconid_disabled']) { $selement['iconid_disabled'] = $selement['iconid_off']; } switch ($selement['elementtype']) { case SYSMAP_ELEMENT_TYPE_MAP: $info[$selementId] = getMapsInfo($selement, $i, $showUnacknowledged); break; case SYSMAP_ELEMENT_TYPE_HOST_GROUP: $info[$selementId] = getHostGroupsInfo($selement, $i, $showUnacknowledged); break; case SYSMAP_ELEMENT_TYPE_HOST: $info[$selementId] = getHostsInfo($selement, $i, $showUnacknowledged); if ($sysmap['iconmapid'] && $selement['use_iconmap']) { $info[$selementId]['iconid'] = getIconByMapping($iconMap, $hostInventories[$selement['elementid']]); } break; case SYSMAP_ELEMENT_TYPE_TRIGGER: $info[$selementId] = getTriggersInfo($selement, $i, $showUnacknowledged); break; case SYSMAP_ELEMENT_TYPE_IMAGE: $info[$selementId] = getImagesInfo($selement); break; } } if ($sysmap['label_format'] == SYSMAP_LABEL_ADVANCED_OFF) { $hlabel = $hglabel = $tlabel = $mlabel = $sysmap['label_type'] == MAP_LABEL_TYPE_NAME; } else { $hlabel = $sysmap['label_type_host'] == MAP_LABEL_TYPE_NAME; $hglabel = $sysmap['label_type_hostgroup'] == MAP_LABEL_TYPE_NAME; $tlabel = $sysmap['label_type_trigger'] == MAP_LABEL_TYPE_NAME; $mlabel = $sysmap['label_type_map'] == MAP_LABEL_TYPE_NAME; } // get names if needed $elems = separateMapElements($sysmap); if (!empty($elems['sysmaps']) && $mlabel) { $subSysmaps = API::Map()->get(array('sysmapids' => zbx_objectValues($elems['sysmaps'], 'elementid'), 'nopermissions' => true, 'output' => array('name'))); $subSysmaps = zbx_toHash($subSysmaps, 'sysmapid'); foreach ($elems['sysmaps'] as $elem) { $info[$elem['selementid']]['name'] = $subSysmaps[$elem['elementid']]['name']; } } if (!empty($elems['hostgroups']) && $hglabel) { $hostgroups = API::HostGroup()->get(array('groupids' => zbx_objectValues($elems['hostgroups'], 'elementid'), 'nopermissions' => true, 'output' => array('name'))); $hostgroups = zbx_toHash($hostgroups, 'groupid'); foreach ($elems['hostgroups'] as $elem) { $info[$elem['selementid']]['name'] = $hostgroups[$elem['elementid']]['name']; } } if (!empty($elems['triggers']) && $tlabel) { foreach ($elems['triggers'] as $elem) { $info[$elem['selementid']]['name'] = CMacrosResolverHelper::resolveTriggerName($allTriggers[$elem['elementid']]); } } if (!empty($elems['hosts']) && $hlabel) { foreach ($elems['hosts'] as $elem) { $info[$elem['selementid']]['name'] = $allHosts[$elem['elementid']]['name']; } } return $info; }
function getSelementsInfo($sysmap) { $config = select_config(); $show_unack = $config['event_ack_enable'] ? $sysmap['show_unack'] : EXTACK_OPTION_ALL; $triggers_map = array(); $triggers_map_submaps = array(); $hostgroups_map = array(); $hosts_map = array(); $selements = zbx_toHash($sysmap['selements'], 'selementid'); foreach ($selements as $selementid => $selement) { $selements[$selementid]['hosts'] = array(); $selements[$selementid]['triggers'] = array(); switch ($selement['elementtype']) { case SYSMAP_ELEMENT_TYPE_MAP: $mapids = array($selement['elementid']); while (!empty($mapids)) { $options = array('sysmapids' => $mapids, 'output' => API_OUTPUT_EXTEND, 'select_selements' => API_OUTPUT_EXTEND, 'nopermissions' => 1, 'nodeids' => get_current_nodeid(true)); $maps = CMap::get($options); $mapids = array(); foreach ($maps as $map) { foreach ($map['selements'] as $sel) { switch ($sel['elementtype']) { case SYSMAP_ELEMENT_TYPE_MAP: $mapids[] = $sel['elementid']; break; case SYSMAP_ELEMENT_TYPE_HOST_GROUP: $hostgroups_map[$sel['elementid']][$selementid] = $selementid; break; case SYSMAP_ELEMENT_TYPE_HOST: $hosts_map[$sel['elementid']][$selementid] = $selementid; break; case SYSMAP_ELEMENT_TYPE_TRIGGER: $triggers_map_submaps[$sel['elementid']][$selementid] = $selementid; break; } } } } break; case SYSMAP_ELEMENT_TYPE_HOST_GROUP: $hostgroups_map[$selement['elementid']][$selement['selementid']] = $selement['selementid']; break; case SYSMAP_ELEMENT_TYPE_HOST: $hosts_map[$selement['elementid']][$selement['selementid']] = $selement['selementid']; break; case SYSMAP_ELEMENT_TYPE_TRIGGER: $triggers_map[$selement['elementid']][$selement['selementid']] = $selement['selementid']; break; } } // get hosts data {{{ $all_hosts = array(); if (!empty($hosts_map)) { $options = array('hostids' => array_keys($hosts_map), 'output' => API_OUTPUT_EXTEND, 'nopermissions' => 1, 'nodeids' => get_current_nodeid(true)); $hosts = CHost::get($options); $all_hosts = array_merge($all_hosts, $hosts); foreach ($hosts as $host) { foreach ($hosts_map[$host['hostid']] as $belongs_to_sel) { $selements[$belongs_to_sel]['hosts'][$host['hostid']] = $host['hostid']; } } } if (!empty($hostgroups_map)) { $options = array('groupids' => array_keys($hostgroups_map), 'output' => API_OUTPUT_EXTEND, 'nopermissions' => 1, 'nodeids' => get_current_nodeid(true)); $hosts = CHost::get($options); $all_hosts = array_merge($all_hosts, $hosts); foreach ($hosts as $host) { foreach ($host['groups'] as $group) { foreach ($hostgroups_map[$group['groupid']] as $belongs_to_sel) { $selements[$belongs_to_sel]['hosts'][$host['hostid']] = $host['hostid']; // add hosts to hosts_map for trigger selection; if (!isset($hosts_map[$host['hostid']])) { $hosts_map[$host['hostid']] = array(); } $hosts_map[$host['hostid']][$belongs_to_sel] = $belongs_to_sel; } } } } $all_hosts = zbx_toHash($all_hosts, 'hostid'); $monitored_hostids = array(); foreach ($all_hosts as $hostid => $host) { if ($host['status'] == HOST_STATUS_MONITORED) { $monitored_hostids[$hostid] = $hostid; } } // }}} // get triggers data {{{ $all_triggers = array(); // triggers from current map, select all if (!empty($triggers_map)) { $options = array('nodeids' => get_current_nodeid(true), 'triggerids' => array_keys($triggers_map), 'output' => API_OUTPUT_EXTEND, 'nopermissions' => 1); $triggers = CTrigger::get($options); $all_triggers = array_merge($all_triggers, $triggers); foreach ($triggers as $trigger) { foreach ($triggers_map[$trigger['triggerid']] as $belongs_to_sel) { $selements[$belongs_to_sel]['triggers'][$trigger['triggerid']] = $trigger['triggerid']; } } } // triggers from submaps, skip dependent if (!empty($triggers_map_submaps)) { $options = array('nodeids' => get_current_nodeid(true), 'triggerids' => array_keys($triggers_map_submaps), 'filter' => array('value' => array(TRIGGER_VALUE_UNKNOWN, TRIGGER_VALUE_TRUE)), 'skipDependent' => 1, 'output' => API_OUTPUT_EXTEND, 'nopermissions' => 1); $triggers = CTrigger::get($options); $all_triggers = array_merge($all_triggers, $triggers); foreach ($triggers as $trigger) { foreach ($triggers_map_submaps[$trigger['triggerid']] as $belongs_to_sel) { $selements[$belongs_to_sel]['triggers'][$trigger['triggerid']] = $trigger['triggerid']; } } } // triggers from all hosts/hostgroups, skip dependent if (!empty($monitored_hostids)) { $options = array('hostids' => $monitored_hostids, 'output' => API_OUTPUT_EXTEND, 'nopermissions' => 1, 'filter' => array('value' => array(TRIGGER_VALUE_UNKNOWN, TRIGGER_VALUE_TRUE)), 'nodeids' => get_current_nodeid(true), 'monitored' => true, 'skipDependent' => 1); $triggers = CTrigger::get($options); $all_triggers = array_merge($all_triggers, $triggers); foreach ($triggers as $trigger) { foreach ($trigger['hosts'] as $host) { foreach ($hosts_map[$host['hostid']] as $belongs_to_sel) { $selements[$belongs_to_sel]['triggers'][$trigger['triggerid']] = $trigger['triggerid']; } } } } $all_triggers = zbx_toHash($all_triggers, 'triggerid'); $options = array('triggerids' => array_keys($all_triggers), 'withLastEventUnacknowledged' => true, 'output' => API_OUTPUT_SHORTEN, 'nodeids' => get_current_nodeid(true), 'nopermissions' => 1, 'monitored' => true, 'filter' => array('value' => TRIGGER_VALUE_TRUE)); $unack_triggerids = CTrigger::get($options); $unack_triggerids = zbx_toHash($unack_triggerids, 'triggerid'); // }}} $info = array(); foreach ($selements as $selementid => $selement) { $i = array('disabled' => 0, 'maintenance' => 0, 'problem' => 0, 'problem_unack' => 0, 'unknown' => 0, 'priority' => 0, 'trigger_disabled' => 0, 'latelyChanged' => false, 'ack' => true); foreach ($selement['hosts'] as $hostid) { $host = $all_hosts[$hostid]; $last_hostid = $hostid; if ($host['status'] == HOST_STATUS_NOT_MONITORED) { $i['disabled']++; } else { if ($host['maintenance_status'] == HOST_MAINTENANCE_STATUS_ON) { $i['maintenance']++; } } } foreach ($selement['triggers'] as $triggerid) { $trigger = $all_triggers[$triggerid]; if ($trigger['status'] == TRIGGER_STATUS_DISABLED) { $i['trigger_disabled']++; } else { if ($trigger['value'] == TRIGGER_VALUE_TRUE) { $i['problem']++; $last_problemid = $triggerid; if ($i['priority'] < $trigger['priority']) { $i['priority'] = $trigger['priority']; } } else { if ($trigger['value'] == TRIGGER_VALUE_UNKNOWN) { $i['unknown']++; } } if (isset($unack_triggerids[$triggerid])) { $i['problem_unack']++; } $i['latelyChanged'] |= time() - $trigger['lastchange'] < TRIGGER_BLINK_PERIOD; } } $i['ack'] = (bool) (!$i['problem_unack']); if ($sysmap['expandproblem'] && $i['problem'] == 1) { $i['problem_title'] = expand_trigger_description_by_data($all_triggers[$last_problemid]); } if ($selement['elementtype'] == SYSMAP_ELEMENT_TYPE_HOST && $i['maintenance'] == 1) { $mnt = get_maintenance_by_maintenanceid($all_hosts[$last_hostid]['maintenanceid']); $i['maintenance_title'] = $mnt['name']; } switch ($selement['elementtype']) { case SYSMAP_ELEMENT_TYPE_MAP: $info[$selementid] = getMapsInfo($selement, $i, $show_unack); break; case SYSMAP_ELEMENT_TYPE_HOST_GROUP: $info[$selementid] = getHostGroupsInfo($selement, $i, $show_unack); break; case SYSMAP_ELEMENT_TYPE_HOST: $info[$selementid] = getHostsInfo($selement, $i, $show_unack); break; case SYSMAP_ELEMENT_TYPE_TRIGGER: $info[$selementid] = getTriggersInfo($selement, $i); break; case SYSMAP_ELEMENT_TYPE_IMAGE: $info[$selementid] = getImagesInfo($selement); break; } } // get names if is needed if ($sysmap['label_type'] == MAP_LABEL_TYPE_NAME) { $elems = separateMapElements($sysmap); if (!empty($elems['sysmaps'])) { $maps = CMap::get(array('sysmapids' => zbx_objectValues($elems['sysmaps'], 'elementid'), 'nopermissions' => 1, 'output' => API_OUTPUT_EXTEND)); $maps = zbx_toHash($maps, 'sysmapid'); foreach ($elems['sysmaps'] as $elem) { $info[$elem['selementid']]['name'] = $maps[$elem['elementid']]['name']; } } if (!empty($elems['hostgroups'])) { $hostgroups = CHostGroup::get(array('groupids' => zbx_objectValues($elems['hostgroups'], 'elementid'), 'nopermissions' => 1, 'output' => API_OUTPUT_EXTEND)); $hostgroups = zbx_toHash($hostgroups, 'groupid'); foreach ($elems['hostgroups'] as $elem) { $info[$elem['selementid']]['name'] = $hostgroups[$elem['elementid']]['name']; } } if (!empty($elems['triggers'])) { foreach ($elems['triggers'] as $elem) { $info[$elem['selementid']]['name'] = expand_trigger_description_by_data($all_triggers[$elem['elementid']]); } } if (!empty($elems['hosts'])) { foreach ($elems['hosts'] as $elem) { $info[$elem['selementid']]['name'] = $all_hosts[$elem['elementid']]['host']; } } } return $info; }