Merge pull request #3502 from Icinga/feature/plugin-output-hook
Introduce monitoring/PluginOutputHook
This commit is contained in:
commit
658cc72141
|
@ -100,7 +100,8 @@ class HostController extends MonitoredObjectController
|
|||
'service_active_checks_enabled',
|
||||
'service_passive_checks_enabled',
|
||||
'current_check_attempt' => 'service_current_check_attempt',
|
||||
'max_check_attempts' => 'service_max_check_attempts'
|
||||
'max_check_attempts' => 'service_max_check_attempts',
|
||||
'service_check_command'
|
||||
));
|
||||
$this->applyRestriction('monitoring/filter/objects', $query);
|
||||
$this->view->services = $query->where('host_name', $this->object->getName());
|
||||
|
|
|
@ -76,7 +76,8 @@ class ListController extends Controller
|
|||
'host_last_state_change' => $stateChangeColumn,
|
||||
'host_notifications_enabled',
|
||||
'host_active_checks_enabled',
|
||||
'host_passive_checks_enabled'
|
||||
'host_passive_checks_enabled',
|
||||
'host_check_command'
|
||||
), $this->addColumns()));
|
||||
$this->applyRestriction('monitoring/filter/objects', $hosts);
|
||||
|
||||
|
@ -156,7 +157,8 @@ class ListController extends Controller
|
|||
'service_severity',
|
||||
'service_notifications_enabled',
|
||||
'service_active_checks_enabled',
|
||||
'service_passive_checks_enabled'
|
||||
'service_passive_checks_enabled',
|
||||
'service_check_command'
|
||||
), $this->addColumns()));
|
||||
$this->applyRestriction('monitoring/filter/objects', $services);
|
||||
|
||||
|
|
|
@ -76,19 +76,31 @@ class Zend_View_Helper_PluginOutput extends Zend_View_Helper_Abstract
|
|||
'<table style="font-size: 0.75em"'
|
||||
);
|
||||
|
||||
/** @var \Icinga\Module\Monitoring\Web\Helper\PluginOutputHookRenderer */
|
||||
protected $hookRenderer;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->hookRenderer = (new \Icinga\Module\Monitoring\Web\Helper\PluginOutputHookRenderer())->registerHooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Render plugin output
|
||||
*
|
||||
* @param string $output
|
||||
* @param bool $raw
|
||||
* @param string $command Check command
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function pluginOutput($output, $raw = false)
|
||||
public function pluginOutput($output, $raw = false, $command = null)
|
||||
{
|
||||
if (empty($output)) {
|
||||
return '';
|
||||
}
|
||||
if ($command !== null) {
|
||||
$output = $this->hookRenderer->render($command, $output, ! $raw);
|
||||
}
|
||||
$output = preg_replace('~<br[^>]*>~', "\n", $output);
|
||||
if (preg_match('~<[^>]*["/\'][^>]*>~', $output)) {
|
||||
// HTML
|
||||
|
|
|
@ -82,7 +82,7 @@ if (! $this->compact): ?>
|
|||
<?php endif ?>
|
||||
<span class="state-icons"><?= $this->hostFlags($host) ?></span>
|
||||
</div>
|
||||
<p class="overview-plugin-output"><?= $this->pluginOutput($this->ellipsis($host->host_output, 10000), true) ?></p>
|
||||
<p class="overview-plugin-output"><?= $this->pluginOutput($this->ellipsis($host->host_output, 10000), true, $host->host_check_command) ?></p>
|
||||
</td>
|
||||
<?php foreach($this->addColumns as $col): ?>
|
||||
<td><?= $this->escape($host->$col) ?></td>
|
||||
|
|
|
@ -86,7 +86,7 @@ if (! $this->compact): ?>
|
|||
<div class="overview-performance-data">
|
||||
<?= $this->perfdata($service->service_perfdata, true, 5) ?>
|
||||
</div>
|
||||
<p class="overview-plugin-output"><?= $this->pluginOutput($this->ellipsis($service->service_output, 10000), true) ?></p>
|
||||
<p class="overview-plugin-output"><?= $this->pluginOutput($this->ellipsis($service->service_output, 10000), true, $service->service_check_command) ?></p>
|
||||
</div>
|
||||
</td>
|
||||
<?php foreach($this->addColumns as $col): ?>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<h2><?= $this->translate('Plugin Output') ?></h2>
|
||||
<?= $this->pluginOutput($object->output) ?>
|
||||
<?= $this->pluginOutput($object->long_output) ?>
|
||||
<?= $this->pluginOutput($object->output, false, $object->check_command) ?>
|
||||
<?= $this->pluginOutput($object->long_output, false, $object->check_command) ?>
|
||||
|
|
|
@ -74,3 +74,88 @@ class Simple extends DetailviewExtensionHook
|
|||
### How it looks <a id="monitoring-module-hooks-detailviewextension-how-it-looks"></a>
|
||||
|
||||
![Screenshot](img/hooks-detailviewextension-01.png)
|
||||
|
||||
## Plugin Output Hook <a id="monitoring-module-hooks-pluginoutput"></a>
|
||||
|
||||
The Plugin Output Hook allows you to rewrite the plugin output based on check commands. You have to implement the
|
||||
following methods:
|
||||
|
||||
* `getCommands()`
|
||||
* and `render()`
|
||||
|
||||
With `getCommands()` you specify for which commands the provided hook is responsible for. You may return a single
|
||||
command as string or a list of commands as array. If you want your hook to be responsible for every command, you have to
|
||||
specify the `*`.
|
||||
|
||||
In `render()` you rewrite the plugin output based on check commands. The parameter `$command` specifies the check
|
||||
command of the host or service and `$output` specifies the plugin output. The parameter `$detail` tells you
|
||||
whether the output is requested from the detail area of the host or service.
|
||||
|
||||
Do not use complex logic for rewriting plugin output in list views because of the performance impact!
|
||||
|
||||
You have to return the rewritten plugin output as string. It is also possible to return a HTML string here.
|
||||
Please refer to `\Icinga\Module\Monitoring\Web\Helper\PluginOutputPurifier` for a list of allowed tags.
|
||||
|
||||
Please also have a look at the following examples.
|
||||
|
||||
**Example hook which is responsible for disk checks:**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Example\ProvidedHook\Monitoring;
|
||||
|
||||
use Icinga\Module\Monitoring\Hook\PluginOutputHook;
|
||||
|
||||
class PluginOutput extends PluginOutputHook
|
||||
{
|
||||
public function getCommands()
|
||||
{
|
||||
return ['disk'];
|
||||
}
|
||||
|
||||
public function render($command, $output, $detail)
|
||||
{
|
||||
if (! $detail) {
|
||||
// Don't rewrite plugin output in list views
|
||||
return $output;
|
||||
}
|
||||
return implode('<br>', explode(';', $output));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Example hook which is responsible for disk and procs checks:**
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace Icinga\Module\Example\ProvidedHook\Monitoring;
|
||||
|
||||
use Icinga\Module\Monitoring\Hook\PluginOutputHook;
|
||||
|
||||
class PluginOutput extends PluginOutputHook
|
||||
{
|
||||
public function getCommands()
|
||||
{
|
||||
return ['disk', 'procs'];
|
||||
}
|
||||
|
||||
public function render($command, $output, $detail)
|
||||
{
|
||||
switch ($command) {
|
||||
case 'disk':
|
||||
if ($detail) {
|
||||
// Only rewrite plugin output in the detail area
|
||||
$output = implode('<br>', explode(';', $output));
|
||||
}
|
||||
break;
|
||||
case 'procs':
|
||||
$output = preg_replace('/(\d)+/', '<b>$1</b>', $output);
|
||||
break;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
<?php
|
||||
/* Icinga Web 2 | (c) 2018 Icinga Development Team | GPLv2+ */
|
||||
|
||||
namespace Icinga\Module\Monitoring\Hook;
|
||||
|
||||
/**
|
||||
* Base class for plugin output hooks
|
||||
*
|
||||
* The Plugin Output Hook allows you to rewrite the plugin output based on check commands.
|
||||
* You have to implement the following methods:
|
||||
* * {@link getCommands()}
|
||||
* * and {@link render()}
|
||||
*/
|
||||
abstract class PluginOutputHook
|
||||
{
|
||||
/**
|
||||
* Get the command or list of commands the hook is responsible for
|
||||
*
|
||||
* With this method you specify for which commands the provided hook is responsible for. You may return a single
|
||||
* command as string or a list of commands as array.
|
||||
* If you want your hook to be responsible for every command, you have to return the asterisk `'*'`.
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
abstract public function getCommands();
|
||||
|
||||
/**
|
||||
* Render the given plugin output based on the specified check command
|
||||
*
|
||||
* With this method you rewrite the plugin output based on check commands. The parameter `$command` specifies the
|
||||
* check command of the host or service and `$output` specifies the plugin output. The parameter `$detail` tells you
|
||||
* whether the output is requested from the detail area of the host or service.
|
||||
*
|
||||
* Do not use complex logic for rewriting plugin output in list views because of the performance impact!
|
||||
*
|
||||
* You have to return the rewritten plugin output as string. It is also possible to return a HTML string here.
|
||||
* Please refer to {@link \Icinga\Module\Monitoring\Web\Helper\PluginOutputPurifier} for a list of allowed tags.
|
||||
*
|
||||
* @param string $command Check command
|
||||
* @param string $output Plugin output
|
||||
* @param bool $detail Whether the output is requested from the detail area
|
||||
*
|
||||
* @return string Rewritten plugin output
|
||||
*/
|
||||
abstract public function render($command, $output, $detail);
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
<?php
|
||||
/* Icinga Web 2 | (c) 2018 Icinga Development Team | GPLv2+ */
|
||||
|
||||
namespace Icinga\Module\Monitoring\Web\Helper;
|
||||
|
||||
use Icinga\Application\Logger;
|
||||
use Icinga\Web\Hook;
|
||||
|
||||
/**
|
||||
* Renderer for plugin output based on hooks
|
||||
*/
|
||||
class PluginOutputHookRenderer
|
||||
{
|
||||
/** @var array */
|
||||
protected $commandMap = [];
|
||||
|
||||
/**
|
||||
* Register PluginOutput hooks
|
||||
*
|
||||
* Map PluginOutput hooks to their responsible commands.
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function registerHooks()
|
||||
{
|
||||
if (! Hook::has('monitoring/PluginOutput')) {
|
||||
return $this;
|
||||
}
|
||||
|
||||
foreach (Hook::all('monitoring/PluginOutput') as $hook) {
|
||||
/** @var \Icinga\Module\Monitoring\Hook\PluginOutputHook $hook */
|
||||
try {
|
||||
$commands = $hook->getCommands();
|
||||
} catch (\Exception $e) {
|
||||
Logger::error(
|
||||
'Failed to get applicable commands from hook "%s". An error occurred: %s',
|
||||
get_class($hook),
|
||||
$e
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (! is_array($commands)) {
|
||||
$commands = [$commands];
|
||||
}
|
||||
|
||||
foreach ($commands as $command) {
|
||||
if (! isset($this->commandMap[$command])) {
|
||||
$this->commandMap[$command] = [];
|
||||
}
|
||||
|
||||
$this->commandMap[$command][] = $hook;
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function renderCommand($command, $output, $detail)
|
||||
{
|
||||
if (isset($this->commandMap[$command])) {
|
||||
foreach ($this->commandMap[$command] as $hook) {
|
||||
/** @var \Icinga\Module\Monitoring\Hook\PluginOutputHook $hook */
|
||||
|
||||
try {
|
||||
$output = $hook->render($command, $output, $detail);
|
||||
} catch (\Exception $e) {
|
||||
Logger::error(
|
||||
'Failed to render plugin output from hook "%s". An error occurred: %s',
|
||||
get_class($hook),
|
||||
$e
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the given plugin output based on the specified check command
|
||||
*
|
||||
* Traverse all hooks which are responsible for the specified check command and call their `render()` methods.
|
||||
*
|
||||
* @param string $command Check command
|
||||
* @param string $output Plugin output
|
||||
* @param bool $detail Whether the output is requested from the detail area
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render($command, $output, $detail)
|
||||
{
|
||||
if (empty($this->commandMap)) {
|
||||
return $output;
|
||||
}
|
||||
|
||||
$output = $this->renderCommand('*', $output, $detail);
|
||||
$output = $this->renderCommand($command, $output, $detail);
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue