diff --git a/library/Icinga/Protocol/Ldap/LdapConnection.php b/library/Icinga/Protocol/Ldap/LdapConnection.php index 57b1fe90d..d78b4a147 100644 --- a/library/Icinga/Protocol/Ldap/LdapConnection.php +++ b/library/Icinga/Protocol/Ldap/LdapConnection.php @@ -666,7 +666,7 @@ class LdapConnection implements Selectable, Inspectable $ds = $this->getConnection(); - $serverSorting = $this->capabilities->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID); + $serverSorting = $this->getCapabilities()->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID); if ($serverSorting && $query->hasOrder()) { ldap_set_option($ds, LDAP_OPT_SERVER_CONTROLS, array( array( @@ -761,7 +761,7 @@ class LdapConnection implements Selectable, Inspectable $ds = $this->getConnection(); - $serverSorting = $this->capabilities->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID); + $serverSorting = $this->getCapabilities()->hasOid(LdapCapabilities::LDAP_SERVER_SORT_OID); if (! $serverSorting && $query->hasOrder()) { foreach ($query->getOrder() as $rule) { if (! in_array($rule[0], $fields)) { diff --git a/library/Icinga/Web/Url.php b/library/Icinga/Web/Url.php index 7c3829537..237c8988a 100644 --- a/library/Icinga/Web/Url.php +++ b/library/Icinga/Web/Url.php @@ -6,7 +6,7 @@ namespace Icinga\Web; use Icinga\Application\Icinga; use Icinga\Cli\FakeRequest; use Icinga\Exception\ProgrammingError; -use Icinga\Web\UrlParams; +use Icinga\Data\Filter\Filter; /** * Url class that provides convenient access to parameters, allows to modify query parameters and @@ -156,6 +156,26 @@ class Url return $urlObject; } + /** + * Create a new filter that needs to fullfill the base filter and the optional filter (if it exists) + * + * @param string $url The url to apply the new filter to + * @param Filter $filter The base filter + * @param Filter $optional The optional filter + * + * @return Url The altered URL containing the new filter + * @throws ProgrammingError + */ + public static function urlAddFilterOptional($url, $filter, $optional) + { + $url = Url::fromPath($url); + $f = $filter; + if (isset($optional)) { + $f = Filter::matchAll($filter, $optional); + } + return $url->setQueryString($f->toQueryString()); + } + /** * Overwrite the baseUrl * diff --git a/modules/monitoring/application/controllers/ProcessController.php b/modules/monitoring/application/controllers/HealthController.php similarity index 58% rename from modules/monitoring/application/controllers/ProcessController.php rename to modules/monitoring/application/controllers/HealthController.php index 84a1a15f5..bbfdcb030 100644 --- a/modules/monitoring/application/controllers/ProcessController.php +++ b/modules/monitoring/application/controllers/HealthController.php @@ -11,7 +11,7 @@ use Icinga\Web\Widget\Tabextension\DashboardAction; /** * Display process and performance information of the monitoring host and program-wide commands */ -class ProcessController extends Controller +class HealthController extends Controller { /** * Add tabs @@ -29,10 +29,21 @@ class ProcessController extends Controller 'Show information about the current monitoring instance\'s process' . ' and it\'s performance as well as available features' ), - 'label' => $this->translate('Monitoring Health'), - 'url' =>'monitoring/process/info' + 'label' => $this->translate('Process Information'), + 'url' =>'monitoring/health/info' ) - )->extend(new DashboardAction()); + ) + ->add( + 'stats', + array( + 'title' => $this->translate( + 'Show statistics about the monitored objects' + ), + 'label' => $this->translate('Stats'), + 'url' =>'monitoring/health/stats' + ) + ) + ->extend(new DashboardAction()); } /** @@ -40,7 +51,7 @@ class ProcessController extends Controller */ public function infoAction() { - $this->view->title = $this->translate('Monitoring Health'); + $this->view->title = $this->translate('Process Information'); $this->getTabs()->activate('info'); $this->setAutorefreshInterval(10); $this->view->backendName = $this->backend->getName(); @@ -95,6 +106,61 @@ class ProcessController extends Controller ->getQuery()->fetchAll(); } + /** + * Display stats about current checks and monitored objects + */ + public function statsAction() + { + $this->getTabs()->activate('stats'); + + $servicestats = $this->backend->select()->from('servicestatussummary', array( + 'services_critical', + 'services_critical_handled', + 'services_critical_unhandled', + 'services_ok', + 'services_pending', + 'services_total', + 'services_unknown', + 'services_unknown_handled', + 'services_unknown_unhandled', + 'services_warning', + 'services_warning_handled', + 'services_warning_unhandled' + )); + $this->applyRestriction('monitoring/filter/objects', $servicestats); + $this->view->servicestats = $servicestats->fetchRow(); + $this->view->unhandledServiceProblems = $this->view->servicestats->services_critical_unhandled + + $this->view->servicestats->services_unknown_unhandled + + $this->view->servicestats->services_warning_unhandled; + + $hoststats = $this->backend->select()->from('hoststatussummary', array( + 'hosts_total', + 'hosts_up', + 'hosts_down', + 'hosts_down_handled', + 'hosts_down_unhandled', + 'hosts_unreachable', + 'hosts_unreachable_handled', + 'hosts_unreachable_unhandled', + 'hosts_pending', + )); + $this->applyRestriction('monitoring/filter/objects', $hoststats); + $this->view->hoststats = $hoststats->fetchRow(); + $this->view->unhandledhostProblems = $this->view->hoststats->hosts_down_unhandled + + $this->view->hoststats->hosts_unreachable_unhandled; + + $this->view->unhandledProblems = $this->view->unhandledhostProblems + + $this->view->unhandledServiceProblems; + + $this->view->runtimevariables = (object) $this->backend->select() + ->from('runtimevariables', array('varname', 'varvalue')) + ->getQuery()->fetchPairs(); + + $this->view->checkperformance = $this->backend->select() + ->from('runtimesummary') + ->getQuery()->fetchAll(); + } + /** * Disable notifications w/ an optional expire time */ @@ -119,7 +185,7 @@ class ProcessController extends Controller } else { $form = new DisableNotificationsExpireCommandForm(); $form - ->setRedirectUrl('monitoring/process/info') + ->setRedirectUrl('monitoring/health/info') ->handleRequest(); $this->view->form = $form; } diff --git a/modules/monitoring/application/controllers/HostsController.php b/modules/monitoring/application/controllers/HostsController.php index 036b78c32..3c576fbc8 100644 --- a/modules/monitoring/application/controllers/HostsController.php +++ b/modules/monitoring/application/controllers/HostsController.php @@ -32,6 +32,7 @@ class HostsController extends Controller $this->applyRestriction('monitoring/filter/objects', $hostList); $hostList->addFilter(Filter::fromQueryString((string) $this->params)); $this->hostList = $hostList; + $this->view->baseFilter = $this->hostList->getFilter(); $this->getTabs()->add( 'show', array( @@ -152,7 +153,6 @@ class HostsController extends Controller ->toQueryString() ); $this->view->commentsLink = Url::fromRequest()->setPath('monitoring/list/comments'); - $this->view->baseFilter = $this->hostList->getFilter(); $this->view->sendCustomNotificationLink = Url::fromRequest()->setPath('monitoring/hosts/send-custom-notification'); } diff --git a/modules/monitoring/application/controllers/ServicesController.php b/modules/monitoring/application/controllers/ServicesController.php index deee364fa..26561f8ff 100644 --- a/modules/monitoring/application/controllers/ServicesController.php +++ b/modules/monitoring/application/controllers/ServicesController.php @@ -33,6 +33,7 @@ class ServicesController extends Controller (string) $this->params->without(array('service_problem', 'service_handled', 'view')) )); $this->serviceList = $serviceList; + $this->view->baseFilter = $this->serviceList->getFilter(); $this->view->listAllLink = Url::fromRequest()->setPath('monitoring/list/services'); $this->getTabs()->add( 'show', @@ -163,7 +164,6 @@ class ServicesController extends Controller ); $this->view->commentsLink = Url::fromRequest() ->setPath('monitoring/list/comments'); - $this->view->baseFilter = $this->serviceList->getFilter(); $this->view->sendCustomNotificationLink = Url::fromRequest()->setPath( 'monitoring/services/send-custom-notification' ); diff --git a/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php b/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php index d487647e2..6f727232f 100644 --- a/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php +++ b/modules/monitoring/application/forms/Command/Instance/ToggleInstanceFeaturesCommandForm.php @@ -65,7 +65,7 @@ class ToggleInstanceFeaturesCommandForm extends CommandForm $notificationDescription = sprintf( '<a aria-label="%1$s" title="%1$s" href="%2$s" data-base-target="_next">%3$s</a>', $this->translate('Disable notifications for a specific time on a program-wide basis'), - $this->getView()->href('monitoring/process/disable-notifications'), + $this->getView()->href('monitoring/health/disable-notifications'), $this->translate('Disable temporarily') ); } else { diff --git a/modules/monitoring/application/views/scripts/process/disable-notifications.phtml b/modules/monitoring/application/views/scripts/health/disable-notifications.phtml similarity index 100% rename from modules/monitoring/application/views/scripts/process/disable-notifications.phtml rename to modules/monitoring/application/views/scripts/health/disable-notifications.phtml diff --git a/modules/monitoring/application/views/scripts/health/info.phtml b/modules/monitoring/application/views/scripts/health/info.phtml new file mode 100644 index 000000000..78a58d525 --- /dev/null +++ b/modules/monitoring/application/views/scripts/health/info.phtml @@ -0,0 +1,84 @@ +<?php +$rv = $this->runtimeVariables()->create($this->runtimevariables); +$cp = $this->checkPerformance()->create($this->checkperformance); + +if (! $this->compact): ?> +<div class="controls"> + <?= $this->tabs; ?> +</div> +<?php endif ?> + +<div class="content processinfo"> + <div class="boxview"> + <div style="min-width: 30em;" class="box left"> + <h2><?= $this->translate('Process Info') ?></h2> + <table class="avp"> + <tbody> + <tr> + <th><?= $this->translate('Program Version') ?></th> + <td><?= $this->programStatus->program_version + ? $this->programStatus->program_version + : $this->translate('N/A') ?></td> + </tr> + <tr> + <th><?= $this->translate('Program Start Time') ?></th> + <td><?= $this->formatDateTime($this->programStatus->program_start_time) ?></td> + </tr> + <tr> + <th><?= $this->translate('Last Status Update'); ?></th> + <td><?= $this->timeAgo($this->programStatus->status_update_time); ?></td> + </tr> + <tr> + <th><?= $this->translate('Last External Command Check'); ?></th> + <td><?= $this->timeAgo($this->programStatus->last_command_check); ?></td> + </tr> + <tr> + <th><?= $this->translate('Last Log File Rotation'); ?></th> + <td><?= $this->programStatus->last_log_rotation + ? $this->timeSince($this->programStatus->last_log_rotation) + : $this->translate('N/A') ?></td> + </tr> + <tr> + <th><?= $this->translate('Global Service Event Handler'); ?></th> + <td><?= $this->programStatus->global_service_event_handler + ? $this->programStatus->global_service_event_handler + : $this->translate('N/A'); ?></td> + </tr> + <tr> + <th><?= $this->translate('Global Host Event Handler'); ?></th> + <td><?= $this->programStatus->global_host_event_handler + ? $this->programStatus->global_host_event_handler + : $this->translate('N/A'); ?></td> + </tr> + <tr> + <th><?= $this->translate('Active Endpoint'); ?></th> + <td><?= $this->programStatus->endpoint_name + ? $this->programStatus->endpoint_name + : $this->translate('N/A') ?></td> + </tr> + </tbody> + </table> + <?php if ((bool) $this->programStatus->is_currently_running === true): ?> + <div class="backend-running"> + <?= sprintf( + $this->translate( + '%1$s has been up and running with PID %2$d %3$s', + 'Last format parameter represents the time running' + ), + $this->backendName, + $this->programStatus->process_id, + $this->timeSince($this->programStatus->program_start_time)) ?> + </div> + <?php else: ?> + <div class="backend-not-running"> + <?= sprintf($this->translate('Backend %s is not running'), $this->backendName) ?> + </div> + <?php endif ?> + </div> + + <br> + <div style="min-width: 30em;" class="box left"> + <?= $this->toggleFeaturesForm; ?> + </div> + </div> +</div> diff --git a/modules/monitoring/application/views/scripts/process/not-running.phtml b/modules/monitoring/application/views/scripts/health/not-running.phtml similarity index 100% rename from modules/monitoring/application/views/scripts/process/not-running.phtml rename to modules/monitoring/application/views/scripts/health/not-running.phtml diff --git a/modules/monitoring/application/views/scripts/health/stats.phtml b/modules/monitoring/application/views/scripts/health/stats.phtml new file mode 100644 index 000000000..792b5a050 --- /dev/null +++ b/modules/monitoring/application/views/scripts/health/stats.phtml @@ -0,0 +1,160 @@ +<?php +$rv = $this->runtimeVariables()->create($this->runtimevariables); +$cp = $this->checkPerformance()->create($this->checkperformance); + +if (! $this->compact): ?> +<div class="controls"> + <?= $this->tabs ?> +</div> +<?php endif ?> + +<div class="content processinfo"> + <div class="boxview"> + <div class="box left"> + <h3><?= $this->unhandledProblems ?> <?= $this->translate('Unhandled Problems:') ?> + <span class="badge badge-critical"> <?= $this->unhandledProblems ?> </span> + </h3> + <table class="avp"> + <tbody> + <tr> + <th> <?= $this->translate('Service Problems:') ?> </th> + <td> + <span class="badge badge-critical"> + <?= + $this->qlink( + $this->unhandledServiceProblems, + 'monitoring/list/services?service_problem=1&service_handled=0&sort=service_severity', + null, + array('data-base-target' => '_next') + ) + ?> + </span> + </td> + </tr> + <tr> + <th> <?= $this->translate('Host Problems:') ?> </th> + <td> + <span class="badge badge-critical"> + <?= + $this->qlink( + $this->unhandledhostProblems, + 'monitoring/list/hosts?host_problem=1&host_handled=0', + null, + array('data-base-target' => '_next') + ) + ?> + </span> + </td> + </tr> + </tbody> + </table> + <br> + + <h3 class="tinystatesummary" data-base-target="_next"> + <?php $this->stats = $hoststats ?> + <?= $this->render('list/components/hostssummary.phtml') ?> + </h3> + <table class="avp"> + <thead> + <tr> + <th><strong><?= $this->translate('Runtime Variables') ?></strong></th> + <th><?= $this->translate('Host Checks') ?></th> + <th></th> + <th></th> + </tr> + </thead> + <tbody> + <tr> + <th> <?= $this->translate('Total') ?> </th> + <td> <?= $rv->total_scheduled_hosts ?> </td> + </tr> + <tr> + <th> <?= $this->translate('Scheduled') ?> </th> + <td> <?= $rv->total_scheduled_hosts ?> </td> + </tr> + </tbody> + </table> + <br> + + <h3 class="tinystatesummary" data-base-target="_next"> + <?php $this->stats = $servicestats ?> + <?= $this->render('list/components/servicesummary.phtml') ?> + </h3> + <table class="avp"> + <thead> + <tr> + <th><strong> <?= $this->translate('Runtime Variables') ?> </strong></th> + <th><?= $this->translate('Service Checks') ?></th> + <th><?= $this->translate('Per Host') ?></th> + <th></th> + </tr> + </thead> + <tbody> + <tr> + <th> <?= $this->translate('Total') ?> </th> + <td> <?= $rv->total_services ?> </td> + <td> <?= sprintf('%.2f', $rv->average_services_per_host) ?> </td> + <td></td> + </tr> + <tr> + <th> <?= $this->translate('Scheduled') ?> </th> + <td> <?= $rv->total_scheduled_services ?> </td> + <td> <?= sprintf('%.2f', $rv->average_scheduled_services_per_host) ?> </td> + <td></td> + </tr> + </tbody> + </table> + <br> + + <h3><?= $this->translate('Active checks') ?></h3> + <table class="avp"> + <thead> + <tr> + <th><strong> <?= $this->translate('Check Performance') ?> </strong></th> + <th><?= $this->translate('Checks') ?></th> + <th><?= $this->translate('Latency') ?></th> + <th><?= $this->translate('Execution time') ?></th> + </tr> + </thead> + <tbody> + <tr> + <th><?= $this->translate('Host Checks') ?></th> + <td><?= $cp->host_active_count; ?></td> + <td><?= sprintf('%.3f', $cp->host_active_latency_avg) ?>s</td> + <td><?= sprintf('%.3f', $cp->host_active_execution_avg) ?>s</td> + </tr> + <tr> + <th><?= $this->translate('Service Checks') ?></th> + <td><?= $cp->service_active_count; ?></td> + <td><?= sprintf('%.3f', $cp->service_active_latency_avg) ?>s</td> + <td><?= sprintf('%.3f', $cp->service_active_execution_avg) ?>s</td> + </tr> + </tbody> + </table> + <br> + + <h3><?= $this->translate('Passive checks') ?></h3> + <table class="avp"> + <thead> + <tr> + <th><strong> <?= $this->translate('Check Performance') ?> </strong></th> + <th><?= $this->translate('Passive Checks') ?></th> + <th></th> + <th></th> + </tr> + </thead> + <tbody> + <tr> + <th><?= $this->translate('Host Checks') ?></th> + <td><?= $cp->host_passive_count ?></td> + </tr> + <tr> + <th><?= $this->translate('Service Checks') ?></th> + <td><?= $cp->service_passive_count ?></td> + </tr> + </tbody> + </table> + </div> + + </div> +</div> diff --git a/modules/monitoring/application/views/scripts/host/services.phtml b/modules/monitoring/application/views/scripts/host/services.phtml index 11166f8fa..fd69d88ad 100644 --- a/modules/monitoring/application/views/scripts/host/services.phtml +++ b/modules/monitoring/application/views/scripts/host/services.phtml @@ -1,9 +1,17 @@ +<?php use Icinga\Data\Filter\Filter; ?> + <div class="controls"> <?php if (! $this->compact): ?> <?= $this->tabs; ?> <?php endif ?> <?= $this->render('partials/host/object-header.phtml') ?> - <?= $this->render('partials/host/servicesummary.phtml') ?> + <h2 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?> + <?php + $this->baseFilter = Filter::where('host', $object->host_name); + $this->stats = $object->stats; + echo $this->render('list/components/servicesummary.phtml'); + ?> + </h2> </div> <?= $this->partial( 'list/services.phtml', diff --git a/modules/monitoring/application/views/scripts/host/show.phtml b/modules/monitoring/application/views/scripts/host/show.phtml index a612ae1af..12de39a78 100644 --- a/modules/monitoring/application/views/scripts/host/show.phtml +++ b/modules/monitoring/application/views/scripts/host/show.phtml @@ -1,9 +1,17 @@ +<?php use Icinga\Data\Filter\Filter; ?> + <div class="controls separated"> <?php if (! $this->compact): ?> <?= $this->tabs; ?> <?php endif ?> <?= $this->render('partials/host/object-header.phtml') ?> - <?= $this->render('partials/host/servicesummary.phtml') ?> + <h3 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?>> + <?php + $this->stats = $object->stats; + $this->baseFilter = Filter::where('host', $object->host_name); + echo $this->render('list/components/servicesummary.phtml'); + ?> + </h3> </div> <div class="content" data-base-target="_next"> <?= $this->render('show/components/output.phtml') ?> diff --git a/modules/monitoring/application/views/scripts/hosts/show.phtml b/modules/monitoring/application/views/scripts/hosts/show.phtml index 3dbb0673f..053c44520 100644 --- a/modules/monitoring/application/views/scripts/hosts/show.phtml +++ b/modules/monitoring/application/views/scripts/hosts/show.phtml @@ -3,7 +3,9 @@ <?= $tabs; ?> <?php endif ?> - <?= $this->render('list/components/hostssummary.phtml') ?> + <h2 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?> + <?= $this->render('list/components/hostssummary.phtml') ?> + </h2> <?= $this->render('partials/host/objects-header.phtml'); ?> </div> diff --git a/modules/monitoring/application/views/scripts/list/components/hostssummary.phtml b/modules/monitoring/application/views/scripts/list/components/hostssummary.phtml index 22f84b583..3fe11bcca 100644 --- a/modules/monitoring/application/views/scripts/list/components/hostssummary.phtml +++ b/modules/monitoring/application/views/scripts/list/components/hostssummary.phtml @@ -3,20 +3,16 @@ use Icinga\Web\Url; use Icinga\Data\Filter\Filter; -function urlAddFilterOptional($url, $filter, $optional) { - $url = Url::fromPath($url); - $f = $filter; - if (isset($optional)) { - $f = Filter::matchAll($filter, $optional); - } - return $url->setQueryString($f->toQueryString()); -} $this->baseFilter = isset($this->baseFilter) ? $this->baseFilter : null; -$stats = $stats->fetchRow(); +// don't fetch rows until they are actually needed to improve dashlet performance +if (!$stats instanceof stdClass) { + $stats = $stats->fetchRow(); +} + $selfUrl = 'monitoring/list/hosts'; $currentUrl = Url::fromRequest()->getRelativeUrl(); -?><h1 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?>> +?> <?= $this->qlink( sprintf($this->translatePlural('%u Host', '%u Hosts', $stats->hosts_total), $stats->hosts_total), $selfUrl, @@ -31,7 +27,7 @@ $currentUrl = Url::fromRequest()->getRelativeUrl(); <span class="state ok<?= $currentUrl === Url::fromPath($selfUrl, array('host_state' => 0))->getRelativeUrl() ? ' active' : ''; ?>"> <?= $this->qlink( $stats->hosts_up, - urlAddFilterOptional( + Url::urlAddFilterOptional( $selfUrl, Filter::where('host_state', 0), $this->baseFilter @@ -54,7 +50,7 @@ $currentUrl = Url::fromRequest()->getRelativeUrl(); <span class="state critical<?= $currentUrl === Url::fromPath($selfUrl, array('host_state' => 1, 'host_unhandled' => 1))->getRelativeUrl() ? ' active' : ''; ?>"> <?= $this->qlink( $stats->hosts_down_unhandled, - urlAddFilterOptional( + Url::urlAddFilterOptional( $selfUrl, Filter::matchAll(Filter::where('host_state', 1), Filter::where('host_unhandled', 1)), $this->baseFilter @@ -75,7 +71,7 @@ $currentUrl = Url::fromRequest()->getRelativeUrl(); <span class="state handled critical<?= $currentUrl === Url::fromPath($selfUrl, array('host_state' => 1, 'host_unhandled' =>0))->getRelativeUrl() ? ' active' : ''; ?>"> <?= $this->qlink( $stats->hosts_down_handled, - urlAddFilterOptional( + Url::urlAddFilterOptional( $selfUrl, Filter::matchAll(Filter::where('host_state', 1), Filter::where('host_unhandled', 0)), $this->baseFilter @@ -101,7 +97,7 @@ $currentUrl = Url::fromRequest()->getRelativeUrl(); <span class="state unknown<?= $currentUrl === Url::fromPath($selfUrl, array('host_state' => 2, 'host_unhandled' => 1))->getRelativeUrl() ? ' active' : ''; ?>"> <?= $this->qlink( $stats->hosts_unreachable_unhandled, - urlAddFilterOptional( + Url::urlAddFilterOptional( $selfUrl, Filter::matchAll(Filter::where('host_state', 2), Filter::where('host_unhandled', 1)), $this->baseFilter @@ -122,7 +118,7 @@ $currentUrl = Url::fromRequest()->getRelativeUrl(); <span class="state handled unknown<?= $currentUrl === Url::fromPath($selfUrl, array('host_state' => 2, 'host_unhandled' => 0))->getRelativeUrl() ? ' active' : '' ?>"> <?= $this->qlink( $stats->hosts_unreachable_handled, - urlAddFilterOptional( + Url::urlAddFilterOptional( $selfUrl, Filter::matchAll(Filter::where('host_state', 2), Filter::where('host_unhandled', 0)), $this->baseFilter @@ -148,7 +144,7 @@ $currentUrl = Url::fromRequest()->getRelativeUrl(); <span class="state pending<?= $currentUrl === Url::fromPath($selfUrl, array('host_state' => 99))->getRelativeUrl() ? ' active' : ''; ?>"> <?= $this->qlink( $stats->hosts_pending, - urlAddFilterOptional( + Url::urlAddFilterOptional( $selfUrl, Filter::where('host_state', 99), $this->baseFilter @@ -166,4 +162,3 @@ $currentUrl = Url::fromRequest()->getRelativeUrl(); </span> <?php endif; ?> </span> -</h1> diff --git a/modules/monitoring/application/views/scripts/list/components/servicesummary.phtml b/modules/monitoring/application/views/scripts/list/components/servicesummary.phtml index 9fd798a0d..1f401004d 100644 --- a/modules/monitoring/application/views/scripts/list/components/servicesummary.phtml +++ b/modules/monitoring/application/views/scripts/list/components/servicesummary.phtml @@ -4,21 +4,16 @@ use Icinga\Data\Filter\Filter; use Icinga\Web\Url; use Icinga\Module\Monitoring\Object\Service; -function urlAddFilterOptional($url, $filter, $optional) { - $url = Url::fromPath($url); - $f = $filter; - if (isset($optional)) { - $f = Filter::matchAll($filter, $optional); - } - return $url->setQueryString($f->toQueryString()); -} $this->baseFilter = isset($this->baseFilter) ? $this->baseFilter : null; -$stats = $stats->fetchRow(); +// don't fetch rows until they are actually needed, to improve dashlet performance +if (!$stats instanceof stdClass) { + $stats = $stats->fetchRow(); +}; $selfUrl = 'monitoring/list/services'; $currentUrl = Url::fromRequest()->getRelativeUrl(); -?><h1 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?>> -<?= $this->qlink( + +echo $this->qlink( sprintf($this->translatePlural( '%u Service', '%u Services', $stats->services_total), $stats->services_total @@ -36,7 +31,7 @@ $currentUrl = Url::fromRequest()->getRelativeUrl(); <?= $this->qlink( $stats->services_ok, - urlAddFilterOptional($selfUrl, Filter::where('service_state', 0), $this->baseFilter), + Url::urlAddFilterOptional($selfUrl, Filter::where('service_state', 0), $this->baseFilter), null, array('title' => sprintf( $this->translatePlural( @@ -81,7 +76,7 @@ foreach (array(2 => 'critical', 3 => 'unknown', 1 => 'warning') as $stateId => $ echo $this->qlink( $stats->$unhandled, - urlAddFilterOptional($selfUrl, $paramsUnhandled, $this->baseFilter), + Url::urlAddFilterOptional($selfUrl, $paramsUnhandled, $this->baseFilter), null, array('title' => sprintf( $this->translatePlural( @@ -106,7 +101,7 @@ foreach (array(2 => 'critical', 3 => 'unknown', 1 => 'warning') as $stateId => $ } echo $this->qlink( $stats->$handled, - urlAddFilterOptional($selfUrl, $paramsHandled, $this->baseFilter), + Url::urlAddFilterOptional($selfUrl, $paramsHandled, $this->baseFilter), null, array('title' => sprintf( $this->translatePlural( @@ -130,7 +125,7 @@ foreach (array(2 => 'critical', 3 => 'unknown', 1 => 'warning') as $stateId => $ <span class="state pending<?= $currentUrl === Url::fromPath($selfUrl, array('service_state' => 99))->getRelativeUrl() ? ' active' : ''; ?>"> <?= $this->qlink( $stats->services_pending, - urlAddFilterOptional($selfUrl, Filter::where('service_state', 99), $this->baseFilter), + Url::urlAddFilterOptional($selfUrl, Filter::where('service_state', 99), $this->baseFilter), null, array('title' => sprintf( $this->translatePlural( @@ -144,4 +139,3 @@ foreach (array(2 => 'critical', 3 => 'unknown', 1 => 'warning') as $stateId => $ </span> <?php endif ?> </span> -</h1> diff --git a/modules/monitoring/application/views/scripts/list/hosts.phtml b/modules/monitoring/application/views/scripts/list/hosts.phtml index 62ca65121..859f01aec 100644 --- a/modules/monitoring/application/views/scripts/list/hosts.phtml +++ b/modules/monitoring/application/views/scripts/list/hosts.phtml @@ -8,7 +8,9 @@ if (! $this->compact): ?> <?= $this->tabs; ?> <div class="dontprint"> <?= $this->render('list/components/selectioninfo.phtml'); ?> - <?= $this->render('list/components/hostssummary.phtml'); ?> + <h2 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?> + <?= $this->render('list/components/hostssummary.phtml'); ?> + </h2> </div> <?= $this->sortBox; ?> <?= $this->limiter; ?> diff --git a/modules/monitoring/application/views/scripts/list/services.phtml b/modules/monitoring/application/views/scripts/list/services.phtml index d2dfb250a..9b5dd1ec1 100644 --- a/modules/monitoring/application/views/scripts/list/services.phtml +++ b/modules/monitoring/application/views/scripts/list/services.phtml @@ -10,7 +10,9 @@ if (! $this->compact): ?> <?= $this->tabs ?> <div class="dontprint"> <?= $this->render('list/components/selectioninfo.phtml') ?> - <?= $this->render('list/components/servicesummary.phtml') ?> + <h1 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?>> + <?= $this->render('list/components/servicesummary.phtml') ?> + </h1> </div> <?= $this->sortBox ?> <?= $this->limiter ?> diff --git a/modules/monitoring/application/views/scripts/partials/command/object-command-form.phtml b/modules/monitoring/application/views/scripts/partials/command/object-command-form.phtml index ab14b1b2a..095d9a4c4 100644 --- a/modules/monitoring/application/views/scripts/partials/command/object-command-form.phtml +++ b/modules/monitoring/application/views/scripts/partials/command/object-command-form.phtml @@ -1,10 +1,18 @@ +<?php use Icinga\Data\Filter\Filter; ?> + <div class="controls"> <?php if (! $this->compact): ?> <?= $this->tabs; ?> <?php endif ?> <?php if ($object->getType() === $object::TYPE_HOST): ?> <?= $this->render('partials/host/object-header.phtml'); ?> - <?= $this->render('partials/host/servicesummary.phtml'); ?> + <h3 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?>"> + <?php + $this->baseFilter = Filter::where('host', $object->host_name); + $this->stats = $object->stats; + echo $this->render('list/components/servicesummary.phtml'); + ?> + </h3> <?php else: ?> <?= $this->render('partials/service/object-header.phtml'); ?> <hr class="command-separator"> diff --git a/modules/monitoring/application/views/scripts/partials/command/objects-command-form.phtml b/modules/monitoring/application/views/scripts/partials/command/objects-command-form.phtml index 42c6e73cd..6a209e159 100644 --- a/modules/monitoring/application/views/scripts/partials/command/objects-command-form.phtml +++ b/modules/monitoring/application/views/scripts/partials/command/objects-command-form.phtml @@ -1,3 +1,5 @@ +<?php use Icinga\Data\Filter\Filter; ?> + <div class="controls"> <?php if (! $this->compact): ?> @@ -5,10 +7,14 @@ <?php endif ?> <?php if (isset($serviceStates)): ?> - <?= $this->render('list/components/servicesummary.phtml') ?> + <h2 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?> + <?= $this->render('list/components/servicesummary.phtml'); ?> + </h2> <?= $this->render('partials/service/objects-header.phtml'); ?> <?php else: ?> - <?= $this->render('list/components/hostssummary.phtml') ?> + <h2 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?> + <?= $this->render('list/components/hostssummary.phtml') ?> + </h2> <?= $this->render('partials/host/objects-header.phtml'); ?> <?php endif ?> </div> diff --git a/modules/monitoring/application/views/scripts/partials/host/servicesummary.phtml b/modules/monitoring/application/views/scripts/partials/host/servicesummary.phtml deleted file mode 100644 index be146acbe..000000000 --- a/modules/monitoring/application/views/scripts/partials/host/servicesummary.phtml +++ /dev/null @@ -1,150 +0,0 @@ -<?php - -use Icinga\Web\Url; -use Icinga\Module\Monitoring\Object\Service; - -function urlAddFilterOptional($url, $filter, $optional) { - $url = Url::fromPath($url); - $f = $filter; - if (isset($optional)) { - $f = Filter::matchAll($filter, $optional); - } - return $url->setQueryString($f->toQueryString()); -} - -$selfUrl = Url::fromPath('monitoring/list/services', array('host' => $object->host_name)); -?><h2 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?>> -<?php if ($object->stats->services_total): ?> -<?= $this->qlink( - sprintf( - $this->translatePlural( - '%u configured service:', - '%u configured services:', - $object->stats->services_total - ), - $object->stats->services_total - ), - $selfUrl, - null, - array( - 'title' => sprintf( - $this->translatePlural( - 'List all %u service on host %s', - 'List all %u services on host %s', - $object->stats->services_total - ), - $object->stats->services_total, - $object->host_name - ), - 'data-base-target' => '_next' - ) -); ?> -<?php else: ?> -<?= $this->translate('No services configured on this host'); ?> -<?php endif; ?> - -<span class="badges"> -<?php if ($object->stats->services_ok): ?> -<span class="state ok"> - <?= $this->qlink( - $object->stats->services_ok, - $selfUrl, - array('service_state' => 0), - array( - 'title' => sprintf( - $this->translatePlural( - 'List %u service that is currently in state OK on host %s', - 'List %u services which are currently in state OK on host %s', - $object->stats->services_ok - ), - $object->stats->services_ok, - $object->host_name - ), - 'data-base-target' => '_next' - ) - ); ?> -</span> -<?php endif ?> -<?php -foreach (array(2 => 'critical', 3 => 'unknown', 1 => 'warning') as $stateId => $state) { - $pre = 'services_' . $state; - if ($object->stats->$pre) { - $handled = $pre . '_handled'; - $unhandled = $pre . '_unhandled'; - $paramsHandled = array('service_state' => $stateId, 'service_handled' => 1); - $paramsUnhandled = array('service_state' => $stateId, 'service_handled' => 0); - echo '<span class="state ' . $state . ($object->stats->$unhandled ? '' : ' handled') . '">'; - if ($object->stats->$unhandled) { - - echo $this->qlink( - $object->stats->$unhandled, - $selfUrl, - $paramsUnhandled, - array( - 'title' => sprintf( - $this->translatePlural( - 'List %u service that is currently in state %s on host %s', - 'List %u services which are currently in state %s on host %s', - $object->stats->$unhandled - ), - $object->stats->$unhandled, - Service::getStateText($stateId, true), - $object->host_name - ), - 'data-base-target' => '_next' - ) - ); - } - if ($object->stats->$handled) { - if ($object->stats->$unhandled) { - echo '<span class="state handled ' . $state . '">'; - } - echo $this->qlink( - $object->stats->$handled, - $selfUrl, - $paramsHandled, - array( - 'title' => sprintf( - $this->translatePlural( - 'List %u service that is currently in state %s (Acknowledged) on host %s', - 'List %u services which are currently in state %s (Acknowledged) on host %s', - $object->stats->$handled - ), - $object->stats->$handled, - Service::getStateText($stateId, true), - $object->host_name - ), - 'data-base-target' => '_next' - ) - ); - if ($object->stats->$unhandled) { - echo "</span>\n"; - } - } - echo "</span>\n"; - } -} -?> -<?php if ($object->stats->services_pending): ?> -<span class="state pending"> - <?= $this->qlink( - $object->stats->services_pending, - $selfUrl, - array('service_state' => 99), - array( - 'title' => sprintf( - $this->translatePlural( - 'List %u service that is currently in state PENDING on host %s', - 'List %u services which are currently in state PENDING on host %s', - $object->stats->services_pending - ), - $object->stats->services_pending, - $object->host_name - ), - 'data-base-target' => '_next' - ) - ) ?> -</span> -<?php endif ?> -</span> -</h2> diff --git a/modules/monitoring/application/views/scripts/process/info.phtml b/modules/monitoring/application/views/scripts/process/info.phtml deleted file mode 100644 index 85e576116..000000000 --- a/modules/monitoring/application/views/scripts/process/info.phtml +++ /dev/null @@ -1,185 +0,0 @@ -<?php -$rv = $this->runtimeVariables()->create($this->runtimevariables); -$cp = $this->checkPerformance()->create($this->checkperformance); - -if (! $this->compact): ?> -<div class="controls"> - <?= $this->tabs; ?> -</div> -<?php endif ?> - -<div class="content processinfo"> - <div class="boxview"> - - <div class="box left"> - <?= $this->toggleFeaturesForm; ?> - </div> - - <div class="box left"> - <h2><?= $this->translate('Process Info') ?></h2> - <table class="avp"> - <tbody> - <tr> - <th><?= $this->translate('Program Version') ?></th> - <td><?= $this->programStatus->program_version - ? $this->programStatus->program_version - : $this->translate('N/A') ?></td> - </tr> - <tr> - <th><?= $this->translate('Program Start Time') ?></th> - <td><?= $this->formatDateTime($this->programStatus->program_start_time) ?></td> - </tr> - <tr> - <th><?= $this->translate('Last Status Update'); ?></th> - <td><?= $this->timeAgo($this->programStatus->status_update_time); ?></td> - </tr> - <tr> - <th><?= $this->translate('Last External Command Check'); ?></th> - <td><?= $this->timeAgo($this->programStatus->last_command_check); ?></td> - </tr> - <tr> - <th><?= $this->translate('Last Log File Rotation'); ?></th> - <td><?= $this->programStatus->last_log_rotation - ? $this->timeSince($this->programStatus->last_log_rotation) - : $this->translate('N/A') ?></td> - </tr> - <tr> - <th><?= $this->translate('Global Service Event Handler'); ?></th> - <td><?= $this->programStatus->global_service_event_handler - ? $this->programStatus->global_service_event_handler - : $this->translate('N/A'); ?></td> - </tr> - <tr> - <th><?= $this->translate('Global Host Event Handler'); ?></th> - <td><?= $this->programStatus->global_host_event_handler - ? $this->programStatus->global_host_event_handler - : $this->translate('N/A'); ?></td> - </tr> - <tr> - <th><?= $this->translate('Active Endpoint'); ?></th> - <td><?= $this->programStatus->endpoint_name - ? $this->programStatus->endpoint_name - : $this->translate('N/A') ?></td> - </tr> - </tbody> - </table> - <?php if ((bool) $this->programStatus->is_currently_running === true): ?> - <div class="backend-running"> - <?= sprintf( - $this->translate( - '%1$s has been up and running with PID %2$d %3$s', - 'Last format parameter represents the time running' - ), - $this->backendName, - $this->programStatus->process_id, - $this->timeSince($this->programStatus->program_start_time)) ?> - </div> - <?php else: ?> - <div class="backend-not-running"> - <?= sprintf($this->translate('Backend %s is not running'), $this->backendName) ?> - </div> - <?php endif ?> - </div> - - <div class="box left"> - <h2><?= $this->translate('Performance Info') ?></h2> - - <h3><?= $this->translate('Object summaries') ?></h3> - <table class="avp"> - <thead> - <tr> - <th></th> - <th><?= $this->translate('overall') ?></th> - <th><?= $this->translate('scheduled') ?></th> - </tr> - </thead> - <tbody> - <tr> - <td> - <strong><?= $this->translate('Hosts') ?></strong> - </td> - <td> - <?= $rv->total_hosts; ?> - </td> - <td> - <?= $rv->total_scheduled_hosts; ?> - </td> - </tr> - - <tr> - <td> - <strong><?= $this->translate('Services') ?></strong> - </td> - <td> - <?= $rv->total_services; ?> - </td> - <td> - <?= $rv->total_scheduled_services; ?> - </td> - </tr> - - <tr> - <td> - <strong><?= $this->translate('Average services per host') ?></strong> - </td> - <td> - <?= sprintf('%.2f', $rv->average_services_per_host); ?> - </td> - <td> - <?= sprintf('%.2f', $rv->average_scheduled_services_per_host); ?> - </td> - </tr> - </tbody> - </table> - - <h3><?= $this->translate('Active checks') ?></h3> - <table class="avp"> - <thead> - <tr> - <th></th> - <th></th> - <th><?= $this->translate('Latency') ?></th> - <th><?= $this->translate('Execution time') ?></th> - </tr> - </thead> - <tbody> - <tr> - <td> - <strong><?= $this->translate('Host Checks') ?></strong> - </td> - <td><?= $cp->host_active_count; ?></td> - <td><?= sprintf('%.3f', $cp->host_active_latency_avg); ?>s</td> - <td><?= sprintf('%.3f', $cp->host_active_execution_avg); ?>s</td> - </tr> - <tr> - <td> - <strong><?= $this->translate('Service Checks') ?></strong> - </td> - <td><?= $cp->service_active_count; ?></td> - <td><?= sprintf('%.3f', $cp->service_active_latency_avg); ?>s</td> - <td><?= sprintf('%.3f', $cp->service_active_execution_avg); ?>s</td> - </tr> - </tbody> - </table> - - <h3><?= $this->translate('Passive checks') ?></h3> - <table class="avp"> - <tbody> - <tr> - <td> - <strong><?= $this->translate('Host Checks') ?></strong> - </td> - <td><?= $cp->host_passive_count; ?></td> - </tr> - <tr> - <td> - <strong><?= $this->translate('Service Checks') ?></strong> - </td> - <td><?= $cp->service_passive_count; ?></td> - </tr> - </tbody> - </table> - </div> - - </div> -</div> diff --git a/modules/monitoring/application/views/scripts/services/show.phtml b/modules/monitoring/application/views/scripts/services/show.phtml index d2ad21bca..be8cf5a8b 100644 --- a/modules/monitoring/application/views/scripts/services/show.phtml +++ b/modules/monitoring/application/views/scripts/services/show.phtml @@ -4,7 +4,10 @@ <?= $tabs; ?> <?php endif ?> - <?= $this->render('list/components/servicesummary.phtml') ?> + + <h2 class="tinystatesummary" <?= $this->compact ? ' data-base-target="col1"' : ''; ?> + <?= $this->render('list/components/servicesummary.phtml') ?> + </h2> <?= $this->render('partials/service/objects-header.phtml'); ?> </div> diff --git a/modules/monitoring/configuration.php b/modules/monitoring/configuration.php index c68ef6522..2d61274ec 100644 --- a/modules/monitoring/configuration.php +++ b/modules/monitoring/configuration.php @@ -221,13 +221,13 @@ $section->add($this->translate('Alert Summary'), array( */ $section = $this->menuSection($this->translate('System')); $section->add($this->translate('Monitoring Health'), array( - 'url' => 'monitoring/process/info', + 'url' => 'monitoring/health/info', 'priority' => 720, 'renderer' => 'Icinga\Module\Monitoring\Web\Menu\BackendAvailabilityMenuItemRenderer' )); /* - * Dashboard + * Current Incidents */ $dashboard = $this->dashboard($this->translate('Current Incidents')); $dashboard->add( @@ -243,6 +243,103 @@ $dashboard->add( 'monitoring/list/hosts?host_problem=1&sort=host_severity' ); +/* + * Overview + */ +$dashboard = $this->dashboard($this->translate('Overview')); +$dashboard->add( + $this->translate('Service Grid'), + 'monitoring/list/servicegrid?limit=15,18' +); +$dashboard->add( + $this->translate('Service Groups'), + '/monitoring/list/servicegroups' +); +$dashboard->add( + $this->translate('Host Groups'), + '/monitoring/list/hostgroups' +); + +/* + * Most Overdue + */ +$dashboard = $this->dashboard($this->translate('Overdue')); +$dashboard->add( + $this->translate('Acknowledgements Active For At Least Three Days'), + 'monitoring/list/comments?comment_type=Ack&comment_timestamp<-3 days&sort=comment_timestamp&dir=asc' +); +$dashboard->add( + $this->translate('Downtimes Active For More Than Three Days'), + 'monitoring/list/downtimes?downtime_is_in_effect=1&downtime_scheduled_start<-3%20days&sort=downtime_start&dir=asc' +); + +/* + * Muted Objects + */ +$dashboard = $this->dashboard($this->translate('Muted')); +$dashboard->add( + $this->translate('Disabled Service Notifications'), + 'monitoring/list/services?service_notifications_enabled=0&limit=10' +); +$dashboard->add( + $this->translate('Disabled Host Notifications'), + 'monitoring/list/hosts?host_notifications_enabled=0&limit=10' +); +$dashboard->add( + $this->translate('Disabled Service Checks'), + 'monitoring/list/services?service_active_checks_enabled=0&limit=10' +); +$dashboard->add( + $this->translate('Disabled Host Checks'), + 'monitoring/list/hosts?host_active_checks_enabled=0&limit=10' +); +$dashboard->add( + $this->translate('Acknowledged Problem Services'), + 'monitoring/list/services?service_acknowledgement_type=2&service_problem=1&sort=service_state&limit=10' +); +$dashboard->add( + $this->translate('Acknowledged Problem Hosts'), + 'monitoring/list/hosts?host_acknowledgement_type=2&host_problem=1&sort=host_severity&limit=10' +); + +/* + * Activity Stream + */ +$dashboard = $this->dashboard($this->translate('Activity Stream')); +$dashboard->add( + $this->translate('Recent Events'), + 'monitoring/list/eventhistory?timestamp>=-3%20days&sort=timestamp&dir=desc&limit=8' +); +$dashboard->add( + $this->translate('Recent Hard State Changes'), + 'monitoring/list/eventhistory?timestamp>=-3%20days&type=hard_state&sort=timestamp&dir=desc&limit=8' +); +$dashboard->add( + $this->translate('Recent Notifications'), + 'monitoring/list/eventhistory?timestamp>=-3%20days&type=notify&sort=timestamp&dir=desc&limit=8' +); +$dashboard->add( + $this->translate('Downtimes Recently Started'), + 'monitoring/list/eventhistory?timestamp>=-3%20days&type=dt_start&sort=timestamp&dir=desc&limit=8' +); +$dashboard->add( + $this->translate('Downtimes Recently Ended'), + 'monitoring/list/eventhistory?timestamp>=-3%20days&type=dt_end&sort=timestamp&dir=desc&limit=8' +); + +/* + * Stats + */ +$dashboard = $this->dashboard($this->translate('Stats')); +$dashboard->add( + $this->translate('Check Stats'), + 'monitoring/health/stats' +); +$dashboard->add( + $this->translate('Process Information'), + 'monitoring/health/info' +); + /* * CSS */ diff --git a/modules/monitoring/library/Monitoring/DataView/Hoststatus.php b/modules/monitoring/library/Monitoring/DataView/Hoststatus.php index 05385763c..413f175f1 100644 --- a/modules/monitoring/library/Monitoring/DataView/Hoststatus.php +++ b/modules/monitoring/library/Monitoring/DataView/Hoststatus.php @@ -58,7 +58,8 @@ class HostStatus extends DataView 'host_modified_host_attributes', 'host_severity', 'host_problem', - 'host_ipv4' + 'host_ipv4', + 'host_acknowledgement_type' ); } diff --git a/modules/monitoring/library/Monitoring/DataView/Servicestatus.php b/modules/monitoring/library/Monitoring/DataView/Servicestatus.php index ff68474f1..f12c66535 100644 --- a/modules/monitoring/library/Monitoring/DataView/Servicestatus.php +++ b/modules/monitoring/library/Monitoring/DataView/Servicestatus.php @@ -92,7 +92,8 @@ class ServiceStatus extends DataView 'service_flap_detection_enabled', 'service_flap_detection_enabled_changed', 'service_modified_service_attributes', - 'service_host_name' + 'service_host_name', + 'service_acknowledgement_type' ); } diff --git a/modules/monitoring/library/Monitoring/Object/Macro.php b/modules/monitoring/library/Monitoring/Object/Macro.php index 4a9045b58..0a6f3a8c0 100644 --- a/modules/monitoring/library/Monitoring/Object/Macro.php +++ b/modules/monitoring/library/Monitoring/Object/Macro.php @@ -55,10 +55,10 @@ class Macro */ public static function resolveMacro($macro, $object) { - if (array_key_exists($macro, self::$icingaMacros) && $object->{self::$icingaMacros[$macro]} !== false) { + if (isset(self::$icingaMacros[$macro]) && isset($object->{self::$icingaMacros[$macro]})) { return $object->{self::$icingaMacros[$macro]}; } - if (array_key_exists($macro, $object->customvars)) { + if (isset($object->customvars[$macro])) { return $object->customvars[$macro]; } diff --git a/modules/monitoring/public/css/module.less b/modules/monitoring/public/css/module.less index a239862c3..e27817613 100644 --- a/modules/monitoring/public/css/module.less +++ b/modules/monitoring/public/css/module.less @@ -180,6 +180,10 @@ table.avp { color: @colorMainForeground; } + .badge a[href] { + color: @colorGray; + } + .go-ahead { a, button.link-like { color: #222; diff --git a/public/css/icinga/widgets.less b/public/css/icinga/widgets.less index 95b64429a..c0d9d7b89 100644 --- a/public/css/icinga/widgets.less +++ b/public/css/icinga/widgets.less @@ -234,6 +234,11 @@ li li .badge-container { background-color: @colorInvalid; } +.badge a[href] { + color: @colorGray; + text-decoration: none; +} + #menu nav ul .badge { margin-right: 0em; top: 0.3em;