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