summaryrefslogtreecommitdiffstats
path: root/library/Toplevelview/Monitoring
diff options
context:
space:
mode:
Diffstat (limited to 'library/Toplevelview/Monitoring')
-rw-r--r--library/Toplevelview/Monitoring/HostgroupQuery.php132
-rw-r--r--library/Toplevelview/Monitoring/Hostgroupsummary.php33
-rw-r--r--library/Toplevelview/Monitoring/HostgroupsummaryQuery.php157
-rw-r--r--library/Toplevelview/Monitoring/IgnoredNotificationPeriods.php49
-rw-r--r--library/Toplevelview/Monitoring/Options.php33
-rw-r--r--library/Toplevelview/Monitoring/Servicestatus.php38
-rw-r--r--library/Toplevelview/Monitoring/ServicestatusQuery.php87
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())
+ ',
+ []
+ );
+ }
+}