diff --git a/library/Icinga/Util/String.php b/library/Icinga/Util/String.php
index d9bd5a6d3..0d42d0e76 100644
--- a/library/Icinga/Util/String.php
+++ b/library/Icinga/Util/String.php
@@ -80,6 +80,20 @@ class String
return $matches;
}
+ /**
+ * Check if a string ends with a different string
+ *
+ * @param $haystack The string to search for matches
+ * @param $needle The string to match at the start of the haystack
+ *
+ * @return bool Whether or not needle is at the beginning of haystack
+ */
+ public static function endsWith($haystack, $needle)
+ {
+ return $needle === '' ||
+ (($temp = strlen($haystack) - strlen($needle)) >= 0 && false !== strpos($haystack, $needle, $temp));
+ }
+
/**
* Generates an array of strings that constitutes the cartesian product of all passed sets, with all
* string combinations concatenated using the passed join-operator.
diff --git a/library/Icinga/Web/Widget/Chart/InlinePie.php b/library/Icinga/Web/Widget/Chart/InlinePie.php
index 0bddc906d..70aadf666 100644
--- a/library/Icinga/Web/Widget/Chart/InlinePie.php
+++ b/library/Icinga/Web/Widget/Chart/InlinePie.php
@@ -5,11 +5,13 @@ namespace Icinga\Web\Widget\Chart;
use Icinga\Chart\PieChart;
use Icinga\Module\Monitoring\Plugin\PerfdataSet;
+use Icinga\Util\String;
use Icinga\Web\Widget\AbstractWidget;
use Icinga\Web\Url;
use Icinga\Util\Format;
use Icinga\Application\Logger;
use Icinga\Exception\IcingaException;
+use stdClass;
/**
* A SVG-PieChart intended to be displayed as a small icon next to labels, to offer a better visualization of the
@@ -27,6 +29,45 @@ class InlinePie extends AbstractWidget
const NUMBER_FORMAT_BYTES = 'bytes';
const NUMBER_FORMAT_RATIO = 'ratio';
+ public static $colorsHostStates = array(
+ '#44bb77', // up
+ '#ff99aa', // down
+ '#cc77ff', // unreachable
+ '#77aaff' // pending
+ );
+
+ public static $colorsHostStatesHandledUnhandled = array(
+ '#44bb77', // up
+ '#44bb77',
+ '#ff99aa', // down
+ '#ff5566',
+ '#cc77ff', // unreachable
+ '#aa44ff',
+ '#77aaff', // pending
+ '#77aaff'
+ );
+
+ public static $colorsServiceStates = array(
+ '#44bb77', // Ok
+ '#ffaa44', // Warning
+ '#ff99aa', // Critical
+ '#aa44ff', // Unknown
+ '#77aaff' // Pending
+ );
+
+ public static $colorsServiceStatesHandleUnhandled = array(
+ '#44bb77', // Ok
+ '#44bb77',
+ '#ffaa44', // Warning
+ '#ffcc66',
+ '#ff99aa', // Critical
+ '#ff5566',
+ '#cc77ff', // Unknown
+ '#aa44ff',
+ '#77aaff', // Pending
+ '#77aaff'
+ );
+
/**
* The template string used for rendering this widget
*
@@ -231,4 +272,19 @@ EOD;
$template = str_replace('{data}', htmlspecialchars(implode(',', $data)), $template);
return $template;
}
+
+ public static function createFromStateSummary(stdClass $states, $title, array $colors)
+ {
+ $handledUnhandledStates = array();
+ foreach ($states as $key => $value) {
+ if (String::endsWith($key, '_handled') || String::endsWith($key, '_unhandled')) {
+ $handledUnhandledStates[$key] = $value;
+ }
+ }
+ $chart = new self(array_values($handledUnhandledStates), $title, $colors);
+ return $chart
+ ->setSize(50)
+ ->setTitle('')
+ ->setSparklineClass('sparkline-multi');
+ }
}
diff --git a/modules/monitoring/application/controllers/HostsController.php b/modules/monitoring/application/controllers/HostsController.php
index b8e36e2b0..3c59f4643 100644
--- a/modules/monitoring/application/controllers/HostsController.php
+++ b/modules/monitoring/application/controllers/HostsController.php
@@ -14,6 +14,7 @@ use Icinga\Module\Monitoring\Forms\Command\Object\AddCommentCommandForm;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\HostList;
use Icinga\Web\Url;
+use Icinga\Web\Widget\Chart\InlinePie;
class Monitoring_HostsController extends Controller
{
@@ -127,13 +128,20 @@ class Monitoring_HostsController extends Controller
$this->view->removeAckForm = $removeAckForm;
}
+ $hostStates = (object)$this->hostList->getStateSummary();
+ $this->view->hostStatesPieChart = InlinePie::createFromStateSummary(
+ $hostStates,
+ $this->translate('Host State'),
+ InlinePie::$colorsHostStatesHandledUnhandled
+ );
+
$this->setAutorefreshInterval(15);
$this->view->rescheduleAllLink = Url::fromRequest()->setPath('monitoring/hosts/reschedule-check');
$this->view->downtimeAllLink = Url::fromRequest()->setPath('monitoring/hosts/schedule-downtime');
$this->view->processCheckResultAllLink = Url::fromRequest()->setPath('monitoring/hosts/process-check-result');
$this->view->addCommentLink = Url::fromRequest()->setPath('monitoring/hosts/add-comment');
$this->view->deleteCommentLink = Url::fromRequest()->setPath('monitoring/hosts/delete-comment');
- $this->view->stats = (object)$this->hostList->getStateSummary();
+ $this->view->stats = $hostStates;
$this->view->objects = $this->hostList;
$this->view->unhandledObjects = $unhandledObjects;
$unhandledFilterQueryString = Filter::matchAny($unhandledFilterExpressions)->toQueryString();
diff --git a/modules/monitoring/application/controllers/ServicesController.php b/modules/monitoring/application/controllers/ServicesController.php
index 691897a57..e7199ed26 100644
--- a/modules/monitoring/application/controllers/ServicesController.php
+++ b/modules/monitoring/application/controllers/ServicesController.php
@@ -15,7 +15,9 @@ use Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentCommandForm;
use Icinga\Module\Monitoring\Object\Host;
use Icinga\Module\Monitoring\Object\Service;
use Icinga\Module\Monitoring\Object\ServiceList;
+use Icinga\Util\String;
use Icinga\Web\Url;
+use Icinga\Web\Widget\Chart\InlinePie;
class Monitoring_ServicesController extends Controller
{
@@ -109,6 +111,8 @@ class Monitoring_ServicesController extends Controller
'host_name',
'host_output',
'host_state',
+ 'host_problem',
+ 'host_handled',
'service_output',
'service_description',
'service_state',
@@ -153,6 +157,20 @@ class Monitoring_ServicesController extends Controller
->handleRequest();
$this->view->removeAckForm = $removeAckForm;
}
+
+ $serviceStates = $this->serviceList->getServiceStateSummary();
+ $this->view->serviceStatesPieChart = InlinePie::createFromStateSummary(
+ $serviceStates,
+ $this->translate('Service State'),
+ InlinePie::$colorsServiceStatesHandleUnhandled
+ );
+
+ $hostStates = $this->serviceList->getHostStateSummary();
+ $this->view->hostStatesPieChart = InlinePie::createFromStateSummary(
+ $hostStates,
+ $this->translate('Host State'),
+ InlinePie::$colorsHostStatesHandledUnhandled
+ );
/*
if (! empty($objectsInDowntime)) {
$removeDowntimeForm = new DeleteDowntimeCommandForm();
@@ -170,7 +188,8 @@ class Monitoring_ServicesController extends Controller
);
$this->view->addCommentLink = Url::fromRequest()->setPath('monitoring/services/add-comment');
$this->view->deleteCommentLink = Url::fromRequest()->setPath('monitoring/services/delete-comment');
- $this->view->stats = $this->serviceList->getStateSummary();
+ $this->view->stats = $serviceStates;
+ $this->view->hostStats = $hostStates;
$this->view->objects = $this->serviceList;
$this->view->unhandledObjects = $unhandledObjects;
$unhandledFilterQueryString = Filter::matchAny($unhandledFilterExpressions)->toQueryString();
diff --git a/modules/monitoring/application/views/scripts/hosts/show.phtml b/modules/monitoring/application/views/scripts/hosts/show.phtml
index d56f92af4..ab92a2f04 100644
--- a/modules/monitoring/application/views/scripts/hosts/show.phtml
+++ b/modules/monitoring/application/views/scripts/hosts/show.phtml
@@ -9,6 +9,13 @@ use Icinga\Module\Monitoring\Forms\Command\Object\DeleteCommentCommandForm;
= $this->render('list/components/hostssummary.phtml') ?>
+
+
+
| - | - | = $this->icon('host'); ?> = $this->translate('Host'); ?> | -= $this->icon('paste'); ?> = $this->translate('Plugin Output'); ?> | -
|---|
| - | - | = $this->icon('service'); ?> = $this->translate('Service'); ?> | -= $this->icon('host'); ?> = $this->translate('Host'); ?> | -= $this->icon('paste'); ?> = $this->translate('Plugin Output'); ?> | -
|---|