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