Test Failed
Pull Request — master (#12)
by wujunze
03:09
created

Logger   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 479
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 7
Bugs 1 Features 3
Metric Value
eloc 84
c 7
b 1
f 3
dl 0
loc 479
rs 7.92
ccs 70
cts 70
cp 1
wmc 51

31 Methods

Rating   Name   Duplication   Size   Complexity  
A getLastLogger() 0 3 1
A setLogger() 0 3 1
A flushConfigBuffer() 0 3 1
A getBasePath() 0 6 2
A debug() 0 3 2
A info() 0 3 2
A getBuffer() 0 3 1
A getConfigBuffer() 0 3 1
A analyzerDetail() 0 15 1
B log() 0 19 7
A setDatetimeFormat() 0 3 1
A alert() 0 3 2
A warning() 0 3 2
A closeLoggerStream() 0 7 2
A getRequestID() 0 3 1
A getDatetimeFormat() 0 3 1
A getConfig() 0 3 1
A __invoke() 0 8 2
A setConfig() 0 4 1
A notice() 0 3 2
A setRequestID() 0 3 1
A critical() 0 4 2
A getConfigDatetimeFormat() 0 3 1
A error() 0 3 2
A setConfigDatetimeFormat() 0 3 1
A analyzerCount() 0 3 1
A setRequestLevel() 0 3 1
A setBasePath() 0 6 2
A __construct() 0 6 3
A emergency() 0 4 2
A flushBuffer() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like Logger often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Logger, and based on these observations, apply Extract Interface, too.

1
<?php
2
declare(strict_types=1);
3
/*
4
 * This file is part of the seasx/seas-logger.
5
 *
6
 * (c) Panda <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Seasx\SeasLogger;
13
14
use Psr\Log\LoggerInterface;
15
use SeasLog;
0 ignored issues
show
Bug introduced by
The type SeasLog was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Seasx\SeasLogger\Exceptions\NotSupportedException;
17
use function extension_loaded;
18
19
/**
20
 * Class Logger
21
 * @package Seasx\SeasLogger
22
 */
23
class Logger implements LoggerInterface
24
{
25
    const CONTEXT_KEY = 'logger.default';
26
    /**
27
     * All level.
28
     */
29
    const ALL = -2147483647;
30
    /**
31
     * Detailed debug information.
32
     */
33
    const DEBUG = 100;
34
    /**
35
     * Interesting events.
36
     *
37
     * Examples: User logs in, SQL logs.
38
     */
39
    const INFO = 200;
40
    /**
41
     * Uncommon events.
42
     */
43
    const NOTICE = 250;
44
    /**
45
     * Exceptional occurrences that are not errors.
46
     *
47
     * Examples: Use of deprecated APIs, poor use of an API,
48
     * undesirable things that are not necessarily wrong.
49
     */
50
    const WARNING = 300;
51
    /**
52
     * Runtime errors.
53
     */
54
    const ERROR = 400;
55
    /**
56
     * Critical conditions.
57
     *
58
     * Example: Application component unavailable, unexpected exception.
59
     */
60
    const CRITICAL = 500;
61
    /**
62
     * Action must be taken immediately.
63
     *
64
     * Example: Entire website down, database unavailable, etc.
65
     * This should trigger the SMS alerts and wake you up.
66
     */
67
    const ALERT = 550;
68
    /**
69
     * Urgent alert.
70
     */
71
    const EMERGENCY = 600;
72
    /**
73
     * request Level limit.
74
     */
75
    public static $RequestLevel = self::ALL;
76
    /**
77
     * Logging levels from syslog protocol defined in RFC 5424.
78
     *
79
     * This is a static variable and not a constant to serve as an extension point for custom levels
80
     *
81
     * @var string[] Logging levels with the levels as key
82
     */
83
    protected static $levels = [
84
        self::DEBUG => 'DEBUG',
85
        self::INFO => 'INFO',
86
        self::NOTICE => 'NOTICE',
87
        self::WARNING => 'WARNING',
88
        self::ERROR => 'ERROR',
89
        self::CRITICAL => 'CRITICAL',
90
        self::ALERT => 'ALERT',
91
        self::EMERGENCY => 'EMERGENCY',
92
    ];
93
    /** @var AbstractConfig */
94
    protected $config;
95
96
    /**
97
     * Logger constructor.
98
     * @param AbstractConfig|null $config
99
     */
100
    public function __construct(AbstractConfig $config = null)
101
    {
102
        if ($config !== null && !extension_loaded('swoole')) {
103 1
            throw new NotSupportedException("This usage must have swoole version>=4");
104
        }
105 1
        $this->config = $config;
106 1
    }
107
108
    /**
109
     * @return AbstractConfig|null
110
     */
111
    public function getConfig(): ?AbstractConfig
112 1
    {
113
        return $this->config;
114 1
    }
115 1
116
    /**
117
     * @param AbstractConfig $config
118
     * @return Logger
119
     */
120
    public function setConfig(?AbstractConfig $config): self
121 1
    {
122
        $this->config = $config;
123 1
        return $this;
124 1
    }
125
126
    /**
127
     * 设置本次请求标识.
128
     *
129
     * @param string
130 1
     *
131
     * @return bool
132 1
     */
133 1
    public static function setRequestID($request_id)
134
    {
135
        return SeasLog::setRequestID($request_id);
136
    }
137
138
    /**
139 1
     * 获取本次请求标识.
140
     *
141 1
     * @return string
142 1
     */
143
    public static function getRequestID()
144
    {
145
        return SeasLog::getRequestID();
146
    }
147
148 1
    /**
149
     * 设置模块目录.
150 1
     *
151 1
     * @param $module
152
     *
153
     * @return bool
154
     */
155
    public static function setLogger($module)
156
    {
157 1
        return SeasLog::setLogger($module);
158
    }
159 1
160 1
    /**
161
     * 获取最后一次设置的模块目录.
162
     *
163
     * @return string
164
     */
165
    public static function getLastLogger()
166 2
    {
167
        return SeasLog::getLastLogger();
168 2
    }
169 2
170
    /**
171
     * 设置DatetimeFormat配置.
172
     *
173
     * @param $format
174
     *
175 1
     * @return bool
176
     */
177 1
    public static function setDatetimeFormat($format)
178 1
    {
179
        return SeasLog::setDatetimeFormat($format);
180
    }
181
182
    /**
183
     * @param string $format
184
     * @return bool
185 2
     */
186
    public function setConfigDatetimeFormat(string $format): bool
187 2
    {
188 1
        return $this->config->setDatetimeFormat($format);
189
    }
190
191 2
    /**
192 1
     * @return string
193
     */
194
    public function getConfigDatetimeFormat(): string
195 2
    {
196
        return $this->config->getDatetimeFormat();
197 2
    }
198 2
199
    /**
200
     * 返回当前DatetimeFormat配置格式.
201
     *
202
     * @return string
203
     */
204
    public static function getDatetimeFormat()
205 22
    {
206
        return SeasLog::getDatetimeFormat();
207 22
    }
208
209
    /**
210
     * 统计所有类型(或单个类型)行数.
211
     *
212
     * @param string $level
213 1
     * @param string $log_path
214
     * @param null $key_word
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $key_word is correct as it would always require null to be passed?
Loading history...
215 1
     *
216
     * @return array
217
     */
218
    public static function analyzerCount($level = 'all', $log_path = '*', $key_word = null)
219
    {
220
        return SeasLog::analyzerCount($level, $log_path, (string)$key_word);
221
    }
222
223
    /**
224
     * 以数组形式,快速取出某类型log的各行详情.
225 2
     *
226
     * @param        $level
227 2
     * @param string $log_path
228
     * @param null $key_word
229
     * @param int $start
230
     * @param int $limit
231
     * @param        $order    默认为正序 SEASLOG_DETAIL_ORDER_ASC,可选倒序 SEASLOG_DETAIL_ORDER_DESC
0 ignored issues
show
Documentation Bug introduced by
The doc comment 默认为正序 at position 0 could not be parsed: Unknown type name '默认为正序' at position 0 in 默认为正序.
Loading history...
232
     *
233
     * @return array
234
     */
235 1
    public static function analyzerDetail(
236
        $level = SEASLOG_INFO,
0 ignored issues
show
Bug introduced by
The constant Seasx\SeasLogger\SEASLOG_INFO was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
237 1
        $log_path = '*',
238
        $key_word = null,
239
        $start = 1,
240
        $limit = 20,
241
        $order = SEASLOG_DETAIL_ORDER_ASC
0 ignored issues
show
Bug introduced by
The constant Seasx\SeasLogger\SEASLOG_DETAIL_ORDER_ASC was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
242
    ) {
243
        return SeasLog::analyzerDetail(
244
            $level,
245
            $log_path,
246
            (string)$key_word,
247 2
            $start,
248
            $limit,
249 2
            $order
250
        );
251
    }
252
253
    /**
254
     * 获得当前日志buffer中的内容.
255
     *
256
     * @return array
257 1
     */
258
    public static function getBuffer()
259 1
    {
260
        return SeasLog::getBuffer();
261
    }
262
263
    /**
264
     * @return array
265
     */
266
    public function getConfigBuffer(): array
267
    {
268
        return $this->config->getBuffer();
269 2
    }
270
271 2
    /**
272
     * 将buffer中的日志立刻刷到硬盘.
273
     *
274
     * @return bool
275
     */
276
    public static function flushBuffer()
277
    {
278
        return SeasLog::flushBuffer();
279 1
    }
280
281 1
    public function flushConfigBuffer(): void
282
    {
283
        $this->config->flush(true);
284
    }
285
286
    /**
287
     * Manually release stream flow from logger
288
     *
289
     * @param $type
290
     * @param string $name
291
     * @return bool
292
     */
293 1
    public static function closeLoggerStream($type = SEASLOG_CLOSE_LOGGER_STREAM_MOD_ALL, $name = '')
0 ignored issues
show
Bug introduced by
The constant Seasx\SeasLogger\SEASLOG...E_LOGGER_STREAM_MOD_ALL was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
294
    {
295 1
        if (empty($name)) {
296
            return SeasLog::closeLoggerStream($type);
297
        }
298
299
        return SeasLog::closeLoggerStream($type, $name);
300
301
    }
302
303
    /**
304
     * set request level for seaslog.
305
     *
306
     * @param int $level
307
     */
308
    public function setRequestLevel($level = self::ALL)
309
    {
310 1
        self::$RequestLevel = $level;
311
    }
312
313
    /**
314
     * System is unusable.
315
     *
316
     * @param string $message
317
     * @param array $context
318 1
     *
319 1
     * @return void
320 1
     */
321 1
    public function emergency($message, array $context = array())
322 1
    {
323 1
        empty($this->config) ? SeasLog::emergency($message, $context) : $this->log(self::EMERGENCY, $message,
324 1
            $context);
325
    }
326
327
    /**
328
     * Logs with an arbitrary level.
329
     *
330
     * @param mixed $level
331
     * @param string $message
332
     * @param array $context
333 1
     *
334
     * @return void
335 1
     */
336
    public function log($level, $message, array $context = array())
337
    {
338
        if ((int)$level < self::$RequestLevel) {
339
            return;
340
        }
341
342
        if (!array_key_exists($level, self::$levels)) {
343 1
            return;
344
        }
345 1
346
        if (empty($this->config)) {
347
            $levelFunction = strtolower(self::$levels[$level]);
348
            SeasLog::$levelFunction($message, $context);
349
        } else {
350
            if (is_string($message)) {
0 ignored issues
show
introduced by
The condition is_string($message) is always true.
Loading history...
351
                $this->config->log(self::$levels[$level], $message, $context);
352
            } elseif (is_array($message)) {
353
                foreach ($message as $m) {
354
                    $this->config->log(self::$levels[$level], $m, $context);
355 1
                }
356
            }
357 1
        }
358 1
    }
359 1
360
    /**
361
     * Action must be taken immediately.
362 1
     *
363
     * Example: Entire website down, database unavailable, etc. This should
364
     * trigger the SMS alerts and wake you up.
365
     *
366
     * @param string $message
367
     * @param array $context
368
     *
369
     * @return void
370
     */
371
    public function alert($message, array $context = array())
372
    {
373
        empty($this->config) ? SeasLog::alert($message, $context) : $this->log(self::ALERT, $message, $context);
374
    }
375
376
    /**
377
     * Critical conditions.
378
     *
379
     * Example: Application component unavailable, unexpected exception.
380
     *
381
     * @param string $message
382
     * @param array $context
383
     *
384
     * @return void
385
     */
386
    public function critical($message, array $context = array())
387
    {
388
        empty($this->config) ? SeasLog::critical($message, $context) : $this->log(self::CRITICAL, $message,
389
            $context);
390
    }
391
392
    /**
393
     * Runtime errors that do not require immediate action but should typically
394
     * be logged and monitored.
395
     *
396
     * @param string $message
397
     * @param array $context
398
     *
399
     * @return void
400
     */
401
    public function error($message, array $context = array())
402
    {
403
        empty($this->config) ? SeasLog::error($message, $context) : $this->log(self::ERROR, $message, $context);
404
    }
405
406
    /**
407
     * Exceptional occurrences that are not errors.
408
     *
409
     * Example: Use of deprecated APIs, poor use of an API, undesirable things
410
     * that are not necessarily wrong.
411
     *
412
     * @param string $message
413
     * @param array $context
414
     *
415
     * @return void
416
     */
417
    public function warning($message, array $context = array())
418
    {
419
        empty($this->config) ? SeasLog::warning($message, $context) : $this->log(self::WARNING, $message, $context);
420
    }
421
422
    /**
423
     * Normal but significant events.
424
     *
425
     * @param string $message
426
     * @param array $context
427
     *
428
     * @return void
429
     */
430
    public function notice($message, array $context = array())
431
    {
432
        empty($this->config) ? SeasLog::notice($message, $context) : $this->log(self::NOTICE, $message, $context);
433
    }
434
435
    /**
436
     * Interesting events.
437
     *
438
     * Example: User logs in, SQL logs.
439
     *
440
     * @param string $message
441
     * @param array $context
442
     *
443
     * @return void
444
     */
445
    public function info($message, array $context = array())
446
    {
447
        empty($this->config) ? SeasLog::info($message, $context) : $this->log(self::INFO, $message, $context);
448
    }
449
450
    /**
451
     * Detailed debug information.
452
     *
453
     * @param string $message
454
     * @param array $context
455
     *
456
     * @return void
457
     */
458
    public function debug($message, array $context = array())
459
    {
460
        empty($this->config) ? SeasLog::debug($message, $context) : $this->log(self::DEBUG, $message, $context);
461
    }
462
463
    /**
464
     * @return string
465
     */
466
    public function getBasePath()
467
    {
468
        if ($this->config instanceof LoggerConfig) {
469
            throw new NotSupportedException(sprintf("LoggerConfig not support %s", __METHOD__));
470
        }
471
        return SeasLog::getBasePath();
472
    }
473
474
    /**
475
     * Create a custom SeasLog instance.
476
     *
477
     * @param array $config
478
     *
479
     * @return Logger
480
     */
481
    public function __invoke(array $config)
482
    {
483
        $logger = new Logger();
484
        if (!empty($config['path'])) {
485
            $logger->setBasePath($config['path']);
486
        }
487
488
        return $logger;
489
    }
490
491
    /**
492
     * @param string $basePath
493
     *
494
     * @return bool
495
     */
496
    public function setBasePath(string $basePath)
497
    {
498
        if ($this->config instanceof LoggerConfig) {
499
            throw new NotSupportedException(sprintf("LoggerConfig not support %s", __METHOD__));
500
        }
501
        return SeasLog::setBasePath($basePath);
502
    }
503
}