]> git.mxchange.org Git - friendica.git/blob - src/Util/Logger/FriendicaIntrospectionProcessor.php
AP: Debug option to deliver via AP first
[friendica.git] / src / Util / Logger / FriendicaIntrospectionProcessor.php
1 <?php
2
3 namespace Friendica\Util\Logger;
4
5 use Monolog\Logger;
6 use Monolog\Processor\ProcessorInterface;
7
8 /**
9  * Injects line/file//function where the log message came from
10  *
11  * Based on the class IntrospectionProcessor without the "class" information
12  * @see IntrospectionProcessor
13  */
14 class FriendicaIntrospectionProcessor implements ProcessorInterface
15 {
16         private $level;
17
18         private $skipStackFramesCount;
19
20         private $skipClassesPartials;
21
22         private $skipFunctions = [
23                 'call_user_func',
24                 'call_user_func_array',
25         ];
26
27         /**
28          * @param string|int $level The minimum logging level at which this Processor will be triggered
29          * @param array $skipClassesPartials An array of classes to skip during logging
30          * @param int $skipStackFramesCount If the logger should use information from other hierarchy levels of the call
31          */
32         public function __construct($level = Logger::DEBUG, $skipClassesPartials = array(), $skipStackFramesCount = 0)
33         {
34                 $this->level = Logger::toMonologLevel($level);
35                 $this->skipClassesPartials = array_merge(array('Monolog\\'), $skipClassesPartials);
36                 $this->skipStackFramesCount = $skipStackFramesCount;
37         }
38
39         public function __invoke(array $record)
40         {
41                 // return if the level is not high enough
42                 if ($record['level'] < $this->level) {
43                         return $record;
44                 }
45
46                 $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
47
48                 $i = 1;
49
50                 while ($this->isTraceClassOrSkippedFunction($trace, $i)) {
51                         $i++;
52                 }
53
54                 $i += $this->skipStackFramesCount;
55
56                 // we should have the call source now
57                 $record['extra'] = array_merge(
58                         $record['extra'],
59                         [
60                                 'file'      => isset($trace[$i - 1]['file']) ? basename($trace[$i - 1]['file']) : null,
61                                 'line'      => isset($trace[$i - 1]['line']) ? $trace[$i - 1]['line'] : null,
62                                 'function'  => isset($trace[$i]['function']) ? $trace[$i]['function'] : null,
63                         ]
64                 );
65
66                 return $record;
67         }
68
69         /**
70          * Checks if the current trace class or function has to be skipped
71          *
72          * @param array $trace The current trace array
73          * @param int   $index The index of the current hierarchy level
74          * @return bool True if the class or function should get skipped, otherwise false
75          */
76         private function isTraceClassOrSkippedFunction(array $trace, $index)
77         {
78                 if (!isset($trace[$index])) {
79                         return false;
80                 }
81
82                 if (isset($trace[$index]['class'])) {
83                         foreach ($this->skipClassesPartials as $part) {
84                                 if (strpos($trace[$index]['class'], $part) !== false) {
85                                         return true;
86                                 }
87                         }
88                 } elseif (in_array($trace[$index]['function'], $this->skipFunctions)) {
89                         return true;
90                 }
91
92                 return false;
93         }
94 }