diff --git a/application/controllers/GraphController.php b/application/controllers/GraphController.php index a4080d5..3585455 100644 --- a/application/controllers/GraphController.php +++ b/application/controllers/GraphController.php @@ -49,7 +49,7 @@ class GraphController extends MonitoringAwareController public function hostAction() { $host = $this->applyMonitoringRestriction( - $this->backend->select()->from('hoststatus', ['host_name']) + $this->backend->select()->from('hoststatus', ['host_check_command']) ) ->where('host_name', $this->filterParams->getRequired('host.name')) ->limit(1) // just to be sure to save a few CPU cycles @@ -59,13 +59,13 @@ class GraphController extends MonitoringAwareController throw new HttpNotFoundException('%s', $this->translate('No such host')); } - $this->supplyImage(); + $this->supplyImage($host->host_check_command); } public function serviceAction() { $service = $this->applyMonitoringRestriction( - $this->backend->select()->from('servicestatus', ['host_name', 'service_description']) + $this->backend->select()->from('servicestatus', ['service_check_command']) ) ->where('host_name', $this->filterParams->getRequired('host.name')) ->where('service_description', $this->filterParams->getRequired('service.name')) @@ -76,13 +76,15 @@ class GraphController extends MonitoringAwareController throw new HttpNotFoundException('%s', $this->translate('No such service')); } - $this->supplyImage(); + $this->supplyImage($service->service_check_command); } /** * Do all monitored object type independend actions + * + * @param string $checkCommand The check command of the monitored object we supply an image for */ - protected function supplyImage() + protected function supplyImage($checkCommand) { $templates = $this->getAllTemplates()->getTemplates(); if (! isset($templates[$this->graphParams['template']])) { @@ -91,7 +93,8 @@ class GraphController extends MonitoringAwareController $charts = $templates[$this->graphParams['template']]->getCharts( static::getMetricsDataSource(), - array_map('rawurldecode', $this->filterParams->toArray(false)) + array_map('rawurldecode', $this->filterParams->toArray(false)), + $checkCommand ); switch (count($charts)) { diff --git a/application/controllers/ListController.php b/application/controllers/ListController.php index f881342..6dfcb7e 100644 --- a/application/controllers/ListController.php +++ b/application/controllers/ListController.php @@ -29,7 +29,12 @@ class ListController extends MonitoringAwareController ); $this->view->hosts = $hosts = $this->applyMonitoringRestriction( - $this->backend->select()->from('hoststatus', ['host_name', 'host_display_name', 'host_check_command']) + $this->backend->select()->from('hoststatus', [ + 'host_name', + 'host_display_name', + 'host_check_command', + '_host_check_command' + ]) ); $this->filterQuery($hosts); @@ -55,7 +60,8 @@ class ListController extends MonitoringAwareController 'host_display_name', 'service_description', 'service_display_name', - 'service_check_command' + 'service_check_command', + '_service_check_command' ]) ); diff --git a/application/views/scripts/list/hosts.phtml b/application/views/scripts/list/hosts.phtml index 7809718..8b9fa41 100644 --- a/application/views/scripts/list/hosts.phtml +++ b/application/views/scripts/list/hosts.phtml @@ -39,7 +39,11 @@ if ($filterEditor->getFilter()->isEmpty()) { ) . ''; } - echo (new Host($host->host_name, $host->host_check_command)) + echo (new Host( + $host->host_name, + $host->host_check_command, + $host->_host_check_command + )) ->setCompact() ->handleRequest(); diff --git a/application/views/scripts/list/services.phtml b/application/views/scripts/list/services.phtml index 0b42b12..3a0e815 100644 --- a/application/views/scripts/list/services.phtml +++ b/application/views/scripts/list/services.phtml @@ -49,7 +49,12 @@ if ($filterEditor->getFilter()->isEmpty()) { ) . ''; } - echo (new Service($service->host_name, $service->service_description, $service->service_check_command)) + echo (new Service( + $service->host_name, + $service->service_description, + $service->service_check_command, + $service->_service_check_command + )) ->setCompact() ->handleRequest(); } diff --git a/library/Graphite/Graphing/Template.php b/library/Graphite/Graphing/Template.php index a86fd5e..9b00518 100644 --- a/library/Graphite/Graphing/Template.php +++ b/library/Graphite/Graphing/Template.php @@ -2,10 +2,27 @@ namespace Icinga\Module\Graphite\Graphing; +use Icinga\Application\Config; +use Icinga\Exception\ConfigurationError; use Icinga\Module\Graphite\Util\MacroTemplate; +use InvalidArgumentException; class Template { + /** + * The configured icinga.graphite_writer_host_name_template + * + * @var MacroTemplate + */ + protected static $hostNameTemplate; + + /** + * The configured icinga.graphite_writer_service_name_template + * + * @var MacroTemplate + */ + protected static $serviceNameTemplate; + /** * All curves to show in a chart by name with Graphite Web metric filters and Graphite functions * @@ -44,14 +61,26 @@ class Template * * @param MetricsDataSource $dataSource * @param string[] $filter + * @param string $checkCommand The check command of the monitored object we fetch charts for * * @return Chart[] */ - public function getCharts(MetricsDataSource $dataSource, array $filter) + public function getCharts(MetricsDataSource $dataSource, array $filter, $checkCommand) { $metrics = []; foreach ($this->curves as $curveName => $curve) { - $query = $dataSource->select()->from($curve[0]); + $query = $dataSource->select()->from($curve[0]->resolve([ + 'host_name_template' => static::getHostNameTemplate()->resolve([ + 'host.check_command' => $checkCommand, + '' => '$$' + ]), + 'service_name_template' => static::getServiceNameTemplate()->resolve([ + 'service.check_command' => $checkCommand, + '' => '$$' + ]), + '' => '$$' + ])); + foreach ($filter as $key => $value) { $query->where($key, $value); } @@ -204,4 +233,66 @@ class Template return $this; } + + /** + * Get {@link hostNameTemplate} + * + * @return MacroTemplate + * + * @throws ConfigurationError If the configuration is invalid + */ + protected static function getHostNameTemplate() + { + if (static::$hostNameTemplate === null) { + $config = Config::module('graphite'); + $template = $config->get( + 'icinga', + 'graphite_writer_host_name_template', + 'icinga2.$host.name$.host.$host.check_command$' + ); + + try { + static::$hostNameTemplate = new MacroTemplate($template); + } catch (InvalidArgumentException $e) { + throw new ConfigurationError( + 'Bad icinga.graphite_writer_host_name_template in "%s": %s', + $config->getConfigFile(), + $e->getMessage() + ); + } + } + + return static::$hostNameTemplate; + } + + /** + * Get {@link serviceNameTemplate} + * + * @return MacroTemplate + * + * @throws ConfigurationError If the configuration is invalid + */ + protected static function getServiceNameTemplate() + { + if (static::$serviceNameTemplate === null) { + $config = Config::module('graphite'); + $template = $config->get( + 'icinga', + 'graphite_writer_service_name_template', + 'icinga2.$host.name$.services.$service.name$.$service.check_command$' + ); + + try { + static::$serviceNameTemplate = new MacroTemplate($template); + } catch (InvalidArgumentException $e) { + throw new ConfigurationError( + 'Bad icinga.graphite_writer_service_name_template in "%s": %s', + $config->getConfigFile(), + $e->getMessage() + ); + } + } + + return static::$serviceNameTemplate; + } } diff --git a/library/Graphite/Graphing/Templates.php b/library/Graphite/Graphing/Templates.php index ff80ea0..5fc2198 100644 --- a/library/Graphite/Graphing/Templates.php +++ b/library/Graphite/Graphing/Templates.php @@ -24,20 +24,6 @@ class Templates */ protected $templates = []; - /** - * The configured icinga.graphite_writer_host_name_template - * - * @var MacroTemplate - */ - protected $hostNameTemplate; - - /** - * The configured icinga.graphite_writer_service_name_template - * - * @var MacroTemplate - */ - protected $serviceNameTemplate; - /** * Constructor */ @@ -175,18 +161,6 @@ class Templates ); } - $curves[$curve][0] = new MacroTemplate($curves[$curve][0]->resolve([ - 'host_name_template' => $this->getHostNameTemplate()->resolve([ - 'host.check_command' => $checkCommand, - '' => '$$' - ]), - 'service_name_template' => $this->getServiceNameTemplate()->resolve([ - 'service.check_command' => $checkCommand, - '' => '$$' - ]), - '' => '$$' - ])); - if (isset($template['functions'][$curve])) { try { $curves[$curve][1] = new MacroTemplate($template['functions'][$curve]); @@ -284,66 +258,4 @@ class Templates { return $this->templates; } - - /** - * Get {@link hostNameTemplate} - * - * @return MacroTemplate - * - * @throws ConfigurationError If the configuration is invalid - */ - protected function getHostNameTemplate() - { - if ($this->hostNameTemplate === null) { - $config = Config::module('graphite'); - $template = $config->get( - 'icinga', - 'graphite_writer_host_name_template', - 'icinga2.$host.name$.host.$host.check_command$' - ); - - try { - $this->hostNameTemplate = new MacroTemplate($template); - } catch (InvalidArgumentException $e) { - throw new ConfigurationError( - 'Bad icinga.graphite_writer_host_name_template in "%s": %s', - $config->getConfigFile(), - $e->getMessage() - ); - } - } - - return $this->hostNameTemplate; - } - - /** - * Get {@link serviceNameTemplate} - * - * @return MacroTemplate - * - * @throws ConfigurationError If the configuration is invalid - */ - protected function getServiceNameTemplate() - { - if ($this->serviceNameTemplate === null) { - $config = Config::module('graphite'); - $template = $config->get( - 'icinga', - 'graphite_writer_service_name_template', - 'icinga2.$host.name$.services.$service.name$.$service.check_command$' - ); - - try { - $this->serviceNameTemplate = new MacroTemplate($template); - } catch (InvalidArgumentException $e) { - throw new ConfigurationError( - 'Bad icinga.graphite_writer_service_name_template in "%s": %s', - $config->getConfigFile(), - $e->getMessage() - ); - } - } - - return $this->serviceNameTemplate; - } } diff --git a/library/Graphite/Util/MacroTemplate.php b/library/Graphite/Util/MacroTemplate.php index cf54ab3..cf27aaa 100644 --- a/library/Graphite/Util/MacroTemplate.php +++ b/library/Graphite/Util/MacroTemplate.php @@ -100,10 +100,24 @@ class MacroTemplate return false; } + $macro = false; + $macros = []; + $currentCapturedSubPatternIndex = 0; + + foreach ($this->template as $part) { + if ($macro && ! isset($macros[$part])) { + $macros[$part] = ++$currentCapturedSubPatternIndex; + } + + $macro = ! $macro; + } + + $macros = array_flip($macros); + $result = []; foreach ($matches as $index => $match) { - if (! is_int($index)) { - $result[hex2bin(explode('_', $index, 2)[1])] = $match; + if ($index > 0) { + $result[$macros[$index]] = $match; } } @@ -174,9 +188,7 @@ class MacroTemplate $result[] = '}'; } else { $macros[$part] = ++$currentCapturedSubPatternIndex; - $result[] = '(?Ps around the images * @@ -83,7 +92,8 @@ abstract class Graphs extends AbstractWidget /** @var Host $object */ return new HostGraphs( $object->getName(), - $object->host_check_command + $object->host_check_command, + $object->_host_check_command ); case 'service': @@ -91,7 +101,8 @@ abstract class Graphs extends AbstractWidget return new ServiceGraphs( $object->getHost()->getName(), $object->getName(), - $object->service_check_command + $object->service_check_command, + $object->_service_check_command ); } } @@ -99,11 +110,14 @@ abstract class Graphs extends AbstractWidget /** * Constructor * - * @param string $checkCommand The check command of the monitored object we display graphs for + * @param string $checkCommand The check command of the monitored object we display graphs for + * @param string|null $obscuredCheckCommand The "real" check command (if any) of the monitored object + * we display graphs for */ - public function __construct($checkCommand) + public function __construct($checkCommand, $obscuredCheckCommand) { $this->checkCommand = $checkCommand; + $this->obscuredCheckCommand = $obscuredCheckCommand; } /** @@ -135,6 +149,7 @@ abstract class Graphs extends AbstractWidget $filter = $this->getMonitoredObjectFilter(); $imageBaseUrl = $this->getImageBaseUrl(); $templates = static::getAllTemplates()->getTemplates(); + $checkCommand = $this->obscuredCheckCommand === null ? $this->checkCommand : $this->obscuredCheckCommand; $classes = $this->classes; $classes[] = 'images'; @@ -142,8 +157,8 @@ abstract class Graphs extends AbstractWidget foreach ($templates as $templateName => $template) { if ($this->designedForMyMonitoredObjectType($template) - && $template->getCheckCommand() === $this->checkCommand) { - $charts = $template->getCharts(static::getMetricsDataSource(), $filter); + && $template->getCheckCommand() === $checkCommand) { + $charts = $template->getCharts(static::getMetricsDataSource(), $filter, $this->checkCommand); if (! empty($charts)) { $result[] = $div; diff --git a/library/Graphite/Web/Widget/Graphs/Host.php b/library/Graphite/Web/Widget/Graphs/Host.php index ee9831c..8e45476 100644 --- a/library/Graphite/Web/Widget/Graphs/Host.php +++ b/library/Graphite/Web/Widget/Graphs/Host.php @@ -18,12 +18,14 @@ class Host extends Graphs /** * Constructor * - * @param string $host The host to render the graphs of - * @param string $checkCommand The check command of the monitored object we display graphs for + * @param string $host The host to render the graphs of + * @param string $checkCommand The check command of the monitored object we display graphs for + * @param string|null $obscuredCheckCommand The "real" check command (if any) of the monitored object + * we display graphs for */ - public function __construct($host, $checkCommand) + public function __construct($host, $checkCommand, $obscuredCheckCommand) { - parent::__construct($checkCommand); + parent::__construct($checkCommand, $obscuredCheckCommand); $this->host = $host; } @@ -41,12 +43,12 @@ class Host extends Graphs protected function designedForMyMonitoredObjectType(Template $template) { foreach ($template->getCurves() as $curve) { - if (in_array('service.name', $curve[0]->getMacros())) { - return false; + if (in_array('host_name_template', $curve[0]->getMacros())) { + return true; } } - return true; + return false; } protected function getMonitoredObjectFilter() diff --git a/library/Graphite/Web/Widget/Graphs/Service.php b/library/Graphite/Web/Widget/Graphs/Service.php index a74d1d6..55b049e 100644 --- a/library/Graphite/Web/Widget/Graphs/Service.php +++ b/library/Graphite/Web/Widget/Graphs/Service.php @@ -25,13 +25,15 @@ class Service extends Graphs /** * Constructor * - * @param string $host The host to render the graphs of - * @param string $service The service to render the graphs of - * @param string $checkCommand The check command of the monitored object we display graphs for + * @param string $host The host to render the graphs of + * @param string $service The service to render the graphs of + * @param string $checkCommand The check command of the monitored object we display graphs for + * @param string|null $obscuredCheckCommand The "real" check command (if any) of the monitored object + * we display graphs for */ - public function __construct($host, $service, $checkCommand) + public function __construct($host, $service, $checkCommand, $obscuredCheckCommand) { - parent::__construct($checkCommand); + parent::__construct($checkCommand, $obscuredCheckCommand); $this->host = $host; $this->service = $service; @@ -50,7 +52,7 @@ class Service extends Graphs protected function designedForMyMonitoredObjectType(Template $template) { foreach ($template->getCurves() as $curve) { - if (in_array('service.name', $curve[0]->getMacros())) { + if (in_array('service_name_template', $curve[0]->getMacros())) { return true; } }