dolibarr  19.0.0-dev
DolLogsCollector.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2023 Laurent Destailleur <eldy@users.sourceforge.net>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <https://www.gnu.org/licenses/>.
16  */
17 
24 use DebugBar\DataCollector\MessagesCollector;
25 use Psr\Log\LogLevel;
26 
27 //use ReflectionClass;
28 
33 class DolLogsCollector extends MessagesCollector
34 {
38  protected $path;
42  protected $maxnboflines;
43 
47  protected $nboflines;
48 
55  public function __construct($path = null, $name = 'logs')
56  {
57  global $conf;
58 
59  parent::__construct($name);
60 
61  $this->nboflines = 0;
62  $this->maxnboflines = getDolGlobalInt('DEBUGBAR_LOGS_LINES_NUMBER', 250); // High number slows seriously output
63 
64  $this->path = $path ?: $this->getLogsFile();
65  }
66 
72  public function getWidgets()
73  {
74  global $langs;
75 
76  $title = $langs->transnoentities('Logs');
77  $name = $this->getName();
78 
79  return array(
80  "$title" => array(
81  "icon" => "list-alt",
82  "widget" => "PhpDebugBar.Widgets.MessagesWidget",
83  "map" => "$name.messages",
84  "default" => "[]"
85  ),
86  "$title:badge" => array(
87  "map" => "$name.count",
88  "default" => "null"
89  )
90  );
91  }
92 
98  public function collect()
99  {
100  global $conf;
101 
102  $uselogfile = getDolGlobalInt('DEBUGBAR_USE_LOG_FILE');
103 
104  if ($uselogfile) {
105  $this->getStorageLogs($this->path);
106  } else {
107  $log_levels = $this->getLevels();
108 
109  foreach ($conf->logbuffer as $line) {
110  if ($this->nboflines >= $this->maxnboflines) {
111  break;
112  }
113  foreach ($log_levels as $level_key => $level) {
114  if (strpos(strtolower($line), strtolower($level_key)) == 20) {
115  $this->nboflines++;
116  $this->addMessage($line, $level, false);
117  }
118  }
119  }
120  }
121 
122  return parent::collect();
123  }
124 
130  public function getLogsFile()
131  {
132  // default dolibarr log file
133  $path = DOL_DATA_ROOT.'/dolibarr.log';
134  return $path;
135  }
136 
143  public function getStorageLogs($path)
144  {
145  if (!file_exists($path)) {
146  return;
147  }
148 
149  // Load the latest lines
150  $file = implode("", $this->tailFile($path, $this->maxnboflines));
151 
152  foreach ($this->getLogs($file) as $log) {
153  $this->addMessage($log['line'], $log['level'], false);
154  }
155  }
156 
164  protected function tailFile($file, $lines)
165  {
166  $handle = fopen($file, "r");
167  $linecounter = $lines;
168  $pos = -2;
169  $beginning = false;
170  $text = array();
171  while ($linecounter > 0) {
172  $t = " ";
173  while ($t != "\n") {
174  if (fseek($handle, $pos, SEEK_END) == -1) {
175  $beginning = true;
176  break;
177  }
178  $t = fgetc($handle);
179  $pos--;
180  }
181  $linecounter--;
182  if ($beginning) {
183  rewind($handle);
184  }
185  $text[$lines - $linecounter - 1] = fgets($handle);
186  if ($beginning) {
187  break;
188  }
189  }
190  fclose($handle);
191  return array_reverse($text);
192  }
193 
200  public function getLogs($file)
201  {
202  $pattern = "/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.*/";
203  $log_levels = $this->getLevels();
204  preg_match_all($pattern, $file, $matches);
205  $log = array();
206  foreach ($matches as $lines) {
207  foreach ($lines as $line) {
208  foreach ($log_levels as $level_key => $level) {
209  if (strpos(strtolower($line), strtolower($level_key)) == 20) {
210  $log[] = array('level' => $level, 'line' => $line);
211  }
212  }
213  }
214  }
215  $log = array_reverse($log);
216  return $log;
217  }
218 
224  public function getLevels()
225  {
226  $class = new ReflectionClass(new LogLevel());
227  $levels = $class->getConstants();
228  $levels['ERR'] = 'error';
229  $levels['WARN'] = 'warning';
230 
231  return $levels;
232  }
233 }
DolLogsCollector class.
getWidgets()
Return widget settings.
getStorageLogs($path)
Get logs.
__construct($path=null, $name='logs')
Constructor.
getLogs($file)
Search a string for log entries.
getLevels()
Get the log levels from psr/log.
getLogsFile()
Get the path to the logs file.
tailFile($file, $lines)
Get latest file lines.
collect()
Return collected data.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.