Monitoring/register: Add status summary to the top bar
This commit is contained in:
parent
278f975c48
commit
36e9cdb549
|
@ -1,26 +1,14 @@
|
|||
<?php
|
||||
use Icinga\Web\Topbar;
|
||||
?>
|
||||
<nav class="navbar navbar-default navbar-fixed-top" id="icingatopbar" role="navigation">
|
||||
<div class="navbar-header">
|
||||
<a href="<?= $this->baseUrl('/') ?>" class="navbar-brand icinga-logo">Icinga</a>
|
||||
</div>
|
||||
|
||||
<div class="nav navbar-nav icinga-navbar-hosts-container">
|
||||
<span class="icinga-navbar-pills icinga-navbar-pills-up">999/999</span>
|
||||
<span class="icinga-navbar-pills icinga-navbar-pills-unreachable">999/999</span>
|
||||
<span class="icinga-navbar-pills icinga-navbar-pills-down">999/999</span>
|
||||
</div>
|
||||
|
||||
<div class="nav navbar-nav icinga-navbar-services-container">
|
||||
<span class="icinga-navbar-pills icinga-navbar-pills-ok">999/999</span>
|
||||
<span class="icinga-navbar-pills icinga-navbar-pills-critical">999/999</span>
|
||||
<span class="icinga-navbar-pills icinga-navbar-pills-warning">999/999</span>
|
||||
<span class="icinga-navbar-pills icinga-navbar-pills-unknown">999/999</span>
|
||||
</div>
|
||||
|
||||
<div class="nav navbar-nav icinga-navbar-reload">
|
||||
<a class="button btn-common btn-small" href="#">
|
||||
<i class="icinga-icon-refresh"></i>
|
||||
</a>
|
||||
</div>
|
||||
<?php foreach (Topbar::getPartials() as $partial) {
|
||||
echo $this->partial($partial['viewScriptName'], $partial['moduleName'], $partial['data']);
|
||||
} ?>
|
||||
|
||||
<form class="navbar-form navbar-left">
|
||||
<div class="form-group">
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
namespace Icinga\Application\Modules;
|
||||
|
||||
use \Exception;
|
||||
use \Icinga\Application\ApplicationBootstrap;
|
||||
use \Icinga\Application\Config;
|
||||
use \Icinga\Application\Icinga;
|
||||
|
@ -133,8 +134,12 @@ class Module
|
|||
public function register()
|
||||
{
|
||||
$this->registerAutoloader()
|
||||
->registerWebIntegration()
|
||||
->runRegisterScript();
|
||||
->registerWebIntegration();
|
||||
try {
|
||||
$this->runRegisterScript();
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Web\Hook;
|
||||
|
||||
use Icinga\Application\Logger as Logger;
|
||||
|
||||
/**
|
||||
* Class Toptray
|
||||
* @package Icinga\Web\Hook
|
||||
*/
|
||||
abstract class Toptray
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ALIGN_LEFT = "pull-left";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ALIGN_NONE = "";
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
const ALIGN_RIGHT = "pull-right";
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $align = self::ALIGN_NONE;
|
||||
|
||||
/**
|
||||
* @param $align
|
||||
*/
|
||||
public function setAlignment($align)
|
||||
{
|
||||
$this->align = $align;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
final public function getWidgetDOM()
|
||||
{
|
||||
try {
|
||||
return '<ul class="nav ' . $this->align . '" >' . $this->buildDOM() . '</ul>';
|
||||
} catch (\Exception $e) {
|
||||
Logger::error("Could not create tray widget : %s", $e->getMessage());
|
||||
return '';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
abstract protected function buildDOM();
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Web;
|
||||
|
||||
class Topbar
|
||||
{
|
||||
private static $partials = array();
|
||||
|
||||
public static function addPartial($viewScriptName, $moduleName, $data)
|
||||
{
|
||||
self::$partials[] = array(
|
||||
'viewScriptName' => $viewScriptName,
|
||||
'moduleName' => $moduleName,
|
||||
'data' => $data
|
||||
);
|
||||
}
|
||||
|
||||
public static function getPartials()
|
||||
{
|
||||
return self::$partials;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
<div class="nav navbar-nav topbar-host-status-summary">
|
||||
<span class="topbar-status-up">
|
||||
<a href="<?= $this->href('monitoring/list/hosts', array('host_severity' => 4)); ?>" title="Hosts Up">
|
||||
<?= $hostSummary->hosts_up ?>
|
||||
</a>
|
||||
</span>
|
||||
<span class="topbar-status-down">
|
||||
<a href="<?= $this->href('monitoring/list/hosts', array('host_severity' => 36)); ?>" title="Hosts Down Unhandled">
|
||||
<?= $hostSummary->hosts_down_unhandled ?>
|
||||
</a>/
|
||||
<a href="<?= $this->href('monitoring/list/hosts', array('host_severity' => array(33, 34))); ?>" title="Hosts Down Handled">
|
||||
<?= $hostSummary->hosts_down_handled ?>
|
||||
</a>
|
||||
</span>
|
||||
<span class="topbar-status-unreachable">
|
||||
<a href="<?= $this->href('monitoring/list/hosts', array('host_severity' => 68)); ?>" title="Hosts Unreachable Unhandled">
|
||||
<?= $hostSummary->hosts_unreachable_unhandled ?>
|
||||
</a>/
|
||||
<a href="<?= $this->href('monitoring/list/hosts', array('host_severity' => array(65, 66))); ?>" title="Hosts Unreachable Handled">
|
||||
<?= $hostSummary->hosts_unreachable_handled ?>
|
||||
</a>
|
||||
</span>
|
||||
<span class="topbar-status-pending">
|
||||
<a href="<?= $this->href('monitoring/list/hosts', array('host_severity' => 20)); ?>" title="Hosts Pending">
|
||||
<?= $hostSummary->hosts_pending ?>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="nav navbar-nav topbar-service-status-summary">
|
||||
<span class="topbar-status-ok">
|
||||
<a href="<?= $this->href('monitoring/list/services', array('service_severity' => 4)); ?>" title="Services Ok">
|
||||
<?= $serviceSummary->services_ok ?>
|
||||
</a>
|
||||
</span>
|
||||
<span class="topbar-status-critical">
|
||||
<a href="<?= $this->href('monitoring/list/services', array('service_severity' => 132)); ?>" title="Services Critical Unhandled">
|
||||
<?= $serviceSummary->services_critical_unhandled ?>
|
||||
</a>/
|
||||
<a href="<?= $this->href('monitoring/list/services', array('service_severity' => array(129, 130))); ?>" title="Services Critical Handled">
|
||||
<?= $serviceSummary->services_critical_handled ?>
|
||||
</a>
|
||||
</span>
|
||||
<span class="topbar-status-warning">
|
||||
<a href="<?= $this->href('monitoring/list/services', array('service_severity' => 36)); ?>" title="Services Warning Unhandled">
|
||||
<?= $serviceSummary->services_warning_unhandled ?>
|
||||
</a>/
|
||||
<a href="<?= $this->href('monitoring/list/services', array('service_severity' => array(33, 34))); ?>" title="Services Warning Handled">
|
||||
<?= $serviceSummary->services_warning_handled ?>
|
||||
</a>
|
||||
</span>
|
||||
<span class="topbar-status-unknown">
|
||||
<a href="<?= $this->href('monitoring/list/services', array('service_severity' => 68)); ?>" title="Services Unknown Unhandled">
|
||||
<?= $serviceSummary->services_unknown_unhandled ?>
|
||||
</a>/
|
||||
<a href="<?= $this->href('monitoring/list/services', array('service_severity' => array(65, 66))); ?>" title="Services Unknown Handled">
|
||||
<?= $serviceSummary->services_unknown_handled ?>
|
||||
</a>
|
||||
</span>
|
||||
<span class="topbar-status-pending">
|
||||
<a href="<?= $this->href('monitoring/list/services', array('service_severity' => 20)); ?>" title="Services Pending">
|
||||
<?= $serviceSummary->services_pending ?>
|
||||
</a>
|
||||
</span>
|
||||
</div>
|
|
@ -41,6 +41,7 @@ class DowntimeQuery extends IdoQuery
|
|||
'downtime_entry_time' => 'UNIX_TIMESTAMP(sd.entry_time)',
|
||||
'downtime_is_fixed' => 'sd.is_fixed',
|
||||
'downtime_is_flexible' => 'CASE WHEN sd.is_fixed = 0 THEN 1 ELSE 0 END',
|
||||
'downtime_scheduled_start_time' => 'UNIX_TIMESTAMP(sd.scheduled_start_time)',
|
||||
'downtime_start' => "UNIX_TIMESTAMP(CASE WHEN sd.trigger_time != '0000-00-00 00:00:00' then sd.trigger_time ELSE sd.scheduled_start_time END)",
|
||||
'downtime_end' => 'UNIX_TIMESTAMP(sd.scheduled_end_time)',
|
||||
'downtime_duration' => 'sd.duration',
|
||||
|
@ -49,8 +50,11 @@ class DowntimeQuery extends IdoQuery
|
|||
'downtime_internal_downtime_id' => 'sd.internal_downtime_id',
|
||||
),
|
||||
'objects' => array(
|
||||
'host' => 'o.name1 COLLATE latin1_general_ci',
|
||||
'service' => 'o.name2 COLLATE latin1_general_ci'
|
||||
'host' => 'o.name1 COLLATE latin1_general_ci',
|
||||
'host_name' => 'o.name1 COLLATE latin1_general_ci',
|
||||
'service' => 'o.name2 COLLATE latin1_general_ci',
|
||||
'service_description' => 'o.name2 COLLATE latin1_general_ci'
|
||||
|
||||
)
|
||||
);
|
||||
|
||||
|
|
|
@ -0,0 +1,347 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
/**
|
||||
* This file is part of Icinga 2 Web.
|
||||
*
|
||||
* Icinga 2 Web - Head for multiple monitoring backends.
|
||||
* Copyright (C) 2013 Icinga Development Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* @copyright 2013 Icinga Development Team <info@icinga.org>
|
||||
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL, version 2
|
||||
* @author Icinga Development Team <info@icinga.org>
|
||||
*/
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\Backend\Ido\Query;
|
||||
|
||||
class HoststatusQuery extends IdoQuery
|
||||
{
|
||||
protected $allowCustomVars = true;
|
||||
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',
|
||||
'host_alias' => 'h.alias',
|
||||
'host_address' => 'h.address',
|
||||
'host_ipv4' => 'INET_ATON(h.address)',
|
||||
'host_icon_image' => 'h.icon_image',
|
||||
'hosts_up' => 'SUM(CASE WHEN hs.has_been_checked != 0 AND hs.has_been_checked IS NOT NULL AND hs.current_state = 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_unreachable_handled' => 'SUM(CASE WHEN hs.has_been_checked != 0 AND hs.has_been_checked IS NOT NULL AND hs.current_state = 2 AND hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth != 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_unreachable_unhandled' => 'SUM(CASE WHEN hs.has_been_checked != 0 AND hs.has_been_checked IS NOT NULL AND hs.current_state = 2 AND hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth = 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_down_handled' => 'SUM(CASE WHEN hs.has_been_checked != 0 AND hs.has_been_checked IS NOT NULL AND hs.current_state = 1 AND hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth != 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_down_unhandled' => 'SUM(CASE WHEN hs.has_been_checked != 0 AND hs.has_been_checked IS NOT NULL AND hs.current_state = 1 AND hs.problem_has_been_acknowledged + hs.scheduled_downtime_depth = 0 THEN 1 ELSE 0 END)',
|
||||
'hosts_pending' => 'SUM(CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 1 ELSE 0 END)'
|
||||
),
|
||||
'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
|
||||
THEN
|
||||
CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL
|
||||
THEN 16
|
||||
ELSE 0
|
||||
END
|
||||
+
|
||||
CASE WHEN hs.problem_has_been_acknowledged = 1
|
||||
THEN 2
|
||||
ELSE
|
||||
CASE WHEN hs.scheduled_downtime_depth > 0
|
||||
THEN 1
|
||||
ELSE 4
|
||||
END
|
||||
END
|
||||
ELSE
|
||||
CASE WHEN hs.has_been_checked = 0 OR hs.has_been_checked IS NULL THEN 16
|
||||
WHEN hs.current_state = 1 THEN 32
|
||||
WHEN hs.current_state = 2 THEN 64
|
||||
ELSE 256
|
||||
END
|
||||
+
|
||||
CASE WHEN hs.problem_has_been_acknowledged = 1
|
||||
THEN 2
|
||||
ELSE
|
||||
CASE WHEN hs.scheduled_downtime_depth > 0
|
||||
THEN 1
|
||||
ELSE 4
|
||||
END
|
||||
END
|
||||
END',
|
||||
),
|
||||
'hostgroups' => array(
|
||||
'hostgroup' => 'hgo.name1 COLLATE latin1_general_ci',
|
||||
),
|
||||
'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 = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_critical_handled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_unknown_handled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged = 1 OR ss.scheduled_downtime_depth > 0) THEN 1 ELSE 0 END)',
|
||||
'services_warning_unhandled' => 'SUM(CASE WHEN ss.current_state = 1 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
'services_critical_unhandled' => 'SUM(CASE WHEN ss.current_state = 2 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
'services_unknown_unhandled' => 'SUM(CASE WHEN ss.current_state = 3 AND (ss.problem_has_been_acknowledged = 0 AND ss.scheduled_downtime_depth = 0) THEN 1 ELSE 0 END)',
|
||||
),
|
||||
);
|
||||
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'];
|
||||
}
|
||||
|
||||
protected function joinBaseTables()
|
||||
{
|
||||
// TODO: Shall we always add hostobject?
|
||||
$this->baseQuery = $this->db->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',
|
||||
array()
|
||||
);
|
||||
$this->joinedVirtualTables = array(
|
||||
'hosts' => true,
|
||||
'hoststatus' => true,
|
||||
);
|
||||
}
|
||||
|
||||
protected function joinStatus()
|
||||
{
|
||||
$this->requireVirtualTable('services');
|
||||
}
|
||||
|
||||
protected function joinServiceStatus()
|
||||
{
|
||||
$this->requireVirtualTable('services');
|
||||
}
|
||||
|
||||
protected function joinServices()
|
||||
{
|
||||
$this->baseQuery->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()
|
||||
);
|
||||
foreach ($this->getColumns() as $col) {
|
||||
$real = $this->aliasToColumnName($col);
|
||||
if (substr($real, 0, 4) === 'SUM(') {
|
||||
continue;
|
||||
}
|
||||
$this->baseQuery->group($real);
|
||||
}
|
||||
$this->useSubqueryCount = true;
|
||||
}
|
||||
|
||||
protected function joinHostgroups()
|
||||
{
|
||||
if ($this->hasJoinedVirtualTable('services')) {
|
||||
return $this->joinServiceHostgroups();
|
||||
} else {
|
||||
return $this->joinHostHostgroups();
|
||||
}
|
||||
}
|
||||
|
||||
protected function joinServiceHostgroups()
|
||||
{
|
||||
$this->baseQuery->join(
|
||||
array('hgm' => $this->prefix . 'hostgroup_members'),
|
||||
'hgm.host_object_id = s.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 joinHostHostgroups()
|
||||
{
|
||||
$this->baseQuery->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->baseQuery->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->baseQuery->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->baseQuery->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',
|
||||
array()
|
||||
);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
|
@ -71,6 +71,7 @@ abstract class DataView implements Filterable
|
|||
*/
|
||||
public static function fromRequest($request, array $columns = null)
|
||||
{
|
||||
|
||||
$view = new static(Backend::createBackend($request->getParam('backend')), $columns);
|
||||
$parser = new UrlViewFilter($view);
|
||||
$view->getQuery()->setFilter($parser->fromRequest($request));
|
||||
|
@ -107,7 +108,6 @@ abstract class DataView implements Filterable
|
|||
$view->getQuery()->where($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
$order = isset($params['order']) ? $params['order'] : null;
|
||||
if ($order !== null) {
|
||||
if (strtolower($order) === 'desc') {
|
||||
|
@ -154,31 +154,32 @@ abstract class DataView implements Filterable
|
|||
public function sort($column = null, $order = null)
|
||||
{
|
||||
$sortRules = $this->getSortRules();
|
||||
|
||||
if ($column === null) {
|
||||
$sortColumns = reset($sortRules);
|
||||
if (!isset($sortColumns['columns'])) {
|
||||
$sortColumns['columns'] = array(key($sortRules));
|
||||
}
|
||||
} else {
|
||||
if (isset($sortRules[$column])) {
|
||||
$sortColumns = $sortRules[$column];
|
||||
if ($sortRules !== null) {
|
||||
if ($column === null) {
|
||||
$sortColumns = reset($sortRules);
|
||||
if (!isset($sortColumns['columns'])) {
|
||||
$sortColumns['columns'] = array($column);
|
||||
$sortColumns['columns'] = array(key($sortRules));
|
||||
}
|
||||
} else {
|
||||
$sortColumns = array(
|
||||
'columns' => array($column),
|
||||
'order' => $order
|
||||
);
|
||||
};
|
||||
}
|
||||
if (isset($sortRules[$column])) {
|
||||
$sortColumns = $sortRules[$column];
|
||||
if (!isset($sortColumns['columns'])) {
|
||||
$sortColumns['columns'] = array($column);
|
||||
}
|
||||
} else {
|
||||
$sortColumns = array(
|
||||
'columns' => array($column),
|
||||
'order' => $order
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
$order = $order === null ? (isset($sortColumns['order']) ? $sortColumns['order'] : self::SORT_ASC) : $order;
|
||||
$order = ($order === self::SORT_ASC) ? 'ASC' : 'DESC';
|
||||
$order = $order === null ? (isset($sortColumns['order']) ? $sortColumns['order'] : self::SORT_ASC) : $order;
|
||||
$order = ($order === self::SORT_ASC) ? 'ASC' : 'DESC';
|
||||
|
||||
foreach ($sortColumns['columns'] as $column) {
|
||||
$this->query->order($column, $order);
|
||||
foreach ($sortColumns['columns'] as $column) {
|
||||
$this->query->order($column, $order);
|
||||
}
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
@ -188,7 +189,10 @@ abstract class DataView implements Filterable
|
|||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function getSortRules();
|
||||
public function getSortRules()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getMappedField($field)
|
||||
{
|
||||
|
|
|
@ -15,7 +15,9 @@ class Downtime extends DataView
|
|||
{
|
||||
return array(
|
||||
'host',
|
||||
'host_name',
|
||||
'service',
|
||||
'service_description',
|
||||
'downtime_author',
|
||||
'downtime_comment',
|
||||
'downtime_entry_time',
|
||||
|
|
|
@ -58,7 +58,8 @@ class HostStatus extends DataView
|
|||
'host_action_url',
|
||||
'host_notes_url',
|
||||
'host_percent_state_change',
|
||||
'host_modified_host_attributes'
|
||||
'host_modified_host_attributes',
|
||||
'host_severity'
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Module\Monitoring\DataView;
|
||||
|
||||
class StatusSummary extends DataView
|
||||
{
|
||||
/**
|
||||
* Retrieve columns provided by this view
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getColumns()
|
||||
{
|
||||
return array(
|
||||
'hosts_up',
|
||||
'hosts_unreachable_handled',
|
||||
'hosts_unreachable_unhandled',
|
||||
'hosts_down_handled',
|
||||
'hosts_down_unhandled',
|
||||
'hosts_pending',
|
||||
'services_ok',
|
||||
'services_critical_handled',
|
||||
'services_critical_unhandled',
|
||||
'services_warning_handled',
|
||||
'services_warning_unhandled',
|
||||
'services_unknown_handled',
|
||||
'services_unknown_unhandled',
|
||||
'services_pending'
|
||||
);
|
||||
}
|
||||
|
||||
public static function getTableName()
|
||||
{
|
||||
return 'hoststatus';
|
||||
}
|
||||
}
|
|
@ -197,40 +197,24 @@
|
|||
padding-left: 25px !important;
|
||||
}
|
||||
|
||||
.icinga-navbar-pills-mixin (@color) {
|
||||
border-color: @color;
|
||||
color: @color;
|
||||
.topbar-status-summary-mixin (@backgroundImage) {
|
||||
background-image: url(@backgroundImage);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5px 50%;
|
||||
padding-left: 30px !important;
|
||||
margin-top: 15px;
|
||||
span:not(:last-child) {
|
||||
margin-right: 5px;
|
||||
}
|
||||
}
|
||||
.topbar-host-status-summary {
|
||||
.topbar-status-summary-mixin('../../img/icons/host.png');
|
||||
}
|
||||
.topbar-service-status-summary {
|
||||
.topbar-status-summary-mixin('../../img/icons/service.png');
|
||||
}
|
||||
|
||||
.icinga-navbar-pills-critical {
|
||||
.icinga-navbar-pills-mixin(@colorCritical);
|
||||
}
|
||||
|
||||
.icinga-navbar-pills-ok {
|
||||
.icinga-navbar-pills-mixin(@colorOk);
|
||||
}
|
||||
|
||||
.icinga-navbar-pills-warning {
|
||||
.icinga-navbar-pills-mixin(@colorWarning);
|
||||
}
|
||||
|
||||
.icinga-navbar-pills-unknown {
|
||||
.icinga-navbar-pills-mixin(@colorWarning);
|
||||
}
|
||||
|
||||
.icinga-navbar-pills-unreachable {
|
||||
.icinga-navbar-pills-mixin(@colorUnreachable);
|
||||
}
|
||||
|
||||
.icinga-navbar-pills-down {
|
||||
.icinga-navbar-pills-mixin(@colorDown);
|
||||
}
|
||||
|
||||
.icinga-navbar-pills-up {
|
||||
.icinga-navbar-pills-mixin(@colorUp);
|
||||
}
|
||||
|
||||
.state-tile (@color) {
|
||||
.topbar-status-mixin (@color) {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 3px 5px 3px 5px;
|
||||
|
@ -238,20 +222,39 @@
|
|||
font-size: 13px;
|
||||
border-color: @color;
|
||||
color: @color;
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
|
||||
.state-tile-up {
|
||||
.navigation-tile-mixin(@colorUp);
|
||||
.topbar-status-up {
|
||||
.topbar-status-mixin(@colorUp);
|
||||
}
|
||||
|
||||
.state-tile-unreachable {
|
||||
.navigation-tile-mixin(@colorUnreachable);
|
||||
.topbar-status-down {
|
||||
.topbar-status-mixin(@colorDown);
|
||||
}
|
||||
|
||||
.state-tile-down {
|
||||
.navigation-tile-mixin(@colorDown);
|
||||
.topbar-status-unreachable {
|
||||
.topbar-status-mixin(@colorUnreachable);
|
||||
}
|
||||
|
||||
.state-tile-pending {
|
||||
.navigation-tile-mixin(@colorPending);
|
||||
}
|
||||
.topbar-status-pending {
|
||||
.topbar-status-mixin(@colorPending);
|
||||
}
|
||||
|
||||
.topbar-status-ok {
|
||||
.topbar-status-mixin(@colorOk);
|
||||
}
|
||||
|
||||
.topbar-status-critical {
|
||||
.topbar-status-mixin(@colorCritical);
|
||||
}
|
||||
|
||||
.topbar-status-warning {
|
||||
.topbar-status-mixin(@colorWarning);
|
||||
}
|
||||
|
||||
.topbar-status-unknown {
|
||||
.topbar-status-mixin(@colorUnknown);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
use Icinga\Authentication\Manager as AuthManager;
|
||||
use Icinga\Application\Icinga;
|
||||
use Icinga\Module\Monitoring\DataView\StatusSummary as StatusSummaryView;
|
||||
use Icinga\Web\Topbar;
|
||||
|
||||
$request = Icinga::app()->getFrontController()->getRequest();
|
||||
|
||||
if (AuthManager::getInstance()->isAuthenticated()) {
|
||||
$hostSummary = StatusSummaryView::fromRequest(
|
||||
$request,
|
||||
array(
|
||||
'hosts_up',
|
||||
'hosts_unreachable_handled',
|
||||
'hosts_unreachable_unhandled',
|
||||
'hosts_down_handled',
|
||||
'hosts_down_unhandled',
|
||||
'hosts_pending'
|
||||
)
|
||||
)->getQuery()->fetchRow();
|
||||
|
||||
$serviceSummary = StatusSummaryView::fromRequest(
|
||||
$request,
|
||||
array(
|
||||
'services_ok',
|
||||
'services_critical_handled',
|
||||
'services_critical_unhandled',
|
||||
'services_warning_handled',
|
||||
'services_warning_unhandled',
|
||||
'services_unknown_handled',
|
||||
'services_unknown_unhandled',
|
||||
'services_pending'
|
||||
)
|
||||
)->getQuery()->fetchRow();
|
||||
|
||||
Topbar::addPartial(
|
||||
'topbar.phtml',
|
||||
'monitoring',
|
||||
array('hostSummary' => $hostSummary, 'serviceSummary' => $serviceSummary)
|
||||
);
|
||||
}
|
||||
|
||||
?>
|
|
@ -169,26 +169,3 @@ ul.icinga-subnavigation {
|
|||
padding-left: 15px;
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
.icinga-navbar-hosts-container {
|
||||
background-image: url('../../img/icons/host.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5px 50%;
|
||||
padding-left: 30px !important;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.icinga-navbar-services-container {
|
||||
background-image: url('../../img/icons/service.png');
|
||||
background-repeat: no-repeat;
|
||||
background-position: 5px 50%;
|
||||
padding-left: 25px !important;
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.icinga-navbar-pills {
|
||||
border-style: solid;
|
||||
border-width: 1px;
|
||||
padding: 3px 5px 3px 5px;
|
||||
border-radius: 3px;
|
||||
font-size: 13px;
|
||||
}
|
Loading…
Reference in New Issue