summaryrefslogtreecommitdiffstats
path: root/library/Director/StartupLogRenderer.php
diff options
context:
space:
mode:
Diffstat (limited to 'library/Director/StartupLogRenderer.php')
-rw-r--r--library/Director/StartupLogRenderer.php126
1 files changed, 126 insertions, 0 deletions
diff --git a/library/Director/StartupLogRenderer.php b/library/Director/StartupLogRenderer.php
new file mode 100644
index 0000000..bc7b3ea
--- /dev/null
+++ b/library/Director/StartupLogRenderer.php
@@ -0,0 +1,126 @@
+<?php
+
+namespace Icinga\Module\Director;
+
+use ipl\Html\Html;
+use Icinga\Module\Director\Objects\DirectorDeploymentLog;
+use gipfl\IcingaWeb2\Link;
+use ipl\Html\ValidHtml;
+
+class StartupLogRenderer implements ValidHtml
+{
+ /** @var DirectorDeploymentLog */
+ protected $deployment;
+
+ public function __construct(DirectorDeploymentLog $deployment)
+ {
+ $this->deployment = $deployment;
+ }
+
+ public function render()
+ {
+ $deployment = $this->deployment;
+ $log = Html::escape($deployment->get('startup_log'));
+ $lines = array();
+ $severity = 'information';
+ $sevPattern = '/^(debug|notice|information|warning|critical)\/(\w+)/';
+ $settings = new Settings($this->deployment->getConnection());
+ $package = $settings->get('icinga_package_name');
+ $pathPattern = '~(/[\w/]+/api/packages/' . $package . '/[^/]+/)';
+ $filePatternHint = $pathPattern . '([^:]+\.conf)(: (\d+))~';
+ $filePatternDetail = $pathPattern . '([^:]+\.conf)(\((\d+)\))~';
+ $markPattern = null;
+ // len [stage] + 1
+ $markReplace = ' ^';
+
+ foreach (preg_split('/\n/', $log) as $line) {
+ if (preg_match('/^\[([\d\s\:\+\-]+)\]\s/', $line, $m)) {
+ $time = $m[1];
+ // TODO: we might use new DateTime($time) and show a special "timeAgo"
+ // format - but for now this should suffice.
+ $line = substr($line, strpos($line, ']') + 2);
+ } else {
+ $time = null;
+ }
+
+ if (preg_match($sevPattern, $line, $m)) {
+ $severity = $m[1];
+ $line = preg_replace(
+ $sevPattern,
+ '<span class="loglevel \1">\1</span>/<span class="application">\2</span>',
+ $line
+ );
+ }
+
+ if ($markPattern !== null) {
+ $line = preg_replace($markPattern, $markReplace, $line);
+ }
+ $line = preg_replace('/([\^]{2,})/', '<span class="error-hint">\1</span>', $line);
+ $markPattern = null;
+
+ $self = $this;
+ if (preg_match($filePatternHint, $line, $m)) {
+ $line = preg_replace_callback(
+ $filePatternHint,
+ function ($matches) use ($severity, $self) {
+ return $self->logLink($matches, $severity);
+ },
+ $line
+ );
+ $line = preg_replace('/\(in/', "\n (in", $line);
+ $line = preg_replace('/\), new declaration/', "),\n new declaration", $line);
+ } elseif (preg_match($filePatternDetail, $line, $m)) {
+ $markIndent = strlen($m[1]);
+ $markPattern = '/\s{' . $markIndent . '}\^/';
+
+ $line = preg_replace_callback(
+ $filePatternDetail,
+ function ($matches) use ($severity, $self) {
+ return $self->logLink($matches, $severity);
+ },
+ $line
+ );
+ }
+
+ if ($time === null) {
+ $lines[] .= $line;
+ } else {
+ $lines[] .= "[$time] $line";
+ }
+ }
+ return implode("\n", $lines);
+ }
+
+ protected function logLink($match, $severity)
+ {
+ $stageDir = $match[1];
+ $filename = $match[2];
+ $suffix = $match[3];
+ if (preg_match('/(\d+).*/', $suffix, $m)) {
+ $lineNumber = $m[1];
+ } else {
+ $lineNumber = null;
+ }
+
+ $deployment = $this->deployment;
+ $params = array(
+ 'config_checksum' => $deployment->getConfigHexChecksum(),
+ 'deployment_id' => $deployment->get('id'),
+ 'file_path' => $filename,
+ 'backTo' => 'deployment'
+ );
+ if ($lineNumber !== null) {
+ $params['highlight'] = $lineNumber;
+ $params['highlightSeverity'] = $severity;
+ }
+
+ return Link::create(
+ '[stage]/' . $filename,
+ 'director/config/file',
+ $params,
+ [
+ 'title' => $stageDir . $filename
+ ]
+ ) . $suffix;
+ }
+}