From 0e0672e0c12c622f73562be768ecaa7bc968927e Mon Sep 17 00:00:00 2001 From: Alexander Klimov <Alexander.Klimov@netways.de> Date: Wed, 5 Feb 2014 17:23:51 +0100 Subject: [PATCH] Add tactical overview (WIP) refs #3782 --- .../controllers/TacticalController.php | 17 +++ .../views/scripts/tactical/index.phtml | 120 ++++++++++++++++++ .../Backend/Ido/Query/StatusSummaryQuery.php | 61 ++++++--- .../Monitoring/DataView/StatusSummary.php | 60 ++++++++- modules/monitoring/public/css/main.less | 75 +++++++++++ 5 files changed, 315 insertions(+), 18 deletions(-) create mode 100644 modules/monitoring/application/controllers/TacticalController.php create mode 100644 modules/monitoring/application/views/scripts/tactical/index.phtml diff --git a/modules/monitoring/application/controllers/TacticalController.php b/modules/monitoring/application/controllers/TacticalController.php new file mode 100644 index 000000000..2b434bb2f --- /dev/null +++ b/modules/monitoring/application/controllers/TacticalController.php @@ -0,0 +1,17 @@ +<?php +// @codingStandardsIgnoreStart +// {{{ICINGA_LICENSE_HEADER}}} +// {{{ICINGA_LICENSE_HEADER}}} + +use Icinga\Module\Monitoring\Controller as MonitoringController; +use Icinga\Module\Monitoring\DataView\StatusSummary; +use Icinga\Chart\PieChart; + +class Monitoring_TacticalController extends MonitoringController +{ + public function indexAction() + { + $this->view->statusSummary = StatusSummary::fromRequest($this->_request)->getQuery()->fetchRow(); + } +} +// @codingStandardsIgnoreStop \ No newline at end of file diff --git a/modules/monitoring/application/views/scripts/tactical/index.phtml b/modules/monitoring/application/views/scripts/tactical/index.phtml new file mode 100644 index 000000000..4c0d61600 --- /dev/null +++ b/modules/monitoring/application/views/scripts/tactical/index.phtml @@ -0,0 +1,120 @@ +<?php +$summary = $this->statusSummary; +$state = array( + 'host' => array( + 'up' => 0, + 'down' => 1, + 'unreachable' => 2, + 'pending' => 99 + ), + 'service' => array( + 'ok' => 0, + 'warning' => 1, + 'critical' => 2, + 'unknown' => 3, + 'pending' => 99 + ) +); +function init_upper($string) { + return mb_strtoupper(substr($string, 0, 1)) . substr($string, 1); +} +$tacticalTables = array(); +foreach (array( + 'host' => array('up', 'down', 'unreachable', 'pending'), + 'service' => array('ok', 'critical', 'warning', 'unknown', 'pending') +) as $key => $value) { + $tacticalTables[$key] = array(); + foreach ($value as $valueState) { + $tacticalTables[$key][$valueState] = array(); + $value_2_ref = $key . 's_' . $valueState; + $tacticalTables[$key][$valueState][$valueState] = (int)$summary->{$value_2_ref}; + foreach (array('disabled', 'unhandled', 'on_problem_hosts') as $value_3) { + $value_3_ref = $value_2_ref . '_' . $value_3; + if (isset($summary->{$value_3_ref})) { + $tacticalTables[$key][$valueState][$value_3] = (int)$summary->{$value_3_ref}; + } + } + } +} +foreach ($tacticalTables as $key => $value) { + printf( + '<table class="tacticalTable"><tr><td colspan="%d"><h1>%ss</h1></td></tr><tr>', + count($value), + init_upper($key) + ); + foreach ($value as $keyState => $valueState) { + printf( + '<td class="topbar-status-%s"><a style="font-weight: bold; color: black" href="%s" title="%ss %s">%s: %d</a>', + $keyState, + $this->href( + 'monitoring/list/' . $key . 's', + array($key . '_state' => $state[$key][$keyState]) + ), + init_upper($key), + $keyState, + init_upper($keyState), + $valueState[$keyState] + ); + foreach ($valueState as $keyStateDetail => $valueStateDetail) { + if ($keyStateDetail !== $keyState && $valueStateDetail !== 0) { + $strReplaced = str_replace('_', ' ', $keyStateDetail); + printf( + '<br /><a href="%s" title="%ss %s %s"%s>%s: %d</a>', + $this->href( + 'monitoring/list/' . $key . 's', + array( + $key . '_state' => $state[$key][$keyState], + $key . '_' . $keyStateDetail => 1 + ) + ), + init_upper($key), + $keyState, + $strReplaced, + ($strReplaced === 'unhandled' ? '' : ' style="color: #f5a9a9"'), + $strReplaced, + $valueStateDetail + ); + } + } + echo '</td>'; + } + echo '</tr></table>'; +} +?> +<table class="tacticalTable"> + <tr> + <td colspan="2"><h1>Host Checks</h1></td> + <td colspan="2"><h1>Service Checks</h1></td> + </tr> + <tr> + <td>Active</td><td>Passive</td> + <td>Active</td><td>Passive</td> + </tr> + <?php + foreach (array(true, false) as $check_enabled) { + echo '<tr>'; + foreach (array('host', 'service') as $hst_srv) { + foreach (array('act', 'pass') as $act_pass) { + $var_ref = $this->statusSummary->{sprintf( + '%ss%s_%sive_checked', + $hst_srv, + ($check_enabled ? '' : '_not'), + $act_pass + )}; + if ($var_ref === '0') { + echo '<td>'; + } else { + printf( + '<td class="topbar-status-%s">%sabled: %s', + ($check_enabled ? 'up' : 'down'), + ($check_enabled ? 'en' : 'dis'), + $var_ref + ); + } + echo '</td>'; + } + } + echo '</tr>'; + } + ?> +</table> \ No newline at end of file diff --git a/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatusSummaryQuery.php b/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatusSummaryQuery.php index e3e8c8bca..13b3fdbf4 100644 --- a/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatusSummaryQuery.php +++ b/modules/monitoring/library/Monitoring/Backend/Ido/Query/StatusSummaryQuery.php @@ -37,21 +37,46 @@ class StatusSummaryQuery extends IdoQuery protected $columnMap = array( 'hoststatussummary' => array( 'hosts_up' => 'SUM(CASE WHEN object_type = \'host\' AND state = 0 THEN 1 ELSE 0 END)', - 'hosts_unreachable_handled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime != 0 THEN 1 ELSE 0 END)', - 'hosts_unreachable_unhandled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime = 0 THEN 1 ELSE 0 END)', + 'hosts_up_disabled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 0 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)', + 'hosts_down' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 THEN 1 ELSE 0 END)', 'hosts_down_handled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 AND acknowledged + in_downtime != 0 THEN 1 ELSE 0 END)', 'hosts_down_unhandled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 AND acknowledged + in_downtime = 0 THEN 1 ELSE 0 END)', - 'hosts_pending' => 'SUM(CASE WHEN object_type = \'host\' AND state = 99 THEN 1 ELSE 0 END)' + 'hosts_down_disabled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 1 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)', + 'hosts_unreachable' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 THEN 1 ELSE 0 END)', + 'hosts_unreachable_handled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime != 0 THEN 1 ELSE 0 END)', + 'hosts_unreachable_unhandled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 AND acknowledged + in_downtime = 0 THEN 1 ELSE 0 END)', + 'hosts_unreachable_disabled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 2 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)', + 'hosts_pending' => 'SUM(CASE WHEN object_type = \'host\' AND state = 99 THEN 1 ELSE 0 END)', + 'hosts_pending_disabled' => 'SUM(CASE WHEN object_type = \'host\' AND state = 99 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)', + 'hosts_active_checked' => 'SUM(CASE WHEN object_type = \'host\' AND is_active_checked = 1 THEN 1 ELSE 0 END)', + 'hosts_not_active_checked' => 'SUM(CASE WHEN object_type = \'host\' AND is_active_checked = 0 THEN 1 ELSE 0 END)', + 'hosts_passive_checked' => 'SUM(CASE WHEN object_type = \'host\' AND is_passive_checked = 1 THEN 1 ELSE 0 END)', + 'hosts_not_passive_checked' => 'SUM(CASE WHEN object_type = \'host\' AND is_passive_checked = 0 THEN 1 ELSE 0 END)' ), 'servicestatussummary' => array( - 'services_ok' => 'SUM(CASE WHEN object_type = \'service\' AND state = 0 THEN 1 ELSE 0 END)', - 'services_pending' => 'SUM(CASE WHEN object_type = \'service\' AND state = 99 THEN 1 ELSE 0 END)', - 'services_warning_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) > 0 THEN 1 ELSE 0 END)', - 'services_critical_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) > 0 THEN 1 ELSE 0 END)', - 'services_unknown_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) > 0 THEN 1 ELSE 0 END)', - 'services_warning_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) = 0 THEN 1 ELSE 0 END)', - 'services_critical_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) = 0 THEN 1 ELSE 0 END)', - 'services_unknown_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) = 0 THEN 1 ELSE 0 END)' + 'services_ok' => 'SUM(CASE WHEN object_type = \'service\' AND state = 0 THEN 1 ELSE 0 END)', + 'services_ok_disabled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 0 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)', + 'services_warning' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 THEN 1 ELSE 0 END)', + 'services_warning_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) > 0 THEN 1 ELSE 0 END)', + 'services_warning_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) = 0 THEN 1 ELSE 0 END)', + 'services_warning_on_problem_hosts' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND host_state != 99 AND host_state != 0 THEN 1 ELSE 0 END)', + 'services_warning_disabled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 1 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)', + 'services_critical' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 THEN 1 ELSE 0 END)', + 'services_critical_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) > 0 THEN 1 ELSE 0 END)', + 'services_critical_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) = 0 THEN 1 ELSE 0 END)', + 'services_critical_on_problem_hosts' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND host_state != 99 AND host_state != 0 THEN 1 ELSE 0 END)', + 'services_critical_disabled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 2 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)', + 'services_unknown' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 THEN 1 ELSE 0 END)', + 'services_unknown_handled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) > 0 THEN 1 ELSE 0 END)', + 'services_unknown_unhandled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND (acknowledged + in_downtime + COALESCE(host_state, 0)) = 0 THEN 1 ELSE 0 END)', + 'services_unknown_on_problem_hosts' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND host_state != 99 AND host_state != 0 THEN 1 ELSE 0 END)', + 'services_unknown_disabled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 3 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)', + 'services_pending' => 'SUM(CASE WHEN object_type = \'service\' AND state = 99 THEN 1 ELSE 0 END)', + 'services_pending_disabled' => 'SUM(CASE WHEN object_type = \'service\' AND state = 99 AND is_active_checked = 0 AND is_passive_checked = 0 THEN 1 ELSE 0 END)', + 'services_active_checked' => 'SUM(CASE WHEN object_type = \'service\' AND is_active_checked = 1 THEN 1 ELSE 0 END)', + 'services_not_active_checked' => 'SUM(CASE WHEN object_type = \'service\' AND is_active_checked = 0 THEN 1 ELSE 0 END)', + 'services_passive_checked' => 'SUM(CASE WHEN object_type = \'service\' AND is_passive_checked = 1 THEN 1 ELSE 0 END)', + 'services_not_passive_checked' => 'SUM(CASE WHEN object_type = \'service\' AND is_passive_checked = 0 THEN 1 ELSE 0 END)' ) ); @@ -86,17 +111,21 @@ class StatusSummaryQuery extends IdoQuery array() ); $hosts->columns(array( - 'state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END', - 'acknowledged' => 'hs.problem_has_been_acknowledged', - 'in_downtime' => 'CASE WHEN (hs.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END', - 'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END', - 'object_type' => '(\'host\')' + 'state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END', + 'acknowledged' => 'hs.problem_has_been_acknowledged', + 'in_downtime' => 'CASE WHEN (hs.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END', + 'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END', + 'is_active_checked' => 'CASE WHEN hs.active_checks_enabled = 1 THEN 1 ELSE 0 END', + 'is_passive_checked' => 'CASE WHEN hs.passive_checks_enabled = 1 THEN 1 ELSE 0 END', + 'object_type' => '(\'host\')' )); $services->columns(array( 'state' => 'CASE WHEN ss.has_been_checked = 0 OR ss.has_been_checked IS NULL THEN 99 ELSE ss.current_state END', 'acknowledged' => 'ss.problem_has_been_acknowledged', 'in_downtime' => 'CASE WHEN (ss.scheduled_downtime_depth = 0) THEN 0 ELSE 1 END', 'host_state' => 'CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 99 ELSE hs.current_state END', + 'is_active_checked' => 'CASE WHEN ss.active_checks_enabled = 1 THEN 1 ELSE 0 END', + 'is_passive_checked' => 'CASE WHEN ss.passive_checks_enabled = 1 THEN 1 ELSE 0 END', 'object_type' => '(\'service\')' )); $union = $this->db->select()->union(array($hosts, $services), Zend_Db_Select::SQL_UNION_ALL); diff --git a/modules/monitoring/library/Monitoring/DataView/StatusSummary.php b/modules/monitoring/library/Monitoring/DataView/StatusSummary.php index 908a01da2..6b12110eb 100644 --- a/modules/monitoring/library/Monitoring/DataView/StatusSummary.php +++ b/modules/monitoring/library/Monitoring/DataView/StatusSummary.php @@ -39,20 +39,76 @@ class StatusSummary extends DataView public function getColumns() { return array( - 'hosts_up', + /*'hosts_up', + 'hosts_unreachable', 'hosts_unreachable_handled', 'hosts_unreachable_unhandled', + 'hosts_down', 'hosts_down_handled', 'hosts_down_unhandled', 'hosts_pending', 'services_ok', + 'services_critical', 'services_critical_handled', 'services_critical_unhandled', + 'services_warning', 'services_warning_handled', 'services_warning_unhandled', + 'services_unknown', 'services_unknown_handled', 'services_unknown_unhandled', - 'services_pending' + 'services_pending', + 'services_active_checked', + 'services_not_active_checked', + 'services_passive_checked', + 'services_not_passive_checked', + 'hosts_active_checked', + 'hosts_not_active_checked', + 'hosts_passive_checked', + 'hosts_not_passive_checked', + 'services_critical_on_problem_hosts', + 'services_warning_on_problem_hosts', + 'services_unknown_on_problem_hosts'*/ + + 'hosts_up', + 'hosts_up_disabled', + 'hosts_down', + 'hosts_down_handled', + 'hosts_down_unhandled', + 'hosts_down_disabled', + 'hosts_unreachable', + 'hosts_unreachable_handled', + 'hosts_unreachable_unhandled', + 'hosts_unreachable_disabled', + 'hosts_pending', + 'hosts_pending_disabled', + 'hosts_active_checked', + 'hosts_not_active_checked', + 'hosts_passive_checked', + 'hosts_not_passive_checked', + 'services_ok', + 'services_ok_disabled', + 'services_warning', + 'services_warning_handled', + 'services_warning_unhandled', + 'services_warning_on_problem_hosts', + 'services_warning_disabled', + 'services_critical', + 'services_critical_handled', + 'services_critical_unhandled', + 'services_critical_on_problem_hosts', + 'services_critical_disabled', + 'services_unknown', + 'services_unknown_handled', + 'services_unknown_unhandled', + 'services_unknown_on_problem_hosts', + 'services_unknown_disabled', + 'services_pending', + 'services_pending_disabled', + 'services_active_checked', + 'services_not_active_checked', + 'services_passive_checked', + 'services_not_passive_checked' ); } } diff --git a/modules/monitoring/public/css/main.less b/modules/monitoring/public/css/main.less index 5bf5f2db5..c80da2b67 100644 --- a/modules/monitoring/public/css/main.less +++ b/modules/monitoring/public/css/main.less @@ -39,6 +39,69 @@ @colorWarning : #FFA500; @colorUnreachable : #E066FF; +table.tacticalTable { + //width: 100%; + border: 0px; + border-collapse: separate; + border-spacing: 5px; +} + +a.tacticalLink:link, +a.tacticalLink:visited, +a.tacticalLink:hover, +a.tacticalLink:active { + color: black; +} + +a.tacticalLinkWhite:link, +a.tacticalLinkWhite:visited, +a.tacticalLinkWhite:hover, +a.tacticalLinkWhite:active { + color: white; +} + +a.tacticalLink:link, +a.tacticalLink:visited, +a.tacticalLink:active, +a.tacticalLinkWhite:link, +a.tacticalLinkWhite:visited, +a.tacticalLinkWhite:active { + text-decoration: underline; +} + +a.tacticalLink:hover, +a.tacticalLinkWhite:hover { + text-decoration: none; +} + +.whiteFont { + color: white; +} + +.tacticalHeader { + //background-color: darkgray; + font-weight: bold; +} + +.tacticalSubHeader { + background-color: lightgray; +} + +.tacticalText { + font-weight: bold; + color: black; +} + +.equalheight-container { + overflow: hidden; +} + +.equalheight { + margin-bottom: -99999px; + padding-bottom: 99999px; + background-color:#efefef; +} + .host-name { display: block; margin-top: 5px; @@ -90,6 +153,18 @@ Status colors ========================================================================== */ +.status-ok { + background-color: @colorOk!important; +} + +.status-down { + background-color: @colorDown!important; +} + +.status-unreachable { + background-color: @colorUnreachable!important; +} + .status-up { background-color: @colorUp!important; }