]> git.mxchange.org Git - friendica.git/blob - src/Factory/LoggerFactory.php
Log the time as decimal
[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                 $logger = new Monolog\Logger($channel);
44                 $logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
45                 $logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
46                 $logger->pushProcessor(new Monolog\Processor\UidProcessor());
47                 $logger->pushProcessor(new FriendicaIntrospectionProcessor(LogLevel::DEBUG, self::$ignoreClassList));
48
49                 $debugging = $config->get('system', 'debugging');
50                 $stream    = $config->get('system', 'logfile');
51                 $level     = $config->get('system', 'loglevel');
52
53                 if ($debugging) {
54                         $loglevel = self::mapLegacyConfigDebugLevel((string)$level);
55                         static::addStreamHandler($logger, $stream, $loglevel);
56                 } else {
57                         static::addVoidHandler($logger);
58                 }
59
60                 Logger::init($logger);
61
62                 return $logger;
63         }
64
65         /**
66          * Creates a new PSR-3 compliant develop logger
67          *
68          * If you want to debug only interactions from your IP or the IP of a remote server for federation debug,
69          * you'll use this logger instance for the duration of your work.
70          *
71          * It should never get filled during normal usage of Friendica
72          *
73          * @param string        $channel The channel of the logger instance
74          * @param Configuration $config  The config
75          *
76          * @return LoggerInterface The PSR-3 compliant logger instance
77          */
78         public static function createDev($channel, Configuration $config)
79         {
80                 $debugging   = $config->get('system', 'debugging');
81                 $stream      = $config->get('system', 'dlogfile');
82                 $developerIp = $config->get('system', 'dlogip');
83
84                 if (!isset($developerIp) || !$debugging) {
85                         return null;
86                 }
87
88                 $logger = new Monolog\Logger($channel);
89                 $logger->pushProcessor(new Monolog\Processor\PsrLogMessageProcessor());
90                 $logger->pushProcessor(new Monolog\Processor\ProcessIdProcessor());
91                 $logger->pushProcessor(new Monolog\Processor\UidProcessor());
92                 $logger->pushProcessor(new FriendicaIntrospectionProcessor(LogLevel::DEBUG, self::$ignoreClassList));
93
94                 $logger->pushHandler(new FriendicaDevelopHandler($developerIp));
95
96                 static::addStreamHandler($logger, $stream, LogLevel::DEBUG);
97
98                 Logger::setDevLogger($logger);
99
100                 return $logger;
101         }
102
103         /**
104          * Mapping a legacy level to the PSR-3 compliant levels
105          * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#5-psrlogloglevel
106          *
107          * @param string $level the level to be mapped
108          *
109          * @return string the PSR-3 compliant level
110          */
111         private static function mapLegacyConfigDebugLevel($level)
112         {
113                 switch ($level) {
114                         // legacy WARNING
115                         case "0":
116                                 return LogLevel::ERROR;
117                         // legacy INFO
118                         case "1":
119                                 return LogLevel::WARNING;
120                         // legacy TRACE
121                         case "2":
122                                 return LogLevel::NOTICE;
123                         // legacy DEBUG
124                         case "3":
125                                 return LogLevel::INFO;
126                         // legacy DATA
127                         case "4":
128                                 return LogLevel::DEBUG;
129                         // legacy ALL
130                         case "5":
131                                 return LogLevel::DEBUG;
132                         // default if nothing set
133                         default:
134                                 return $level;
135                 }
136         }
137
138         /**
139          * Adding a handler to a given logger instance
140          *
141          * @param LoggerInterface $logger  The logger instance
142          * @param mixed           $stream  The stream which handles the logger output
143          * @param string          $level   The level, for which this handler at least should handle logging
144          *
145          * @return void
146          *
147          * @throws InternalServerErrorException if the logger is incompatible to the logger factory
148          * @throws \Exception in case of general failures
149          */
150         public static function addStreamHandler($logger, $stream, $level = LogLevel::NOTICE)
151         {
152                 if ($logger instanceof Monolog\Logger) {
153                         $loglevel = Monolog\Logger::toMonologLevel($level);
154
155                         // fallback to notice if an invalid loglevel is set
156                         if (!is_int($loglevel)) {
157                                 $loglevel = LogLevel::NOTICE;
158                         }
159
160                         $fileHandler = new Monolog\Handler\StreamHandler($stream, $loglevel);
161
162                         $formatter = new Monolog\Formatter\LineFormatter("%datetime% %channel% [%level_name%]: %message% %context% %extra%\n");
163                         $fileHandler->setFormatter($formatter);
164
165                         $logger->pushHandler($fileHandler);
166                 } else {
167                         throw new InternalServerErrorException('Logger instance incompatible for MonologFactory');
168                 }
169         }
170
171         public static function addVoidHandler($logger)
172         {
173                 if ($logger instanceof Monolog\Logger) {
174                         $logger->pushHandler(new Monolog\Handler\NullHandler());
175                 }
176         }
177 }