From e9dd69267cab2460c608f2dc67f42894dacfd3e2 Mon Sep 17 00:00:00 2001 From: Eric Lippmann Date: Tue, 26 May 2015 13:36:53 +0200 Subject: [PATCH] monitoring: Prepare HoststatusQuery to be used when viewing hosts The Hoststatusquery does not include the joins for last ack, comment and downtime as where unsure whether or not we will still support this. refs #7344 refs #9009 --- .../Backend/Ido/Query/HoststatusQuery.php | 375 +++++++----------- 1 file changed, 140 insertions(+), 235 deletions(-) diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php index ec9e6bd32..5095b401c 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/HoststatusQuery.php @@ -3,49 +3,86 @@ namespace Icinga\Module\Monitoring\Backend\Ido\Query; +use Zend_Db_Expr; + class HoststatusQuery extends IdoQuery { + /** + * {@inheritdoc} + */ protected $allowCustomVars = true; + /** + * {@inheritdoc} + */ protected $columnMap = array( 'hosts' => array( - 'host' => 'ho.name1 COLLATE latin1_general_ci', - 'host_name' => 'ho.name1 COLLATE latin1_general_ci', - 'host_display_name' => 'h.display_name COLLATE latin1_general_ci', - 'host_alias' => 'h.alias', - 'host_address' => 'h.address', - 'host_ipv4' => 'INET_ATON(h.address)', - 'host_icon_image' => 'h.icon_image', - 'object_type' => '(\'host\')' + 'host' => 'ho.name1 COLLATE latin1_general_ci', + 'host_action_url' => 'h.action_url', + 'host_address' => 'h.address', + 'host_alias' => 'h.alias', + 'host_display_name' => 'h.display_name COLLATE latin1_general_ci', + 'host_icon_image' => 'h.icon_image', + 'host_icon_image_alt' => 'h.icon_image_alt', + 'host_ipv4' => 'INET_ATON(h.address)', + 'host_name' => 'ho.name1', + 'host_notes_url' => 'h.notes_url', + 'object_type' => '(\'host\')' ), 'hoststatus' => array( - 'problems' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END', - 'handled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END', - 'unhandled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) = 0 THEN 1 ELSE 0 END', - 'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END', - 'host_output' => 'hs.output', - 'host_long_output' => 'hs.long_output', - 'host_perfdata' => 'hs.perfdata', - 'host_problem' => 'CASE WHEN hs.current_state = 0 THEN 0 ELSE 1 END', - 'host_acknowledged' => 'hs.problem_has_been_acknowledged', - 'host_in_downtime' => 'CASE WHEN (hs.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END', - 'host_handled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END', - 'host_does_active_checks' => 'hs.active_checks_enabled', - 'host_accepts_passive_checks' => 'hs.passive_checks_enabled', - 'host_last_state_change' => 'UNIX_TIMESTAMP(hs.last_state_change)', - 'host_last_hard_state' => 'hs.last_hard_state', - 'host_check_command' => 'hs.check_command', - 'host_last_check' => 'UNIX_TIMESTAMP(hs.last_check)', - 'host_next_check' => 'CASE WHEN hs.should_be_scheduled THEN UNIX_TIMESTAMP(hs.next_check) ELSE NULL END', - 'host_check_execution_time' => 'hs.execution_time', - 'host_check_latency' => 'hs.latency', - 'host_notifications_enabled' => 'hs.notifications_enabled', - 'host_last_time_up' => 'hs.last_time_up', - 'host_last_time_down' => 'hs.last_time_down', - 'host_last_time_unreachable' => 'hs.last_time_unreachable', - 'host_current_check_attempt' => 'hs.current_check_attempt', - 'host_max_check_attempts' => 'hs.max_check_attempts', - 'host_severity' => 'CASE WHEN hs.current_state = 0 + 'host_acknowledged' => 'hs.problem_has_been_acknowledged', + 'host_acknowledgement_type' => 'hs.acknowledgement_type', + 'host_active_checks_enabled' => 'hs.active_checks_enabled', + 'host_active_checks_enabled_changed' => 'CASE WHEN hs.active_checks_enabled = h.active_checks_enabled THEN 0 ELSE 1 END', + 'host_attempt' => 'hs.current_check_attempt || \'/\' || hs.max_check_attempts', + 'host_check_command' => 'hs.check_command', + 'host_check_execution_time' => 'hs.execution_time', + 'host_check_latency' => 'hs.latency', + 'host_check_source' => 'hs.check_source', + 'host_check_type' => 'hs.check_type', + 'host_current_check_attempt' => 'hs.current_check_attempt', + 'host_current_notification_number' => 'hs.current_notification_number', + 'host_event_handler' => 'hs.event_handler', + 'host_event_handler_enabled' => 'hs.event_handler_enabled', + 'host_event_handler_enabled_changed' => 'CASE WHEN hs.event_handler_enabled = h.event_handler_enabled THEN 0 ELSE 1 END', + 'host_failure_prediction_enabled' => 'hs.failure_prediction_enabled', + 'host_flap_detection_enabled' => 'hs.flap_detection_enabled', + 'host_flap_detection_enabled_changed' => 'CASE WHEN hs.flap_detection_enabled = h.flap_detection_enabled THEN 0 ELSE 1 END', + 'host_handled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) > 0 THEN 1 ELSE 0 END', + 'host_hard_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_in_downtime' => 'CASE WHEN (hs.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END', + 'host_is_flapping' => 'hs.is_flapping', + 'host_is_reachable' => 'hs.is_reachable', + 'host_last_check' => 'UNIX_TIMESTAMP(hs.last_check)', + 'host_last_hard_state' => 'hs.last_hard_state', + 'host_last_hard_state_change' => 'UNIX_TIMESTAMP(hs.last_hard_state_change)', + 'host_last_notification' => 'UNIX_TIMESTAMP(hs.last_notification)', + 'host_last_state_change' => 'UNIX_TIMESTAMP(hs.last_state_change)', + 'host_last_time_down' => 'UNIX_TIMESTAMP(hs.last_time_down)', + 'host_last_time_unreachable' => 'UNIX_TIMESTAMP(hs.last_time_unreachable)', + 'host_last_time_up' => 'UNIX_TIMESTAMP(hs.last_time_up)', + 'host_long_output' => 'hs.long_output', + 'host_max_check_attempts' => 'hs.max_check_attempts', + 'host_modified_host_attributes' => 'hs.modified_host_attributes', + 'host_next_check' => 'CASE hs.should_be_scheduled WHEN 1 THEN UNIX_TIMESTAMP(hs.next_check) ELSE NULL END', + 'host_next_notification' => 'UNIX_TIMESTAMP(hs.next_notification)', + 'host_no_more_notifications' => 'hs.no_more_notifications', + 'host_normal_check_interval' => 'hs.normal_check_interval', + 'host_notifications_enabled' => 'hs.notifications_enabled', + 'host_notifications_enabled_changed' => 'CASE WHEN hs.notifications_enabled = h.notifications_enabled THEN 0 ELSE 1 END', + 'host_obsessing' => 'hs.obsess_over_host', + 'host_obsessing_changed' => 'CASE WHEN hs.obsess_over_host = h.obsess_over_host THEN 0 ELSE 1 END', + 'host_output' => 'hs.output', + 'host_passive_checks_enabled' => 'hs.passive_checks_enabled', + 'host_passive_checks_enabled_changed' => 'CASE WHEN hs.passive_checks_enabled = h.passive_checks_enabled THEN 0 ELSE 1 END', + 'host_percent_state_change' => 'hs.percent_state_change', + 'host_perfdata' => 'hs.perfdata', + 'host_problem' => 'CASE WHEN COALESCE(hs.current_state, 0) = 0 THEN 0 ELSE 1 END', + 'host_problem_has_been_acknowledged' => 'hs.problem_has_been_acknowledged', + 'host_process_performance_data' => 'hs.process_performance_data', + 'host_retry_check_interval' => 'hs.retry_check_interval', + 'host_scheduled_downtime_depth' => 'hs.scheduled_downtime_depth', + 'host_severity' => 'CASE WHEN hs.current_state = 0 THEN CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 16 @@ -80,245 +117,113 @@ class HoststatusQuery extends IdoQuery CASE WHEN hs.state_type = 1 THEN 8 ELSE 0 - END' + END', + 'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END', + 'host_state_type' => 'hs.state_type', + 'host_status_update_time' => 'hs.status_update_time', + 'host_unhandled' => 'CASE WHEN (hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth) = 0 THEN 1 ELSE 0 END' ), 'hostgroups' => array( 'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci', - 'hostgroup_name' => 'hgo.name1', - 'hostgroup_alias' => 'hg.alias COLLATE latin1_general_ci' - ), - 'servicegroups' => array( - 'servicegroup' => 'sgo.name1 COLLATE latin1_general_ci', - 'servicegroup_name' => 'sgo.name1', - 'servicegroup_alias' => 'sg.alias' - ), - 'contactgroups' => array( - 'contactgroup' => 'contactgroup', - ), - 'contacts' => array( - 'contact' => 'hco.name1 COLLATE latin1_general_ci', - ), - 'services' => array( - 'services_cnt' => 'SUM(1)', - 'services_ok' => 'SUM(CASE WHEN ss.current_state = 0 THEN 1 ELSE 0 END)', - 'services_warning' => 'SUM(CASE WHEN ss.current_state = 1 THEN 1 ELSE 0 END)', - 'services_critical' => 'SUM(CASE WHEN ss.current_state = 2 THEN 1 ELSE 0 END)', - 'services_unknown' => 'SUM(CASE WHEN ss.current_state = 3 THEN 1 ELSE 0 END)', - 'services_pending' => 'SUM(CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 1 ELSE 0 END)', - 'services_problem' => 'SUM(CASE WHEN ss.current_state > 0 THEN 1 ELSE 0 END)', - 'services_problem_handled' => 'SUM(CASE WHEN ss.current_state > 0 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)', - 'services_problem_unhandled' => 'SUM(CASE WHEN ss.current_state > 0 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)', - 'services_warning_handled' => 'SUM(CASE WHEN ss.current_state = 1 AND (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) > 0 THEN 1 ELSE 0 END)', - 'services_critical_handled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) > 0 THEN 1 ELSE 0 END)', - 'services_unknown_handled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) > 0 THEN 1 ELSE 0 END)', - 'services_warning_unhandled' => 'SUM(CASE WHEN ss.current_state = 1 AND (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) = 0 THEN 1 ELSE 0 END)', - 'services_critical_unhandled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) = 0 THEN 1 ELSE 0 END)', - 'services_unknown_unhandled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) = 0 THEN 1 ELSE 0 END)', + 'hostgroup_alias' => 'hg.alias COLLATE latin1_general_ci', + 'hostgroup_name' => 'hgo.name1' ), + 'serviceproblemsummary' => array( + 'host_unhandled_services' => 'sps.unhandled_services_count' + ) ); - protected $aggregateColumnIdx = array( - 'services_cnt' => true, - 'services_problem' => true, - 'services_problem_handled' => true, - 'services_problem_unhandled' => true, - ); - - protected $hcgSub; - - public function getDefaultColumns() - { - return $this->columnMap['hosts'] + $this->columnMap['hoststatus']; - } - + /** + * {@inheritdoc} + */ protected function joinBaseTables() { - // TODO: Shall we always add hostobject? $this->select->from( array('ho' => $this->prefix . 'objects'), array() - )->join( - array('hs' => $this->prefix . 'hoststatus'), - 'ho.' . $this->object_id . ' = hs.host_object_id AND ho.is_active = 1 AND ho.objecttype_id = 1', - array() )->join( array('h' => $this->prefix . 'hosts'), - 'hs.host_object_id = h.host_object_id', + 'h.host_object_id = ho.object_id AND ho.is_active = 1 AND ho.objecttype_id = 1', array() ); - $this->joinedVirtualTables = array( - 'hosts' => true, - 'hoststatus' => true, - ); + $this->joinedVirtualTables['hosts'] = true; } - protected function joinStatus() - { - $this->requireVirtualTable('services'); - } - - protected function joinServiceStatus() - { - $this->requireVirtualTable('services'); - } - - protected function joinServices() + /** + * Join host status + * + * @return $this + */ + protected function joinHoststatus() { $this->select->join( - array('s' => $this->prefix . 'services'), - 's.host_object_id = h.host_object_id', - array() - )->join( - array('so' => $this->prefix . 'objects'), - 'so.' . $this->object_id . ' = s.service_object_id AND so.is_active = 1', - array() - )->joinLeft( - array('ss' => $this->prefix . 'servicestatus'), - 'so.' . $this->object_id . ' = ss.service_object_id', + array('hs' => $this->prefix . 'hoststatus'), + 'hs.host_object_id = ho.object_id', array() ); - foreach ($this->getColumns() as $col) { - $real = $this->aliasToColumnName($col); - if (substr($real, 0, 4) === 'SUM(') { - continue; - } - $this->select->group($real); - } - $this->useSubqueryCount = true; + return $this; } + /** + * Join host groups + * + * @return $this + */ protected function joinHostgroups() - { - if ($this->hasJoinedVirtualTable('services')) { - return $this->joinServiceHostgroups(); - } else { - return $this->joinHostHostgroups(); - } - } - - protected function joinServiceHostgroups() { $this->select->join( array('hgm' => $this->prefix . 'hostgroup_members'), - 'hgm.host_object_id = s.host_object_id', + 'hgm.host_object_id = ho.object_id', array() )->join( array('hg' => $this->prefix . 'hostgroups'), - 'hgm.hostgroup_id = hg.' . $this->hostgroup_id, + 'hg.hostgroup_id = hgm.hostgroup_id', array() )->join( array('hgo' => $this->prefix . 'objects'), - 'hgo.' . $this->object_id . ' = hg.hostgroup_object_id' - . ' AND hgo.is_active = 1', + 'hgo.object_id = hg.hostgroup_object_id AND hgo.is_active = 1 AND hgo.objecttype_id = 3', array() ); return $this; } - protected function joinHostHostgroups() + /** + * Join service problem summary + * + * @return $this + */ + protected function joinServiceproblemsummary() { - $this->select->join( - array('hgm' => $this->prefix . 'hostgroup_members'), - 'hgm.host_object_id = h.host_object_id', - array() - )->join( - array('hg' => $this->prefix . 'hostgroups'), - 'hgm.hostgroup_id = hg.' . $this->hostgroup_id, - array() - )->join( - array('hgo' => $this->prefix . 'objects'), - 'hgo.' . $this->object_id . ' = hg.hostgroup_object_id' . ' AND hgo.is_active = 1', - array() - ); - return $this; - } - - protected function joinContacts() - { - $this->hcgcSub = $this->db->select()->distinct()->from( - array('hcgc' => $this->prefix . 'host_contactgroups'), - array('host_name' => 'ho.name1') - )->join( - array('cgo' => $this->prefix . 'objects'), - 'hcg.contactgroup_object_id = cgo.' . $this->object_id . ' AND cgo.is_active = 1', - array() - )->join( - array('h' => $this->prefix . 'hosts'), - 'hcg.host_id = h.host_id', - array() - )->join( - array('ho' => $this->prefix . 'objects'), - 'h.host_object_id = ho.' . $this->object_id . ' AND ho.is_active = 1', - array() - ); - $this->select->join( - array('hcg' => $this->hcgSub), - 'hcg.host_name = ho.name1', - array() - ); - - return $this; - } - - protected function filterContactgroup($value) - { - $this->hcgSub->where( - $this->prepareFilterStringForColumn( - 'cgo.name1 COLLATE latin1_general_ci', - $value - ) - ); - return $this; - } - - protected function joinContactgroups() - { - $this->hcgSub = $this->createContactgroupFilterSubselect(); - $this->select->join( - array('hcg' => $this->hcgSub), - 'hcg.object_id = ho.object_id', - array() - ); - return $this; - } - - protected function createContactgroupFilterSubselect() - { - die((string) $this->db->select()->distinct()->from( - array('hcg' => $this->prefix . 'host_contactgroups'), - array('object_id' => 'ho.object_id') - )->join( - array('cgo' => $this->prefix . 'objects'), - 'hcg.contactgroup_object_id = cgo.' . $this->object_id - . ' AND cgo.is_active = 1', - array() - )->join( - array('h' => $this->prefix . 'hosts'), - 'hcg.host_id = h.host_id', - array() - )->join( - array('ho' => $this->prefix . 'objects'), - 'h.host_object_id = ho.' . $this->object_id . ' AND ho.is_active = 1', - array() - )); - } - - protected function joinServicegroups() - { - // TODO: Only hosts with services having such servicegroups - $this->requireVirtualTable('services'); - $this->select->join( - array('sgm' => $this->prefix . 'servicegroup_members'), - 'sgm.service_object_id = s.service_object_id', - array() - )->join( - array('sg' => $this->prefix . 'servicegroups'), - 'sgm.servicegroup_id = sg.' . $this->servicegroup_id, - array() - )->join( - array('sgo' => $this->prefix . 'objects'), - 'sgo.' . $this->object_id . ' = sg.servicegroup_object_id' - . ' AND sgo.is_active = 1', + $select = <<<'SQL' +SELECT + SUM( + CASE WHEN(ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0)) > 0 + THEN 0 + ELSE 1 + END + ) AS unhandled_services_count, + SUM( + CASE WHEN (ss.problem_has_been_acknowledged + ss.scheduled_downtime_depth + COALESCE(hs.current_state, 0) ) > 0 + THEN 1 + ELSE 0 + END + ) AS handled_services_count, + s.host_object_id +FROM + icinga_servicestatus ss + JOIN icinga_objects o ON o.object_id = ss.service_object_id + JOIN icinga_services s ON s.service_object_id = o.object_id + JOIN icinga_hoststatus hs ON hs.host_object_id = s.host_object_id +WHERE + o.is_active = 1 + AND o.objecttype_id = 2 + AND ss.current_state > 0 +GROUP BY + s.host_object_id +SQL; + $this->select->joinLeft( + array('sps' => new Zend_Db_Expr('(' . $select . ')')), + 'sps.host_object_id = ho.object_id', array() ); return $this;