Resolve templates' macros on demand

refs #5
This commit is contained in:
Alexander A. Klimov 2017-10-06 17:27:50 +02:00
parent aba61645f8
commit eacec58b22
6 changed files with 107 additions and 101 deletions

View file

@ -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)) {

View file

@ -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;
}
}

View file

@ -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;
}
}

View file

@ -158,7 +158,7 @@ abstract class Graphs extends AbstractWidget
foreach ($templates as $templateName => $template) {
if ($this->designedForMyMonitoredObjectType($template)
&& $template->getCheckCommand() === $checkCommand) {
$charts = $template->getCharts(static::getMetricsDataSource(), $filter);
$charts = $template->getCharts(static::getMetricsDataSource(), $filter, $this->checkCommand);
if (! empty($charts)) {
$result[] = $div;

View file

@ -43,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()

View file

@ -52,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;
}
}