Elgg  Version 6.3
Logger.php
Go to the documentation of this file.
1 <?php
2 
3 namespace Elgg;
4 
5 use Elgg\Cli\Application as CliApplication;
10 use Monolog\Handler\ErrorLogHandler;
11 use Monolog\Level;
12 use Monolog\Processor\MemoryPeakUsageProcessor;
13 use Monolog\Processor\MemoryUsageProcessor;
14 use Monolog\Processor\ProcessIdProcessor;
15 use Monolog\Processor\PsrLogMessageProcessor;
16 use Monolog\Processor\WebProcessor;
17 use Psr\Log\LogLevel;
18 use Symfony\Component\Console\Input\InputInterface;
19 use Symfony\Component\Console\Output\OutputInterface;
20 
26 class Logger extends \Monolog\Logger {
27 
28  const CHANNEL = 'ELGG';
29 
30  const OFF = 600; // use highest log level for OFF
31 
36  protected static $elgg_levels = [
37  0 => false,
38  100 => LogLevel::DEBUG,
39  200 => LogLevel::INFO,
40  250 => LogLevel::NOTICE,
41  300 => LogLevel::WARNING,
42  400 => LogLevel::ERROR,
43  500 => LogLevel::CRITICAL,
44  550 => LogLevel::ALERT,
45  600 => LogLevel::EMERGENCY,
46  ];
47 
52  protected static $legacy_levels = [
53  'OFF' => false,
54  'INFO' => LogLevel::INFO,
55  'NOTICE' => LogLevel::NOTICE,
56  'WARNING' => LogLevel::WARNING,
57  'ERROR' => LogLevel::ERROR,
58  ];
59 
63  protected $level;
64 
68  protected $disabled_stack = [];
69 
78  public static function factory(?InputInterface $input = null, ?OutputInterface $output = null) {
79  $logger = new static(self::CHANNEL);
80 
81  if (\Elgg\Application::isCli()) {
82  if (is_null($input) || is_null($output)) {
85 
86  $app = new CliApplication();
87  $app->setup($input, $output);
88  }
89 
90  $handler = new ErrorHandler(
91  $output,
92  \Elgg\Application::getStdErr(),
93  true
94  );
95 
96  $formatter = new ErrorFormatter();
97  $formatter->allowInlineLineBreaks();
98  $formatter->ignoreEmptyContextAndExtra();
99 
100  $handler->setFormatter($formatter);
101 
102  if ($output->isVeryVerbose()) {
103  $handler->pushProcessor(new BacktraceProcessor(Level::Error));
104  }
105  } else {
106  $handler = new ErrorLogHandler();
107 
108  $handler->pushProcessor(new WebProcessor());
109 
110  $formatter = new ElggLogFormatter();
111  $formatter->allowInlineLineBreaks();
112  $formatter->ignoreEmptyContextAndExtra();
113 
114  $handler->setFormatter($formatter);
115 
116  $handler->pushProcessor(new MemoryUsageProcessor());
117  $handler->pushProcessor(new MemoryPeakUsageProcessor());
118  $handler->pushProcessor(new ProcessIdProcessor());
119  $handler->pushProcessor(new BacktraceProcessor(Level::Warning));
120  }
121 
122  $handler->pushProcessor(new PsrLogMessageProcessor());
123 
124  $logger->pushHandler($handler);
125 
126  $logger->setLevel();
127 
128  return $logger;
129  }
130 
138  protected function normalizeLevel($level = null) {
139  if (!is_string($level) || !in_array($level, self::$elgg_levels)) {
140  $level_value = $level;
141  if ($level === false) {
142  $level_value = 'false';
143  }
144 
145  $this->warning("Deprecated in 6.1: Using the log level '{$level_value}' has been deprecated. Use the \Psr\Log\LogLevel constants.");
146  }
147 
148  if (!$level) {
149  return false;
150  }
151 
152  if (array_key_exists($level, self::$legacy_levels)) {
153  $level = self::$legacy_levels[$level];
154  if ($level === false) {
155  // can't array_key_exists for false
156  return 0;
157  }
158  }
159 
160  if (array_key_exists($level, self::$elgg_levels)) {
161  $level = self::$elgg_levels[$level];
162  }
163 
164  if (!in_array($level, self::$elgg_levels)) {
165  $level = false;
166  }
167 
168  return $level;
169  }
170 
179  public function setLevel($level = null) {
180  // TODO: In Elgg 7 we should throw exceptions if level is not a Psr/Log/LogLevel
181 
182  if (!isset($level)) {
183  $php_error_level = error_reporting();
184 
185  $level = LogLevel::CRITICAL;
186 
187  if (($php_error_level & E_NOTICE) == E_NOTICE) {
188  $level = LogLevel::NOTICE;
189  } else if (($php_error_level & E_WARNING) == E_WARNING) {
190  $level = LogLevel::WARNING;
191  } else if (($php_error_level & E_ERROR) == E_ERROR) {
192  $level = LogLevel::ERROR;
193  }
194  }
195 
196  $this->level = $this->normalizeLevel($level);
197  }
198 
207  public function getLevel($severity = true) {
208  if ($severity) {
209  return array_search($this->level, self::$elgg_levels);
210  }
211 
212  return $this->level;
213  }
214 
222  public function isLoggable($level) {
223  $level = $this->normalizeLevel($level);
224 
225  $severity = array_search($level, self::$elgg_levels);
226  if (!$this->getLevel() || $severity < $this->getLevel()) {
227  return false;
228  }
229 
230  return true;
231  }
232 
236  public function log($level, $message, array $context = []): void {
237 
238  $level = $this->normalizeLevel($level);
239 
240  if (!empty($this->disabled_stack)) {
241  // capture to top of stack
242  end($this->disabled_stack);
243  $key = key($this->disabled_stack);
244  $this->disabled_stack[$key][] = [
245  'message' => $message,
246  'level' => $level,
247  ];
248 
249  return;
250  }
251 
252  if (!$this->isLoggable($level)) {
253  return;
254  }
255 
256  parent::log($level, $message, $context);
257  }
258 
262  public function emergency($message, array $context = []): void {
263  $this->log(LogLevel::EMERGENCY, $message, $context);
264  }
265 
269  public function alert($message, array $context = []): void {
270  $this->log(LogLevel::ALERT, $message, $context);
271  }
272 
276  public function critical($message, array $context = []): void {
277  $this->log(LogLevel::CRITICAL, $message, $context);
278  }
279 
283  public function error($message, array $context = []): void {
284  $this->log(LogLevel::ERROR, $message, $context);
285  }
286 
290  public function warning($message, array $context = []): void {
291  $this->log(LogLevel::WARNING, $message, $context);
292  }
293 
297  public function notice($message, array $context = []): void {
298  $this->log(LogLevel::NOTICE, $message, $context);
299  }
300 
304  public function info($message, array $context = []): void {
305  $this->log(LogLevel::INFO, $message, $context);
306  }
307 
311  public function debug($message, array $context = []): void {
312  $this->log(LogLevel::DEBUG, $message, $context);
313  }
314 
323  public function dump($data) {
324  $this->warning('Deprecated in 6.3: ' . __METHOD__ . ' has been deprecated use ->error()');
325 
326  $this->log(LogLevel::ERROR, $data);
327  }
328 
341  public function disable() {
342  $this->disabled_stack[] = [];
343  }
344 
352  public function enable() {
353  return array_pop($this->disabled_stack);
354  }
355 }
$handler
Definition: add.php:7
$context
Definition: add.php:8
if(! $entity instanceof \ElggUser) $data
Definition: attributes.php:13
Handle system and PHP errors.
static getStdOut()
Load console output interface.
static getStdIn()
Load console input interface.
Wrapper for console application.
Definition: Application.php:11
Format errors for console output.
Console handler.
Inject backtrace stack into the record.
Logger.
Definition: Logger.php:26
dump($data)
Dump data to log.
Definition: Logger.php:323
log($level, $message, array $context=[])
{}
Definition: Logger.php:236
notice($message, array $context=[])
{}
Definition: Logger.php:297
normalizeLevel($level=null)
Normalizes legacy string or numeric representation of the level to LogLevel strings.
Definition: Logger.php:138
getLevel($severity=true)
Get the current logging level severity.
Definition: Logger.php:207
emergency($message, array $context=[])
{}
Definition: Logger.php:262
alert($message, array $context=[])
{}
Definition: Logger.php:269
isLoggable($level)
Check if a level is loggable under current logging level.
Definition: Logger.php:222
enable()
Restore logging and get record of log calls (after tests)
Definition: Logger.php:352
debug($message, array $context=[])
{}
Definition: Logger.php:311
error($message, array $context=[])
{}
Definition: Logger.php:283
static factory(?InputInterface $input=null, ?OutputInterface $output=null)
Build a new logger.
Definition: Logger.php:78
critical($message, array $context=[])
{}
Definition: Logger.php:276
info($message, array $context=[])
{}
Definition: Logger.php:304
setLevel($level=null)
Set the logging level.
Definition: Logger.php:179
warning($message, array $context=[])
{}
Definition: Logger.php:290
disable()
Temporarily disable logging and capture logs (before tests)
Definition: Logger.php:341
$output
Definition: download.php:9
$input
Form field view.
Definition: field.php:13
if($container instanceof ElggGroup && $container->guid !=elgg_get_page_owner_guid()) $key
Definition: summary.php:44