1<?php 2 3use dokuwiki\Logger; 4 5/** 6 * DokuWiki Plugin logviewer (Admin Component) 7 * 8 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 9 * @author Andreas Gohr <andi@splitbrain.org> 10 */ 11class admin_plugin_logviewer extends DokuWiki_Admin_Plugin 12{ 13 14 protected $facilities; 15 protected $facility; 16 protected $date; 17 18 /** @inheritDoc */ 19 public function forAdminOnly() 20 { 21 return true; 22 } 23 24 /** @inheritDoc */ 25 public function handle() 26 { 27 global $INPUT; 28 29 $this->facilities = $this->getFacilities(); 30 $this->facility = $INPUT->str('facility'); 31 if (!in_array($this->facility, $this->facilities)) { 32 $this->facility = $this->facilities[0]; 33 } 34 35 $this->date = $INPUT->str('date'); 36 if (!preg_match('/^\d\d\d\d-\d\d-\d\d$/', $this->date)) { 37 $this->date = gmdate('Y-m-d'); 38 } 39 } 40 41 /** @inheritDoc */ 42 public function html() 43 { 44 echo '<div id="plugin__logviewer">'; 45 echo $this->locale_xhtml('intro'); 46 $this->displayTabs(); 47 $this->displayLog(); 48 echo '</div>'; 49 } 50 51 /** 52 * Show the navigational tabs and date picker 53 */ 54 protected function displayTabs() 55 { 56 global $ID; 57 58 $form = new dokuwiki\Form\Form(['method' => 'GET']); 59 $form->setHiddenField('do', 'admin'); 60 $form->setHiddenField('page', 'logviewer'); 61 $form->setHiddenField('facility', $this->facility); 62 $form->addTextInput('date', $this->getLang('date')) 63 ->attr('type', 'date')->val($this->date)->addClass('quickselect'); 64 $form->addButton('submit', '>')->attr('type', 'submit'); 65 echo $form->toHTML(); 66 67 echo '<ul class="tabs">'; 68 foreach ($this->facilities as $facility) { 69 echo '<li>'; 70 if ($facility == $this->facility) { 71 echo '<strong>' . hsc($facility) . '</strong>'; 72 } else { 73 $link = wl($ID, 74 ['do' => 'admin', 'page' => 'logviewer', 'date' => $this->date, 'facility' => $facility]); 75 echo '<a href="' . $link . '">' . hsc($facility) . '</a>'; 76 } 77 echo '</li>'; 78 } 79 echo '</ul>'; 80 81 } 82 83 /** 84 * Output the logfile contents 85 */ 86 protected function displayLog() 87 { 88 $logfile = Logger::getInstance($this->facility)->getLogfile($this->date); 89 if (!file_exists($logfile)) { 90 echo $this->locale_xhtml('nolog'); 91 return; 92 } 93 94 // loop through the file an print it 95 echo '<dl>'; 96 $lines = file($logfile); 97 $cnt = count($lines); 98 for ($i = 0; $i < $cnt; $i++) { 99 $line = $lines[$i]; 100 101 if ($line[0] === ' ' && $line[1] === ' ') { 102 // lines indented by two spaces are details, aggregate them 103 echo '<dd>'; 104 while (isset($line[0]) && $line[0] === ' ' && isset($line[1]) && $line[1] === ' ') { 105 echo hsc(substr($line, 2)) . '<br />'; 106 $i++; 107 $line = $lines[$i] ?? ''; 108 } 109 echo '</dd>'; 110 $i -= 1; // rewind the counter 111 } else { 112 // other lines are actual log lines in three parts 113 list($dt, $file, $msg) = sexplode("\t", $line, 3, ''); 114 echo '<dt>'; 115 echo '<span class="datetime">' . hsc($dt) . '</span>'; 116 echo '<span class="log">'; 117 echo '<span class="msg">' . hsc($msg) . '</span>'; 118 echo '<span class="file">' . hsc($file) . '</span>'; 119 echo '</span>'; 120 echo '</dt>'; 121 } 122 } 123 echo '</dl>'; 124 } 125 126 /** 127 * Get the available logging facilities 128 * 129 * @return array 130 */ 131 protected function getFacilities() 132 { 133 global $conf; 134 $conf['logdir']; 135 136 // default facilities first 137 $facilities = [ 138 Logger::LOG_ERROR, 139 Logger::LOG_DEPRECATED, 140 Logger::LOG_DEBUG, 141 ]; 142 143 // add all other dirs 144 $dirs = glob($conf['logdir'] . '/*', GLOB_ONLYDIR); 145 foreach ($dirs as $dir) { 146 $facilities[] = basename($dir); 147 } 148 $facilities = array_unique($facilities); 149 150 return $facilities; 151 } 152 153} 154 155