diff --git a/modules/monitoring/application/controllers/HostController.php b/modules/monitoring/application/controllers/HostController.php
index bb98b2a8f..b0cda11dd 100644
--- a/modules/monitoring/application/controllers/HostController.php
+++ b/modules/monitoring/application/controllers/HostController.php
@@ -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());
diff --git a/modules/monitoring/application/controllers/ListController.php b/modules/monitoring/application/controllers/ListController.php
index ccdb149d4..4bbb39fb5 100644
--- a/modules/monitoring/application/controllers/ListController.php
+++ b/modules/monitoring/application/controllers/ListController.php
@@ -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);
diff --git a/modules/monitoring/application/views/helpers/PluginOutput.php b/modules/monitoring/application/views/helpers/PluginOutput.php
index 1c77b578d..f10e516ff 100644
--- a/modules/monitoring/application/views/helpers/PluginOutput.php
+++ b/modules/monitoring/application/views/helpers/PluginOutput.php
@@ -76,19 +76,31 @@ class Zend_View_Helper_PluginOutput extends Zend_View_Helper_Abstract
'
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('~
]*>~', "\n", $output);
if (preg_match('~<[^>]*["/\'][^>]*>~', $output)) {
// HTML
diff --git a/modules/monitoring/application/views/scripts/list/hosts.phtml b/modules/monitoring/application/views/scripts/list/hosts.phtml
index da00fccc6..e00038bf6 100644
--- a/modules/monitoring/application/views/scripts/list/hosts.phtml
+++ b/modules/monitoring/application/views/scripts/list/hosts.phtml
@@ -82,7 +82,7 @@ if (! $this->compact): ?>
= $this->hostFlags($host) ?>
- = $this->pluginOutput($this->ellipsis($host->host_output, 10000), true) ?>
+ = $this->pluginOutput($this->ellipsis($host->host_output, 10000), true, $host->host_check_command) ?>
addColumns as $col): ?>
= $this->escape($host->$col) ?> |
diff --git a/modules/monitoring/application/views/scripts/list/services.phtml b/modules/monitoring/application/views/scripts/list/services.phtml
index c9f1e855b..25a18781a 100644
--- a/modules/monitoring/application/views/scripts/list/services.phtml
+++ b/modules/monitoring/application/views/scripts/list/services.phtml
@@ -86,7 +86,7 @@ if (! $this->compact): ?>
= $this->perfdata($service->service_perfdata, true, 5) ?>
- = $this->pluginOutput($this->ellipsis($service->service_output, 10000), true) ?>
+ = $this->pluginOutput($this->ellipsis($service->service_output, 10000), true, $service->service_check_command) ?>
addColumns as $col): ?>
diff --git a/modules/monitoring/application/views/scripts/show/components/output.phtml b/modules/monitoring/application/views/scripts/show/components/output.phtml
index e4c0fd0a8..c450319a1 100644
--- a/modules/monitoring/application/views/scripts/show/components/output.phtml
+++ b/modules/monitoring/application/views/scripts/show/components/output.phtml
@@ -1,3 +1,3 @@
= $this->translate('Plugin Output') ?>
-= $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) ?>
diff --git a/modules/monitoring/doc/20-Hooks.md b/modules/monitoring/doc/20-Hooks.md
index 373f7ebea..5d38843d6 100644
--- a/modules/monitoring/doc/20-Hooks.md
+++ b/modules/monitoring/doc/20-Hooks.md
@@ -74,3 +74,88 @@ class Simple extends DetailviewExtensionHook
### How it looks

+
+## Plugin Output Hook
+
+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
+', explode(';', $output));
+ }
+}
+```
+
+**Example hook which is responsible for disk and procs checks:**
+
+```php
+', explode(';', $output));
+ }
+ break;
+ case 'procs':
+ $output = preg_replace('/(\d)+/', '$1', $output);
+ break;
+ }
+
+ return $output;
+ }
+}
+```
diff --git a/modules/monitoring/library/Monitoring/Hook/PluginOutputHook.php b/modules/monitoring/library/Monitoring/Hook/PluginOutputHook.php
new file mode 100644
index 000000000..52ecd0963
--- /dev/null
+++ b/modules/monitoring/library/Monitoring/Hook/PluginOutputHook.php
@@ -0,0 +1,46 @@
+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;
+ }
+}