Test Failed
Push — master ( ed25dd...eced50 )
by Fran
04:57 queued 01:39
created

Logger::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
ccs 8
cts 8
cp 1
crap 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 $logger
70
     * @param boolean $debug
71
     * @param Config $config
72
     * @throws \Exception
73
     */
74 2
    private function addPushLogger($logger, $debug, Config $config)
75
    {
76 2
        $this->logger = new Monolog(strtoupper($logger));
77 2
        $this->logger->pushHandler($this->addDefaultStreamHandler($debug));
78 2
        if ($debug) {
79 2
            $phpFireLog = $config->get('logger.phpFire');
80 2
            if (!empty($phpFireLog)) {
81 1
                $this->logger->pushHandler(new FirePHPHandler());
82
            }
83 2
            $memoryLog = $config->get('logger.memory');
84 2
            if (!empty($memoryLog)) {
85 1
                $this->logger->pushProcessor(new MemoryUsageProcessor());
86
            }
87
        }
88 2
        $this->uuid = new UidProcessor();
89 2
        $this->logger->pushProcessor($this->uuid);
90 2
    }
91
92
    /**
93
     * @param Config $config
94
     * @param array $args
95
     * @return array
96
     * @throws exception\GeneratorException
97
     */
98 2
    private function setup(Config $config, array $args = [])
99
    {
100 2
        $args = $args ?? [];
101 2
        $debug = $config->getDebugMode();
102 2
        $namespace = self::DEFAULT_NAMESPACE;
103 2
        if (0 !== count($args)) {
104 2
            $namespace = $args[0][0] ?? 'PSFS';
105 2
            $debug = $args[0][1] ?? true;
106
        }
107 2
        $path = $this->createLoggerPath($config);
108 2
        return array($this->cleanLoggerName($namespace), $debug, $path);
109
    }
110
111
    /**
112
     * @param Config $config
113
     *
114
     * @return string
115
     */
116 2
    private function setLoggerName(Config $config)
117
    {
118 2
        $logger = $config->get('platform_name') ?: self::DEFAULT_NAMESPACE;
119 2
        $logger = $this->cleanLoggerName($logger);
120
121 2
        return $logger;
122
    }
123
124
    /**
125
     * @param $logger
126
     *
127
     * @return mixed
128
     */
129 2
    private function cleanLoggerName($logger)
130
    {
131 2
        $logger = str_replace(' ', '', $logger);
132 2
        $logger = preg_replace('/\\\/', ".", $logger);
133
134 2
        return $logger;
135
    }
136
137
    /**
138
     * @param Config $config
139
     * @return string
140
     * @throws exception\GeneratorException
141
     */
142 2
    private function createLoggerPath(Config $config)
143
    {
144 2
        $logger = $this->setLoggerName($config);
145 2
        $path = LOG_DIR . DIRECTORY_SEPARATOR . $logger . DIRECTORY_SEPARATOR . date('Y') . DIRECTORY_SEPARATOR . date('m');
146 2
        GeneratorHelper::createDir($path);
147
148 2
        return $path;
149
    }
150
151
    /**
152
     * @param string $msg
153
     * @param int $type
154
     * @param array $context
155
     * @return bool
156
     */
157 22
    public function addLog($msg, $type = LOG_DEBUG, array $context = []) {
158 22
        return $this->logger->addRecord($type, $msg, $this->addMinimalContext($context));
159
    }
160
161
    /**
162
     * @param string $msg
163
     * @param int $type
164
     * @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...
165
     */
166 22
    public static function log($msg, $type = LOG_DEBUG, array $context = null)
167
    {
168 22
        if(null === $context) {
169 22
            $context = [];
170
        }
171 22
        if(Config::getParam('profiling.enable')) {
172 9
            Inspector::stats($msg);
173
        }
174
        switch ($type) {
175 22
            case LOG_DEBUG:
176 21
                self::getInstance()->addLog($msg, \Monolog\Logger::DEBUG, $context);
177 21
                break;
178 7
            case LOG_WARNING:
179 2
                self::getInstance()->addLog($msg, \Monolog\Logger::WARNING, $context);
180 2
                break;
181 7
            case LOG_CRIT:
182 1
                if(Config::getParam('log.slack.hook')) {
183
                    SlackHelper::getInstance()->trace($msg, '', '', $context);
184
                }
185 1
                self::getInstance()->addLog($msg, \Monolog\Logger::CRITICAL, $context);
186 1
                break;
187 7
            case LOG_ERR:
188 4
                self::getInstance()->addLog($msg, \Monolog\Logger::ERROR, $context);
189 4
                break;
190 4
            case LOG_INFO:
191 4
                self::getInstance()->addLog($msg, \Monolog\Logger::INFO, $context);
192 4
                break;
193
            default:
194 1
                self::getInstance()->addLog($msg, \Monolog\Logger::NOTICE, $context);
195 1
                break;
196
        }
197 22
    }
198
199
    /**
200
     * @param bool $debug
201
     * @return StreamHandler
202
     * @throws \Exception
203
     */
204 2
    private function addDefaultStreamHandler($debug = false)
205
    {
206
        // the default date format is "Y-m-d H:i:s"
207 2
        $dateFormat = 'Y-m-d H:i:s.u';
208
        // the default output format is "[%datetime%] %channel%.%level_name%: %message% %context% %extra%\n"
209 2
        $output = "[%datetime%] [%channel%:%level_name%]\t%message%\t%context%\t%extra%\n";
210
        // finally, create a formatter
211 2
        $formatter = new LineFormatter($output, $dateFormat);
212 2
        $stream = new StreamHandler($this->stream, $debug ? Monolog::DEBUG : Monolog::WARNING);
213 2
        $stream->setFormatter($formatter);
214 2
        return $stream;
215
    }
216
217
    /**
218
     * @param array $context
219
     * @return array
220
     */
221 22
    private function addMinimalContext(array $context = [])
222
    {
223 22
        $context['uri'] = null !== $_SERVER && array_key_exists('REQUEST_URI', $_SERVER) ? $_SERVER['REQUEST_URI'] : 'Unknow';
224 22
        $context['method'] = null !== $_SERVER && array_key_exists('REQUEST_METHOD', $_SERVER) ? $_SERVER['REQUEST_METHOD'] : 'Unknow';
225 22
        if(null !== $_SERVER && array_key_exists('HTTP_X_PSFS_UID', $_SERVER)) {
226
            $context['uid'] = $_SERVER['HTTP_X_PSFS_UID'];
227
        }
228 22
        return $context;
229
    }
230
231
    /**
232
     * @return string
233
     */
234
    public function getLogUid() {
235
        return $this->uuid->getUid();
236
    }
237
238
    /**
239
     * @return string
240
     */
241
    public static function getUid() {
242
        return self::getInstance()->getLogUid();
243
    }
244
}
245