Passed
Push — master ( f77967...f25758 )
by Fran
03:23
created

Logger   A

Complexity

Total Complexity 39

Size/Duplication

Total Lines 271
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 11

Test Coverage

Coverage 94%

Importance

Changes 0
Metric Value
dl 0
loc 271
rs 9.28
c 0
b 0
f 0
ccs 94
cts 100
cp 0.94
wmc 39
lcom 2
cbo 11

18 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A __destruct() 0 4 1
A defaultLog() 0 4 1
A infoLog() 0 4 1
A debugLog() 0 4 2
A errorLog() 0 4 1
A criticalLog() 0 7 2
A warningLog() 0 4 1
A addPushLogger() 0 17 4
A setup() 0 12 2
A setLoggerName() 0 7 2
A cleanLoggerName() 0 7 1
A createLoggerPath() 0 8 1
B log() 0 29 8
A addDefaultStreamHandler() 0 12 2
B addMinimalContext() 0 9 7
A getLogUid() 0 3 1
A getUid() 0 3 1
1
<?php
2
3
namespace PSFS\base;
4
5
use Monolog\Formatter\LineFormatter;
6
use Monolog\Handler\FirePHPHandler;
7
use Monolog\Handler\StreamHandler;
8
use Monolog\Logger as Monolog;
9
use Monolog\Processor\MemoryUsageProcessor;
10
use Monolog\Processor\UidProcessor;
11
use PSFS\base\config\Config;
12
use PSFS\base\types\helpers\GeneratorHelper;
13
use PSFS\base\types\helpers\Inspector;
14
use PSFS\base\types\helpers\SlackHelper;
15
use PSFS\base\types\traits\SingletonTrait;
16
17
18
if (!defined('LOG_DIR')) {
19
    GeneratorHelper::createDir(BASE_DIR . DIRECTORY_SEPARATOR . 'logs');
20
    define('LOG_DIR', BASE_DIR . DIRECTORY_SEPARATOR . 'logs');
21
}
22
23
/**
24
 * Class Logger
25
 * @package PSFS\base
26
 * Servicio de log
27
 */
28
class Logger
29
{
30
    const DEFAULT_NAMESPACE = 'PSFS';
31
    use SingletonTrait;
32
    /**
33
     * @var \Monolog\Logger
34
     */
35
    protected $logger;
36
    /**
37
     * @var resource
38
     */
39
    private $stream;
40
    /**
41
     * @var UidProcessor
42
     */
43
    private $uuid;
44
    /**
45
     * @var string
46
     */
47
    protected $log_level;
48
49
    /**
50
     * Logger constructor.
51
     * @throws exception\GeneratorException
52
     */
53 2
    public function __construct()
54
    {
55 2
        $config = Config::getInstance();
56 2
        $args = func_get_args();
57 2
        list($logger, $debug, $path) = $this->setup($config, $args);
58 2
        $this->stream = fopen($path . DIRECTORY_SEPARATOR . date('Ymd') . '.log', 'a+');
59 2
        $this->addPushLogger($logger, $debug, $config);
60 2
        $this->log_level = Config::getParam('log.level', 'info');
61 2
    }
62
63 1
    public function __destruct()
64
    {
65 1
        fclose($this->stream);
66 1
    }
67
68
    /**
69
     * @param string $msg
70
     * @param array $context
71
     * @return bool
72
     */
73 1
    public function defaultLog($msg = '', array $context = [])
74
    {
75 1
        return $this->logger->addNotice($msg, $this->addMinimalContext($context));
76
    }
77
78
    /**
79
     * @param string $msg
80
     * @param array $context
81
     *
82
     * @return bool
83
     */
84 4
    public function infoLog($msg = '', array $context = [])
85
    {
86 4
        return $this->logger->addInfo($msg, $this->addMinimalContext($context));
87
    }
88
89
    /**
90
     * @param string $msg
91
     * @param array $context
92
     *
93
     * @return bool
94
     */
95 21
    public function debugLog($msg = '', array $context = [])
96
    {
97 21
        return ($this->log_level === 'debug') ? $this->logger->addDebug($msg, $this->addMinimalContext($context)) : null;
98
    }
99
100
    /**
101
     * @param $msg
102
     * @param array $context
103
     *
104
     * @return bool
105
     */
106 4
    public function errorLog($msg, array $context = [])
107
    {
108 4
        return $this->logger->addError($msg, $this->addMinimalContext($context));
109
    }
110
111
    /**
112
     * @param $msg
113
     * @param array $context
114
     *
115
     * @return bool
116
     */
117 1
    public function criticalLog($msg, array $context = [])
118
    {
119 1
        if(Config::getParam('log.slack.hook')) {
120
            SlackHelper::getInstance()->trace($msg, '', '', $context);
121
        }
122 1
        return $this->logger->addCritical($msg, $this->addMinimalContext($context));
123
    }
124
125
    /**
126
     * @param $msg
127
     * @param array $context
128
     * @return bool
129
     */
130 2
    public function warningLog($msg, array $context = [])
131
    {
132 2
        return $this->logger->addWarning($msg, $this->addMinimalContext($context));
133
    }
134
135
    /**
136
     * @param string $logger
137
     * @param boolean $debug
138
     * @param Config $config
139
     * @throws \Exception
140
     */
141 2
    private function addPushLogger($logger, $debug, Config $config)
142
    {
143 2
        $this->logger = new Monolog(strtoupper($logger));
144 2
        $this->logger->pushHandler($this->addDefaultStreamHandler($debug));
145 2
        if ($debug) {
146 2
            $phpFireLog = $config->get('logger.phpFire');
147 2
            if (!empty($phpFireLog)) {
148 1
                $this->logger->pushHandler(new FirePHPHandler());
149
            }
150 2
            $memoryLog = $config->get('logger.memory');
151 2
            if (!empty($memoryLog)) {
152 1
                $this->logger->pushProcessor(new MemoryUsageProcessor());
153
            }
154
        }
155 2
        $this->uuid = new UidProcessor();
156 2
        $this->logger->pushProcessor($this->uuid);
157 2
    }
158
159
    /**
160
     * @param Config $config
161
     * @param array $args
162
     * @return array
163
     * @throws exception\GeneratorException
164
     */
165 2
    private function setup(Config $config, array $args = [])
166
    {
167 2
        $args = $args ?? [];
168 2
        $debug = $config->getDebugMode();
169 2
        $namespace = self::DEFAULT_NAMESPACE;
170 2
        if (0 !== count($args)) {
171 2
            $namespace = $args[0][0] ?? 'PSFS';
172 2
            $debug = $args[0][1] ?? true;
173
        }
174 2
        $path = $this->createLoggerPath($config);
175 2
        return array($this->cleanLoggerName($namespace), $debug, $path);
176
    }
177
178
    /**
179
     * @param Config $config
180
     *
181
     * @return string
182
     */
183 2
    private function setLoggerName(Config $config)
184
    {
185 2
        $logger = $config->get('platform_name') ?: self::DEFAULT_NAMESPACE;
186 2
        $logger = $this->cleanLoggerName($logger);
187
188 2
        return $logger;
189
    }
190
191
    /**
192
     * @param $logger
193
     *
194
     * @return mixed
195
     */
196 2
    private function cleanLoggerName($logger)
197
    {
198 2
        $logger = str_replace(' ', '', $logger);
199 2
        $logger = preg_replace('/\\\/', ".", $logger);
200
201 2
        return $logger;
202
    }
203
204
    /**
205
     * @param Config $config
206
     * @return string
207
     * @throws exception\GeneratorException
208
     */
209 2
    private function createLoggerPath(Config $config)
210
    {
211 2
        $logger = $this->setLoggerName($config);
212 2
        $path = LOG_DIR . DIRECTORY_SEPARATOR . $logger . DIRECTORY_SEPARATOR . date('Y') . DIRECTORY_SEPARATOR . date('m');
213 2
        GeneratorHelper::createDir($path);
214
215 2
        return $path;
216
    }
217
218
    /**
219
     * @param string $msg
220
     * @param int $type
221
     * @param array $context
0 ignored issues
show
Documentation introduced by
Should the type for parameter $context not be null|array? Also, consider making the array more specific, something like array<String>, or String[].

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive. In addition it looks for parameters that have the generic type array and suggests a stricter type like array<String>.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
222
     */
223 22
    public static function log($msg, $type = LOG_DEBUG, array $context = null)
224
    {
225 22
        if(null === $context) {
226 22
            $context = [];
227
        }
228 22
        if(Config::getParam('profiling.enable')) {
229 1
            Inspector::stats($msg);
230
        }
231
        switch ($type) {
232 22
            case LOG_DEBUG:
233 21
                self::getInstance()->debugLog($msg, $context);
234 21
                break;
235 7
            case LOG_WARNING:
236 2
                self::getInstance()->warningLog($msg, $context);
237 2
                break;
238 7
            case LOG_CRIT:
239 1
                self::getInstance()->criticalLog($msg, $context);
240 1
                break;
241 7
            case LOG_ERR:
242 4
                self::getInstance()->errorLog($msg, $context);
243 4
                break;
244 4
            case LOG_INFO:
245 4
                self::getInstance()->infoLog($msg, $context);
246 4
                break;
247
            default:
248 1
                self::getInstance()->defaultLog($msg, $context);
249 1
                break;
250
        }
251 22
    }
252
253
    /**
254
     * @param bool $debug
255
     * @return StreamHandler
256
     * @throws \Exception
257
     */
258 2
    private function addDefaultStreamHandler($debug = false)
259
    {
260
        // the default date format is "Y-m-d H:i:s"
261 2
        $dateFormat = 'Y-m-d H:i:s.u';
262
        // the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
263 2
        $output = "[%datetime%] [%channel%:%level_name%]\t%message%\t%context%\t%extra%\n";
264
        // finally, create a formatter
265 2
        $formatter = new LineFormatter($output, $dateFormat);
266 2
        $stream = new StreamHandler($this->stream, $debug ? Monolog::DEBUG : Monolog::WARNING);
267 2
        $stream->setFormatter($formatter);
268 2
        return $stream;
269
    }
270
271
    /**
272
     * @param array $context
273
     * @return array
274
     */
275 7
    private function addMinimalContext(array $context = [])
276
    {
277 7
        $context['uri'] = null !== $_SERVER && array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : 'Unknow';
278 7
        $context['method'] = null !== $_SERVER && array_key_exists('REQUEST_METHOD', $_SERVER) ? $_SERVER['REQUEST_METHOD'] : 'Unknow';
279 7
        if(null !== $_SERVER && array_key_exists('HTTP_X_PSFS_UID', $_SERVER)) {
280
            $context['uid'] = $_SERVER['HTTP_X_PSFS_UID'];
281
        }
282 7
        return $context;
283
    }
284
285
    /**
286
     * @return string
287
     */
288
    public function getLogUid() {
289
        return $this->uuid->getUid();
290
    }
291
292
    /**
293
     * @return string
294
     */
295
    public static function getUid() {
296
        return self::getInstance()->getLogUid();
297
    }
298
}
299