diff options
Diffstat (limited to 'library/Toplevelview/Monitoring')
-rw-r--r-- | library/Toplevelview/Monitoring/HostgroupQuery.php | 132 | ||||
-rw-r--r-- | library/Toplevelview/Monitoring/Hostgroupsummary.php | 33 | ||||
-rw-r--r-- | library/Toplevelview/Monitoring/HostgroupsummaryQuery.php | 157 | ||||
-rw-r--r-- | library/Toplevelview/Monitoring/IgnoredNotificationPeriods.php | 49 | ||||
-rw-r--r-- | library/Toplevelview/Monitoring/Options.php | 33 | ||||
-rw-r--r-- | library/Toplevelview/Monitoring/Servicestatus.php | 38 | ||||
-rw-r--r-- | library/Toplevelview/Monitoring/ServicestatusQuery.php | 87 |
7 files changed, 529 insertions, 0 deletions
diff --git a/library/Toplevelview/Monitoring/HostgroupQuery.php b/library/Toplevelview/Monitoring/HostgroupQuery.php new file mode 100644 index 0000000..62cc014 --- /dev/null +++ b/library/Toplevelview/Monitoring/HostgroupQuery.php @@ -0,0 +1,132 @@ +<?php +/* Copyright (C) 2017 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Monitoring; + +use Icinga\Module\Monitoring\Backend\Ido\Query\HostgroupQuery as IcingaHostgroupQuery; + +/** + * Patched version of HostgroupQuery + */ +class HostgroupQuery extends IcingaHostgroupQuery +{ + use IgnoredNotificationPeriods; + use Options; + + public function __construct($ds, $columns = null, $options = null) + { + $this->setOptions($options); + parent::__construct($ds, $columns); + } + + public function init() + { + if (($periods = $this->getOption('ignored_notification_periods')) !== null) { + $this->ignoreNotificationPeriods($periods); + } + + $patchedColumnMap = array( + 'servicestatus' => array( + 'service_notifications_enabled' => 'ss.notifications_enabled', + 'service_is_flapping' => 'ss.is_flapping', + 'service_state' => ' + CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL + THEN 99 + ELSE CASE WHEN ss.state_type = 1 + THEN ss.current_state + ELSE ss.last_hard_state + END + END', + 'service_handled' => ' + CASE WHEN (ss.problem_has_been_acknowledged + COALESCE(hs.current_state, 0)) > 0 + THEN 1 + ELSE 0 + END', + 'service_handled_wo_host' => ' + CASE WHEN ss.problem_has_been_acknowledged > 0 + THEN 1 + ELSE 0 + END', + 'service_in_downtime' => ' + CASE WHEN (ss.scheduled_downtime_depth = 0) + THEN 0 + ELSE 1 + END', + ), + 'hoststatus' => array( + 'host_notifications_enabled' => 'hs.notifications_enabled', + 'host_is_flapping' => 'hs.is_flapping', + 'host_state' => ' + CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL + THEN 99 + ELSE CASE WHEN hs.state_type = 1 + THEN hs.current_state + ELSE hs.last_hard_state + END + END', + 'host_handled' => ' + CASE WHEN hs.problem_has_been_acknowledged > 0 + THEN 1 + ELSE 0 + END', + 'host_in_downtime' => ' + CASE WHEN (hs.scheduled_downtime_depth = 0) + THEN 0 + ELSE 1 + END', + ), + 'servicenotificationperiod' => array( + 'service_notification_period' => 'ntpo.name1', + 'service_in_notification_period' => ' + CASE WHEN ntpo.object_id IS NULL + THEN 1 + ELSE CASE WHEN ntpr.timeperiod_id IS NOT NULL + THEN 1 + ELSE 0 + END + END', + ), + ); + + foreach ($patchedColumnMap as $table => $columns) { + foreach ($columns as $k => $v) { + $this->columnMap[$table][$k] = $v; + } + } + + parent::init(); + } + + protected function joinServicenotificationperiod() + { + $extraJoinCond = ''; + + if ($this->hasIgnoredNotifications()) { + $extraJoinCond .= $this->db->quoteInto( + ' AND ntpo.name1 NOT IN (?)', + $this->getIgnoredNotificationPeriods() + ); + } + + $this->select->joinLeft( + ['ntp' => $this->prefix . 'timeperiods'], + 'ntp.timeperiod_object_id = s.notification_timeperiod_object_id' + . ' AND ntp.config_type = 1 AND ntp.instance_id = s.instance_id', + [] + ); + $this->select->joinLeft( + ['ntpo' => $this->prefix . 'objects'], + 'ntpo.object_id = s.notification_timeperiod_object_id' . $extraJoinCond, + [] + ); + $this->select->joinLeft( + ['ntpr' => $this->prefix . 'timeperiod_timeranges'], + "ntpr.timeperiod_id = ntp.timeperiod_id + AND ntpr.day = DAYOFWEEK(CURRENT_DATE()) - 1 + AND ntpr.start_sec <= UNIX_TIMESTAMP() - UNIX_TIMESTAMP(CURRENT_DATE()) + AND ntpr.end_sec >= UNIX_TIMESTAMP() - UNIX_TIMESTAMP(CURRENT_DATE()) + ", + [] + ); + } +} diff --git a/library/Toplevelview/Monitoring/Hostgroupsummary.php b/library/Toplevelview/Monitoring/Hostgroupsummary.php new file mode 100644 index 0000000..c89f09c --- /dev/null +++ b/library/Toplevelview/Monitoring/Hostgroupsummary.php @@ -0,0 +1,33 @@ +<?php +/* Copyright (C) 2017 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Monitoring; + +use Icinga\Data\ConnectionInterface; +use Icinga\Module\Monitoring\Backend\MonitoringBackend; +use Icinga\Module\Monitoring\DataView\Hostgroupsummary as IcingaHostgroupsummary; + +/** + * Patched version of Hostgroupsummary + * + * Just to load a patched version of HostgroupsummaryQuery + */ +class Hostgroupsummary extends IcingaHostgroupsummary +{ + /** @noinspection PhpMissingParentConstructorInspection */ + /** + * @param ConnectionInterface $connection + * @param array|null $columns + * @param array|null $options + * @noinspection PhpMissingParentConstructorInspection + */ + public function __construct( + ConnectionInterface $connection, + array $columns = null, + $options = null + ) { + /** @var MonitoringBackend $connection */ + $this->connection = $connection; + $this->query = new HostgroupsummaryQuery($connection->getResource(), $columns, $options); + } +} diff --git a/library/Toplevelview/Monitoring/HostgroupsummaryQuery.php b/library/Toplevelview/Monitoring/HostgroupsummaryQuery.php new file mode 100644 index 0000000..5390613 --- /dev/null +++ b/library/Toplevelview/Monitoring/HostgroupsummaryQuery.php @@ -0,0 +1,157 @@ +<?php +/* Copyright (C) 2017 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Monitoring; + +use Icinga\Data\Filter\Filter; +use Icinga\Module\Monitoring\Backend\Ido\Query\HostgroupsummaryQuery as IcingaHostgroupsummaryQuery; +use Zend_Db_Expr; +use Zend_Db_Select; + +/** + * Patched version of HostgroupsummaryQuery + */ +class HostgroupsummaryQuery extends IcingaHostgroupsummaryQuery +{ + use Options; + + public function __construct($ds, $columns = null, $options = null) + { + $this->setOptions($options); + parent::__construct($ds, $columns); + } + + public function init() + { + if ($this->getOption('notification_periods') === true) { + $serviceOutDowntime =# + 'service_notifications_enabled = 1 AND service_in_downtime = 0 AND service_in_notification_period = 1'; + $serviceInDowntime = + '(service_notifications_enabled = 0 OR service_in_downtime = 1 OR service_in_notification_period = 0)'; + } else { + $serviceOutDowntime = 'service_notifications_enabled = 1 AND service_in_downtime = 0'; + $serviceInDowntime = '(service_notifications_enabled = 0 OR service_in_downtime = 1)'; + } + + $hostOutDowntime = 'host_notifications_enabled = 1 AND host_in_downtime = 0'; + $hostInDowntime = '(host_notifications_enabled = 0 OR host_in_downtime = 1)'; + + if ($this->getOption('host_never_unhandled') === true) { + $patchServicesHandled = "(service_handled_wo_host = 1 OR service_is_flapping = 1) AND $serviceOutDowntime"; + $patchServicesUnhandled = "service_handled_wo_host = 0 AND service_is_flapping = 0 AND $serviceOutDowntime"; + } else { + $patchServicesHandled = "(service_handled = 1 OR service_is_flapping = 1) AND $serviceOutDowntime"; + $patchServicesUnhandled = "service_handled = 0 AND service_is_flapping = 0 AND $serviceOutDowntime"; + } + + $patchHostsHandled = "(host_handled = 1 OR host_is_flapping = 1) AND $hostOutDowntime"; + $patchHostsUnhandled = "host_handled = 0 AND host_is_flapping = 0 AND $hostOutDowntime"; + + $patchedColumnMap = array( + 'hostgroupsummary' => array( + 'hosts_down_handled' => + "SUM(CASE WHEN host_state = 1 AND $patchHostsHandled THEN 1 ELSE 0 END)", + 'hosts_down_unhandled' => + "SUM(CASE WHEN host_state = 1 AND $patchHostsUnhandled THEN 1 ELSE 0 END)", + 'hosts_unreachable_handled' => + "SUM(CASE WHEN host_state = 2 AND $patchHostsHandled THEN 1 ELSE 0 END)", + 'hosts_unreachable_unhandled' => + "SUM(CASE WHEN host_state = 2 AND $patchHostsUnhandled THEN 1 ELSE 0 END)", + 'hosts_downtime_handled' => + "SUM(CASE WHEN host_state != 0 AND $hostInDowntime THEN 1 ELSE 0 END)", + 'hosts_downtime_active' => + "SUM(CASE WHEN $hostInDowntime THEN 1 ELSE 0 END)", + 'services_critical_handled' => + "SUM(CASE WHEN service_state = 2 AND $patchServicesHandled THEN 1 ELSE 0 END)", + 'services_critical_unhandled' => + "SUM(CASE WHEN service_state = 2 AND $patchServicesUnhandled THEN 1 ELSE 0 END)", + 'services_unknown_handled' => + "SUM(CASE WHEN service_state = 3 AND $patchServicesHandled THEN 1 ELSE 0 END)", + 'services_unknown_unhandled' => + "SUM(CASE WHEN service_state = 3 AND $patchServicesUnhandled THEN 1 ELSE 0 END)", + 'services_warning_handled' => + "SUM(CASE WHEN service_state = 1 AND $patchServicesHandled THEN 1 ELSE 0 END)", + 'services_warning_unhandled' => + "SUM(CASE WHEN service_state = 1 AND $patchServicesUnhandled THEN 1 ELSE 0 END)", + 'services_downtime_handled' => + "SUM(CASE WHEN service_state != 0 AND $serviceInDowntime THEN 1 ELSE 0 END)", + 'services_downtime_active' => + "SUM(CASE WHEN $serviceInDowntime THEN 1 ELSE 0 END)", + ) + ); + + foreach ($patchedColumnMap as $table => $columns) { + foreach ($columns as $k => $v) { + $this->columnMap[$table][$k] = $v; + } + } + parent::init(); + } + + protected function createSubQuery($queryName, $columns = array()) + { + if ($queryName === 'Hostgroup') { + // use locally patched query + return new HostgroupQuery($this->ds, $columns, $this->options); + } else { + return parent::createSubQuery($queryName, $columns); + } + } + + protected function joinBaseTables() + { + $this->countQuery = $this->createSubQuery( + 'Hostgroup', + array() + ); + $hostColumns = array( + 'hostgroup_alias', + 'hostgroup_name', + 'host_handled', + 'host_notifications_enabled', + 'host_state', + 'host_is_flapping', + 'host_in_downtime', + 'service_handled' => new Zend_Db_Expr('NULL'), + 'service_handled_wo_host' => new Zend_Db_Expr('NULL'), + 'service_state' => new Zend_Db_Expr('NULL'), + 'service_notifications_enabled' => new Zend_Db_Expr('NULL'), + 'service_is_flapping' => new Zend_Db_Expr('NULL'), + 'service_in_downtime' => new Zend_Db_Expr('NULL'), + ); + + $serviceColumns = array( + 'hostgroup_alias', + 'hostgroup_name', + 'host_handled' => new Zend_Db_Expr('NULL'), + 'host_state' => new Zend_Db_Expr('NULL'), + 'host_notifications_enabled' => new Zend_Db_Expr('NULL'), + 'host_is_flapping' => new Zend_Db_Expr('NULL'), + 'host_in_downtime' => new Zend_Db_Expr('NULL'), + 'service_handled', + 'service_handled_wo_host', + 'service_state', + 'service_notifications_enabled', + 'service_is_flapping', + 'service_in_downtime', + ); + + if ($this->getOption('notification_periods') === true) { + $hostColumns['service_in_notification_period'] = new Zend_Db_Expr('NULL'); + $serviceColumns['service_in_notification_period'] = 'service_in_notification_period'; + } + + $hosts = $this->createSubQuery('Hostgroup', $hostColumns); + // ignore empty hostgroups in this subquery + $hosts->setFilter(Filter::expression('ho.object_id', '>', 0)); + $this->subQueries[] = $hosts; + $services = $this->createSubQuery('Hostgroup', $serviceColumns); + // ignore empty hostgroups in this subquery + $services->setFilter(Filter::expression('ho.object_id', '>', 0)); + $this->subQueries[] = $services; + $this->summaryQuery = $this->db->select()->union(array($hosts, $services), Zend_Db_Select::SQL_UNION_ALL); + $this->select->from(array('hostgroupsummary' => $this->summaryQuery), array()); + $this->group(array('hostgroup_name', 'hostgroup_alias')); + $this->joinedVirtualTables['hostgroupsummary'] = true; + } +} diff --git a/library/Toplevelview/Monitoring/IgnoredNotificationPeriods.php b/library/Toplevelview/Monitoring/IgnoredNotificationPeriods.php new file mode 100644 index 0000000..4b9e94c --- /dev/null +++ b/library/Toplevelview/Monitoring/IgnoredNotificationPeriods.php @@ -0,0 +1,49 @@ +<?php +/* Copyright (C) 2019 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Monitoring; + +trait IgnoredNotificationPeriods +{ + protected $ignoredNotificationPeriods = []; + + public function ignoreNotificationPeriod($name) + { + $this->ignoredNotificationPeriods[$name] = true; + return $this; + } + + /** + * @param string|array|iterable $list + * + * @return $this + */ + public function ignoreNotificationPeriods($list) + { + if (is_string($list)) { + /** @var string $list */ + $this->ignoredNotificationPeriods[$list] = true; + } else { + foreach ($list as $i) { + $this->ignoredNotificationPeriods[$i] = true; + } + } + + return $this; + } + + public function getIgnoredNotificationPeriods() + { + return array_keys($this->ignoredNotificationPeriods); + } + + public function resetIgnoredNotificationPeriods() + { + $this->ignoredNotificationPeriods = []; + } + + public function hasIgnoredNotifications() + { + return ! empty($this->ignoredNotificationPeriods); + } +} diff --git a/library/Toplevelview/Monitoring/Options.php b/library/Toplevelview/Monitoring/Options.php new file mode 100644 index 0000000..75f739f --- /dev/null +++ b/library/Toplevelview/Monitoring/Options.php @@ -0,0 +1,33 @@ +<?php +/* Copyright (C) 2019 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Monitoring; + +trait Options +{ + protected $options = []; + + public function getOption($key) + { + if (array_key_exists($key, $this->options)) { + return $this->options[$key]; + } + + return null; + } + + public function setOptions($options, $flush = false) + { + if ($flush) { + $this->options = []; + } + + if (! empty($options)) { + foreach ($options as $k => $v) { + $this->options[$k] = $v; + } + } + + return $this; + } +} diff --git a/library/Toplevelview/Monitoring/Servicestatus.php b/library/Toplevelview/Monitoring/Servicestatus.php new file mode 100644 index 0000000..e43572f --- /dev/null +++ b/library/Toplevelview/Monitoring/Servicestatus.php @@ -0,0 +1,38 @@ +<?php +/* Copyright (C) 2017 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Monitoring; + +use Icinga\Data\ConnectionInterface; +use Icinga\Module\Monitoring\Backend\MonitoringBackend; +use Icinga\Module\Monitoring\DataView\Servicestatus as IcingaServiceStatus; + +class Servicestatus extends IcingaServiceStatus +{ + /** @noinspection PhpMissingParentConstructorInspection */ + /** + * @param ConnectionInterface $connection + * @param array|null $columns + * @noinspection PhpMissingParentConstructorInspection + */ + public function __construct(ConnectionInterface $connection, array $columns = null, $options = null) + { + /** @var MonitoringBackend $connection */ + $this->connection = $connection; + $this->query = new ServicestatusQuery($connection->getResource(), $columns, $options); + } + + /** + * {@inheritdoc} + */ + public function getColumns() + { + return array_merge( + parent::getColumns(), + array( + //'service_in_notification_period', + 'service_notification_period', + ) + ); + } +} diff --git a/library/Toplevelview/Monitoring/ServicestatusQuery.php b/library/Toplevelview/Monitoring/ServicestatusQuery.php new file mode 100644 index 0000000..addee2f --- /dev/null +++ b/library/Toplevelview/Monitoring/ServicestatusQuery.php @@ -0,0 +1,87 @@ +<?php +/* Copyright (C) 2017 Icinga Development Team <info@icinga.com> */ + +namespace Icinga\Module\Toplevelview\Monitoring; + +use Icinga\Module\Monitoring\Backend\Ido\Query\ServicestatusQuery as IcingaServicestatusQuery; + +/** + * Patched version of ServicestatusQuery + */ +class ServicestatusQuery extends IcingaServicestatusQuery +{ + use IgnoredNotificationPeriods; + use Options; + + public function __construct($ds, $columns = null, $options = null) + { + $this->setOptions($options); + parent::__construct($ds, $columns); + } + + public function init() + { + if (($periods = $this->getOption('ignored_notification_periods')) !== null) { + $this->ignoreNotificationPeriods($periods); + } + + $patchedColumnMap = array( + 'servicestatus' => array( + 'service_handled_wo_host' => 'CASE WHEN ss.problem_has_been_acknowledged > 0 THEN 1 ELSE 0 END', + ), + 'servicenotificationperiod' => array( + 'service_notification_period' => 'ntpo.name1', + 'service_in_notification_period' => ' + CASE WHEN ntpo.name1 IS NULL + THEN 1 + ELSE CASE WHEN ntpr.timeperiod_id IS NOT NULL + THEN 1 + ELSE 0 + END + END', + ), + ); + + foreach ($patchedColumnMap as $table => $columns) { + foreach ($columns as $k => $v) { + $this->columnMap[$table][$k] = $v; + } + } + + parent::init(); + } + + protected function joinServicenotificationperiod() + { + $extraJoinCond = ''; + + if ($this->hasIgnoredNotifications()) { + $extraJoinCond .= $this->db->quoteInto( + ' AND ntpo.name1 NOT IN (?)', + $this->getIgnoredNotificationPeriods() + ); + } + + $this->select->joinLeft( + ["ntp" => $this->prefix . 'timeperiods'], + 'ntp.timeperiod_object_id = s.notification_timeperiod_object_id' + . ' AND ntp.config_type = 1 AND ntp.instance_id = s.instance_id', + [] + ); + $this->select->joinLeft( + ['ntpo' => $this->prefix . 'objects'], + 'ntpo.object_id = s.notification_timeperiod_object_id' + . $extraJoinCond, + [] + ); + $this->select->joinLeft( + ['ntpr' => $this->prefix . 'timeperiod_timeranges'], + 'ntpr.timeperiod_id = ntp.timeperiod_id + AND ntpr.day = DAYOFWEEK(CURRENT_DATE()) - 1 + AND ntpr.start_sec < UNIX_TIMESTAMP() - UNIX_TIMESTAMP(CURRENT_DATE()) + AND ntpr.end_sec > UNIX_TIMESTAMP() - UNIX_TIMESTAMP(CURRENT_DATE()) + ', + [] + ); + } +} |