diff options
Diffstat (limited to 'library/Businessprocess/State/IcingaDbState.php')
-rw-r--r-- | library/Businessprocess/State/IcingaDbState.php | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/library/Businessprocess/State/IcingaDbState.php b/library/Businessprocess/State/IcingaDbState.php new file mode 100644 index 0000000..f33d4a4 --- /dev/null +++ b/library/Businessprocess/State/IcingaDbState.php @@ -0,0 +1,145 @@ +<?php + +namespace Icinga\Module\Businessprocess\State; + +use Exception; +use Icinga\Application\Benchmark; +use Icinga\Module\Businessprocess\BpConfig; +use Icinga\Module\Businessprocess\IcingaDbObject; +use Icinga\Module\Businessprocess\ServiceNode; +use Icinga\Module\Icingadb\Model\Host; +use Icinga\Module\Icingadb\Model\Service; +use ipl\Sql\Connection as IcingaDbConnection; +use ipl\Stdlib\Filter; + +class IcingaDbState +{ + /** @var BpConfig */ + protected $config; + + /** @var IcingaDbConnection */ + protected $backend; + + public function __construct(BpConfig $config) + { + $this->config = $config; + $this->backend = IcingaDbObject::fetchDb(); + } + + public static function apply(BpConfig $config) + { + $self = new static($config); + $self->retrieveStatesFromBackend(); + + return $config; + } + + public function retrieveStatesFromBackend() + { + $config = $this->config; + + try { + $this->reallyRetrieveStatesFromBackend(); + } catch (Exception $e) { + $config->addError( + $config->translate('Could not retrieve process state: %s'), + $e->getMessage() + ); + } + } + + public function reallyRetrieveStatesFromBackend() + { + $config = $this->config; + + Benchmark::measure(sprintf( + 'Retrieving states for business process %s using Icinga DB backend', + $config->getName() + )); + + $hosts = $config->listInvolvedHostNames(); + if (empty($hosts)) { + return $this; + } + + $queryHost = Host::on($this->backend)->with('state'); + IcingaDbObject::applyIcingaDbRestrictions($queryHost); + + $queryHost->filter(Filter::equal('host.name', $hosts)); + + $hostObject = $queryHost->getModel()->getTableName(); + + Benchmark::measure('Retrieved states for ' . $queryHost->count() . ' hosts in ' . $config->getName()); + + $queryService = Service::on($this->backend)->with([ + 'state', + 'host', + 'host.state' + ]); + + $queryService->filter(Filter::equal('host.name', $hosts)); + + IcingaDbObject::applyIcingaDbRestrictions($queryService); + + Benchmark::measure('Retrieved states for ' . $queryService->count() . ' services in ' . $config->getName()); + + $configs = $config->listInvolvedConfigs(); + + $serviceObject = $queryService->getModel()->getTableName(); + + foreach ($configs as $cfg) { + foreach ($queryService as $row) { + $this->handleDbRow($row, $cfg, $serviceObject); + } + foreach ($queryHost as $row) { + $this->handleDbRow($row, $cfg, $hostObject); + } + } + + Benchmark::measure('Got states for business process ' . $config->getName()); + + return $this; + } + + protected function handleDbRow($row, BpConfig $config, $objectName) + { + if ($objectName === 'service') { + $key = $row->host->name . ';' . $row->name; + } else { + $key = $row->name . ';Hoststatus'; + } + + // We fetch more states than we need, so skip unknown ones + if (! $config->hasNode($key)) { + return; + } + + $node = $config->getNode($key); + + if ($this->config->usesHardStates()) { + if ($row->state->hard_state !== null) { + $node->setState($row->state->hard_state)->setMissing(false); + } + } else { + if ($row->state->soft_state !== null) { + $node->setState($row->state->soft_state)->setMissing(false); + } + } + + if ($row->state->last_state_change !== null) { + $node->setLastStateChange($row->state->last_state_change/1000); + } + if ($row->state->in_downtime) { + $node->setDowntime(true); + } + if ($row->state->is_acknowledged) { + $node->setAck(true); + } + + $node->setAlias($row->display_name); + + if ($node instanceof ServiceNode) { + $node->setHostAlias($row->host->display_name); + } + } +} |