*/ namespace Icinga\Module\Toplevelview\Tree; use Icinga\Application\Benchmark; use Icinga\Exception\NotFoundError; use Icinga\Module\Toplevelview\Monitoring\Servicestatus; class TLVServiceNode extends TLVIcingaNode { protected $type = 'service'; protected $key = '{host}!{service}'; public function getTitle() { return sprintf( '%s: %s', $this->get('host'), $this->get('service') ); } public function register() { // also register host, because that's what we fetch data with $hostDummy = new TLVHostNode(); $this->root->registerObject($hostDummy->getType(), $this->get('host'), get_class($hostDummy)); // register myself return parent::register(); } public function getKey() { return sprintf('%s!%s', $this->properties['host'], $this->properties['service']); } public static function fetch(TLVTree $root) { Benchmark::measure('Begin fetching services'); if (! array_key_exists('service', $root->registeredObjects) or empty($root->registeredObjects['service'])) { throw new NotFoundError('No services registered to fetch!'); } $names = array_keys($root->registeredObjects['host']); $columns = array( 'host_name', 'service_description', 'service_hard_state', 'service_handled', 'service_handled_wo_host', 'service_notifications_enabled', 'service_notification_period', 'service_is_flapping', 'service_in_downtime', ); $options = []; foreach (['notification_periods', 'host_never_unhandled', 'ignored_notification_periods'] as $opt) { $options[$opt] = $root->get($opt); } if ($root->get('notification_periods') === true) { $columns[] = 'service_in_notification_period'; } // Note: this uses a patched version of Servicestatus / ServicestatusQuery ! $services = new Servicestatus($root->getBackend(), $columns, $options); $services->where('host_name', $names); foreach ($services as $service) { $key = sprintf('%s!%s', $service->host_name, $service->service_description); if (array_key_exists($key, $root->registeredObjects['service'])) { $root->registeredObjects['service'][$key] = $service; } } Benchmark::measure('Finished fetching services'); } public function getStatus() { if ($this->status === null) { $this->status = $status = new TLVStatus(); $key = $this->getKey(); if (($data = $this->root->getFetched($this->type, $key)) !== null) { $status->zero(); $status->add('total'); $state = $data->service_hard_state; if ($this->getRoot()->get('notification_periods') === true) { $notInPeriod = $data->service_in_notification_period === '0'; } else { $notInPeriod = false; } if ($this->getRoot()->get('host_never_unhandled') === true) { $isHandled = $data->service_handled_wo_host === '1'; } else { $isHandled = $data->service_handled === '1'; } $isHandled = $isHandled || $data->service_is_flapping === '1'; if ($data->service_in_downtime > 0 || $data->service_notifications_enabled === '0' || $notInPeriod ) { $status->add('downtime_active'); if ($state !== '0') { $state = '10'; } } if ($isHandled) { $handled = '_handled'; } else { $handled = '_unhandled'; } if ($state === '0' || $state === '99') { $status->add('ok', 1); } elseif ($state === '1') { $status->add('warning' . $handled, 1); } elseif ($state === '2') { $status->add('critical' . $handled, 1); } elseif ($state === '10') { $status->add('downtime_handled'); } else { $status->add('unknown' . $handled, 1); } } else { $status->add('missing', 1); } } return $this->status; } }