/** * Creates nodes that can be used to display the SLA report tree using the CTree class. * * @see CTree * * @param array $services an array of services to display in the tree * @param array $slaData sla report data, see CService::getSla() * @param $period * @param array $parentService * @param array $service * @param array $dependency * @param array $tree */ function createServiceMonitoringTree(array $services, array $slaData, $period, &$tree, array $parentService = array(), array $service = array(), array $dependency = array()) { // if no parent service is given, start from the root if (!$service) { $serviceNode = array('id' => 0, 'parentid' => 0, 'caption' => _('root'), 'status' => SPACE, 'sla' => SPACE, 'sla2' => SPACE, 'trigger' => array(), 'reason' => SPACE, 'graph' => SPACE); $service = $serviceNode; $service['serviceid'] = 0; $service['dependencies'] = array(); $service['trigger'] = array(); // add all top level services as children of "root" foreach ($services as $topService) { if (!$topService['parent']) { $service['dependencies'][] = array('servicedownid' => $topService['serviceid'], 'soft' => 0, 'linkid' => 0); } } $tree = array($serviceNode); } else { $serviceSla = $slaData[$service['serviceid']]; $slaValues = reset($serviceSla['sla']); // caption // remember the selected time period when following the bar link $periods = array('today' => 'daily', 'week' => 'weekly', 'month' => 'monthly', 'year' => 'yearly', 24 => 'daily', 24 * 7 => 'weekly', 24 * 30 => 'monthly', 24 * DAY_IN_YEAR => 'yearly'); $caption = array(new CLink(array(get_node_name_by_elid($service['serviceid'], null, ': '), $service['name']), 'report3.php?serviceid=' . $service['serviceid'] . '&year=' . date('Y') . '&period=' . $periods[$period])); $trigger = $service['trigger']; if ($trigger) { $url = new CLink($trigger['description'], 'events.php?source=' . EVENT_SOURCE_TRIGGERS . '&triggerid=' . $trigger['triggerid']); $caption[] = ' - '; $caption[] = $url; } // reason $problemList = '-'; if ($serviceSla['problems']) { $problemList = new CList(null, 'service-problems'); foreach ($serviceSla['problems'] as $problemTrigger) { $problemList->addItem(new CLink($problemTrigger['description'], 'events.php?source=' . EVENT_SOURCE_TRIGGERS . '&triggerid=' . $problemTrigger['triggerid'])); } } // sla $sla = '-'; $sla2 = '-'; if ($service['showsla'] && $slaValues['sla'] !== null) { $slaGood = $slaValues['sla']; $slaBad = 100 - $slaValues['sla']; $p = min($slaBad, 20); $width = 160; $widthRed = $width * $p / 20; $widthGreen = $width - $widthRed; $chart1 = null; if ($widthGreen > 0) { $chart1 = new CDiv(null, 'sla-bar-part sla-green'); $chart1->setAttribute('style', 'width: ' . $widthGreen . 'px;'); } $chart2 = null; if ($widthRed > 0) { $chart2 = new CDiv(null, 'sla-bar-part sla-red'); $chart2->setAttribute('style', 'width: ' . $widthRed . 'px;'); } $bar = new CLink(array($chart1, $chart2, new CDiv('80%', 'sla-bar-legend sla-bar-legend-start'), new CDiv('100%', 'sla-bar-legend sla-bar-legend-end')), 'srv_status.php?serviceid=' . $service['serviceid'] . '&showgraph=1' . url_param('path')); $bar = new CDiv($bar, 'sla-bar'); $bar->setAttribute('title', _s('Only the last 20%% of the indicator is displayed.')); $slaBar = array($bar, new CSpan(sprintf('%.4f', $slaBad), 'sla-value ' . ($service['goodsla'] > $slaGood ? 'red' : 'green'))); $sla = new CDiv($slaBar, 'invisible'); $sla2 = array(new CSpan(sprintf('%.4f', $slaGood), 'sla-value ' . ($service['goodsla'] > $slaGood ? 'red' : 'green')), '/', new CSpan(sprintf('%.4f', $service['goodsla']), 'sla-value')); } $serviceNode = array('id' => $service['serviceid'], 'caption' => $caption, 'description' => $service['trigger'] ? $service['trigger']['description'] : _('None'), 'reason' => $problemList, 'sla' => $sla, 'sla2' => $sla2, 'parentid' => $parentService ? $parentService['serviceid'] : 0, 'status' => $serviceSla['status'] !== null ? $serviceSla['status'] : '-'); } // hard dependencies and dependencies for the "root" node if (!$dependency || $dependency['soft'] == 0) { $tree[$serviceNode['id']] = $serviceNode; foreach ($service['dependencies'] as $dependency) { $childService = $services[$dependency['servicedownid']]; createServiceMonitoringTree($services, $slaData, $period, $tree, $service, $childService, $dependency); } } else { $serviceNode['caption'] = new CSpan($serviceNode['caption'], 'service-caption-soft'); $tree[$serviceNode['id'] . '.' . $dependency['linkid']] = $serviceNode; } }
$service['trigger'] = $triggers[$service['trigger']['triggerid']]; } } unset($service); // fetch sla $slaData = API::Service()->getSla(array('intervals' => array(array('from' => $period_start, 'to' => $period_end)))); // expand problem trigger descriptions foreach ($slaData as &$serviceSla) { foreach ($serviceSla['problems'] as &$problemTrigger) { $problemTrigger['description'] = $triggers[$problemTrigger['triggerid']]['description']; } unset($problemTrigger); } unset($serviceSla); $treeData = array(); createServiceMonitoringTree($services, $slaData, $period, $treeData); $tree = new CServiceTree('service_status_tree', $treeData, array('caption' => _('Service'), 'status' => _('Status'), 'reason' => _('Reason'), 'sla' => _('Problem time'), 'sla2' => nbsp(_('SLA') . ' / ' . _('Acceptable SLA')))); if ($tree) { // creates form for choosing a preset interval $r_form = new CForm(); $r_form->setAttribute('class', 'nowrap'); $r_form->setMethod('get'); $r_form->setAttribute('name', 'period_choice'); $r_form->addVar('fullscreen', $_REQUEST['fullscreen']); $period_combo = new CComboBox('period', $period, 'javascript: submit();'); foreach ($periods as $key => $val) { $period_combo->addItem($key, $val); } $r_form->addItem(array(_('Period') . SPACE, $period_combo)); $srv_wdgt = new CWidget('hat_services', 'service-list service-mon'); $srv_wdgt->addPageHeader(_('IT SERVICES'), get_icon('fullscreen', array('fullscreen' => $_REQUEST['fullscreen'])));
/** * Creates nodes that can be used to display the SLA report tree using the CTree class. * * @see CTree * * @param array $services an array of services to display in the tree * @param array $slaData sla report data, see CService::getSla() * @param $period * @param array $parentService * @param array $service * @param array $dependency * @param array $tree */ function createServiceMonitoringTree(array $services, array $slaData, $period, &$tree, array $parentService = [], array $service = [], array $dependency = []) { // if no parent service is given, start from the root if (!$service) { $serviceNode = ['id' => 0, 'caption' => _('root'), 'reason' => '', 'sla' => '', 'sla2' => '', 'sla3' => '', 'parentid' => 0, 'status' => '']; $service = $serviceNode; $service['serviceid'] = 0; $service['dependencies'] = []; $service['trigger'] = []; // add all top level services as children of "root" foreach ($services as $topService) { if (!$topService['parent']) { $service['dependencies'][] = ['servicedownid' => $topService['serviceid'], 'soft' => 0, 'linkid' => 0]; } } $tree = [$serviceNode]; } else { $serviceSla = $slaData[$service['serviceid']]; $slaValues = reset($serviceSla['sla']); // caption // remember the selected time period when following the bar link $periods = ['today' => 'daily', 'week' => 'weekly', 'month' => 'monthly', 'year' => 'yearly', 24 => 'daily', 24 * 7 => 'weekly', 24 * 30 => 'monthly', 24 * DAY_IN_YEAR => 'yearly']; $caption = new CLink($service['name'], 'zabbix.php?action=report.services' . '&serviceid=' . $service['serviceid'] . '&period=' . $periods[$period]); $trigger = $service['trigger']; if ($trigger) { $caption = [$caption, ' - ', new CLink($trigger['description'], 'events.php?filter_set=1&source=' . EVENT_SOURCE_TRIGGERS . '&triggerid=' . $trigger['triggerid'])]; } // reason $reason = []; foreach ($serviceSla['problems'] as $problemTrigger) { if ($reason) { $reason[] = ', '; } $reason[] = new CLink($problemTrigger['description'], 'events.php?filter_set=1&source=' . EVENT_SOURCE_TRIGGERS . '&triggerid=' . $problemTrigger['triggerid']); } // sla $sla = ''; $sla2 = ''; $sla3 = ''; if ($service['showsla'] && $slaValues['sla'] !== null) { $sla_good = $slaValues['sla']; $sla_bad = 100 - $slaValues['sla']; $width = 160; $width_red = $width * min($sla_bad, 20) / 20; $width_green = $width - $width_red; $sla = (new CDiv(new CLink([(new CSpan([new CSpan('80%'), new CSpan('100%')]))->addClass(ZBX_STYLE_PROGRESS_BAR_LABEL), $width_green > 0 ? (new CSpan(' '))->addClass(ZBX_STYLE_PROGRESS_BAR_BG)->addClass(ZBX_STYLE_GREEN_BG)->setAttribute('style', 'width: ' . $width_green . 'px;') : null, $width_red > 0 ? (new CSpan(' '))->addClass(ZBX_STYLE_PROGRESS_BAR_BG)->addClass(ZBX_STYLE_RED_BG)->setAttribute('style', 'width: ' . $width_red . 'px;') : null], 'srv_status.php?serviceid=' . $service['serviceid'] . '&showgraph=1' . url_param('path'))))->addClass(ZBX_STYLE_PROGRESS_BAR_CONTAINER)->setAttribute('title', _s('Only the last 20%% of the indicator is displayed.')); $sla2 = (new CSpan(sprintf('%.4f', $sla_bad)))->addClass($service['goodsla'] > $sla_good ? ZBX_STYLE_RED : ZBX_STYLE_GREEN); $sla3 = [(new CSpan(sprintf('%.4f', $sla_good)))->addClass($service['goodsla'] > $sla_good ? ZBX_STYLE_RED : ZBX_STYLE_GREEN), ' / ', sprintf('%.4f', $service['goodsla'])]; } $serviceNode = ['id' => $service['serviceid'], 'caption' => $caption, 'reason' => $reason, 'sla' => $sla, 'sla2' => $sla2, 'sla3' => $sla3, 'parentid' => $parentService ? $parentService['serviceid'] : 0, 'status' => $serviceSla['status'] !== null ? $serviceSla['status'] : '']; } // hard dependencies and dependencies for the "root" node if (!$dependency || $dependency['soft'] == 0) { $tree[$serviceNode['id']] = $serviceNode; foreach ($service['dependencies'] as $dependency) { $childService = $services[$dependency['servicedownid']]; createServiceMonitoringTree($services, $slaData, $period, $tree, $service, $childService, $dependency); } } else { $serviceNode['caption'] = (new CSpan($serviceNode['caption']))->addClass('service-caption-soft'); $tree[$serviceNode['id'] . '.' . $dependency['linkid']] = $serviceNode; } }