]> git.mxchange.org Git - friendica.git/blob - src/Factory/LoggerFactory.php
Summary has to be converted to HTML / Don't use summary when we have the source
[friendica.git] / src / Factory / LoggerFactory.php
1 <?php
2
3 namespace Friendica\Factory;
4
5 use Friendica\Core\Config\Configuration;
6 use Friendica\Core\Logger;
7 use Friendica\Network\HTTPException\InternalServerErrorException;
8 use Friendica\Util\Logger\FriendicaDevelopHandler;
9 use Friendica\Util\Logger\FriendicaIntrospectionProcessor;
10 use Friendica\Util\Logger\WorkerLogger;
11 use Friendica\Util\Profiler;
12 use Monolog;
13 use Psr\Log\LoggerInterface;
14 use Psr\Log\LogLevel;
15
16 /**
17  * A logger factory
18  *
19  * Currently only Monolog is supported
20  */
21 class LoggerFactory
22 {
23         /**
24          * A list of classes, which shouldn't get logged
25          * @var array
26          */
27         private static $ignoreClassList = [
28                 Logger::class,
29                 Profiler::class,
30                 WorkerLogger::class
31         ];
32
33         /**
34          * Creates a new PSR-3 compliant logger instances
35          *
36          * @param string        $channel The channel of the logger instance
37          * @param Configuration $config  The config
38          *
39          * @return LoggerInterface The PSR-3 compliant logger instance
40          */
41         public static function create($channel, Configuration $config)
42         {
43                 $loggerTimeZone = new \DateTimeZone('UTC');
44                 Monolog\Logger::setTimezone($loggerTimeZone);
45
46                 $logger = new Monolog\Logger($channel);
47                 $logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
48                 $logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
49                 $logger->pushProcessor(new Monolog\Processor\UidProcessor());
50                 $logger->pushProcessor(new FriendicaIntrospectionProcessor(LogLevel::DEBUG, self::$ignoreClassList));
51
52                 $debugging = $config->get('system', 'debugging');
53                 $stream    = $config->get('system', 'logfile');
54                 $level     = $config->get('system', 'loglevel');
55
56                 if ($debugging) {
57                         $loglevel = self::mapLegacyConfigDebugLevel((string)$level);
58                         static::addStreamHandler($logger, $stream, $loglevel);
59                 } else {
60                         static::addVoidHandler($logger);
61                 }
62
63                 Logger::init($logger);
64
65                 return $logger;
66         }
67
68         /**
69          * Creates a new PSR-3 compliant develop logger
70          *
71          * If you want to debug only interactions from your IP or the IP of a remote server for federation debug,
72          * you'll use this logger instance for the duration of your work.
73          *
74          * It should never get filled during normal usage of Friendica
75          *
76          * @param string        $channel The channel of the logger instance
77          * @param Configuration $config  The config
78          *
79          * @return LoggerInterface The PSR-3 compliant logger instance
80          */
81         public static function createDev($channel, Configuration $config)
82         {
83                 $debugging   = $config->get('system', 'debugging');
84                 $stream      = $config->get('system', 'dlogfile');
85                 $developerIp = $config->get('system', 'dlogip');
86
87                 if (!isset($developerIp) || !$debugging) {
88                         return null;
89                 }
90
91                 $loggerTimeZone = new \DateTimeZone('UTC');
92                 Monolog\Logger::setTimezone($loggerTimeZone);
93
94                 $logger = new Monolog\Logger($channel);
95                 $logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
96                 $logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
97                 $logger->pushProcessor(new Monolog\Processor\UidProcessor());
98                 $logger->pushProcessor(new FriendicaIntrospectionProcessor(LogLevel::DEBUG, self::$ignoreClassList));
99
100                 $logger->pushHandler(new FriendicaDevelopHandler($developerIp));
101
102                 static::addStreamHandler($logger, $stream, LogLevel::DEBUG);
103
104                 Logger::setDevLogger($logger);
105
106                 return $logger;
107         }
108
109         /**
110          * Mapping a legacy level to the PSR-3 compliant levels
111          * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#5-psrlogloglevel
112          *
113          * @param string $level the level to be mapped
114          *
115          * @return string the PSR-3 compliant level
116          */
117         private static function mapLegacyConfigDebugLevel($level)
118         {
119                 switch ($level) {
120                         // legacy WARNING
121                         case "0":
122                                 return LogLevel::ERROR;
123                         // legacy INFO
124                         case "1":
125                                 return LogLevel::WARNING;
126                         // legacy TRACE
127                         case "2":
128                                 return LogLevel::NOTICE;
129                         // legacy DEBUG
130                         case "3":
131                                 return LogLevel::INFO;
132                         // legacy DATA
133                         case "4":
134                                 return LogLevel::DEBUG;
135                         // legacy ALL
136                         case "5":
137                                 return LogLevel::DEBUG;
138                         // default if nothing set
139                         default:
140                                 return $level;
141                 }
142         }
143
144         /**
145          * Adding a handler to a given logger instance
146          *
147          * @param LoggerInterface $logger  The logger instance
148          * @param mixed           $stream  The stream which handles the logger output
149          * @param string          $level   The level, for which this handler at least should handle logging
150          *
151          * @return void
152          *
153          * @throws InternalServerErrorException if the logger is incompatible to the logger factory
154          * @throws \Exception in case of general failures
155          */
156         public static function addStreamHandler($logger, $stream, $level = LogLevel::NOTICE)
157         {
158                 if ($logger instanceof Monolog\Logger) {
159                         $loglevel = Monolog\Logger::toMonologLevel($level);
160
161                         // fallback to notice if an invalid loglevel is set
162                         if (!is_int($loglevel)) {
163                                 $loglevel = LogLevel::NOTICE;
164                         }
165
166                         $fileHandler = new Monolog\Handler\StreamHandler($stream, $loglevel);
167
168                         $formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n");
169                         $fileHandler->setFormatter($formatter);
170
171                         $logger->pushHandler($fileHandler);
172                 } else {
173                         throw new InternalServerErrorException('Logger instance incompatible for MonologFactory');
174                 }
175         }
176
177         public static function addVoidHandler($logger)
178         {
179                 if ($logger instanceof Monolog\Logger) {
180                         $logger->pushHandler(new Monolog\Handler\NullHandler());
181                 }
182         }
183 }