Completed
Push — 6.0 ( 660e56...f0eade )
by liu
03:54
created

Log::driver()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 12
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 6
nc 3
nop 1
dl 0
loc 12
ccs 0
cts 7
cp 0
crap 20
rs 10
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: liu21st <[email protected]>
10
// +----------------------------------------------------------------------
11
declare (strict_types = 1);
12
13
namespace think;
14
15
use Psr\Log\LoggerInterface;
16
17
/**
18
 * 日志管理类
19
 */
20
class Log implements LoggerInterface
21
{
22
    const EMERGENCY = 'emergency';
23
    const ALERT     = 'alert';
24
    const CRITICAL  = 'critical';
25
    const ERROR     = 'error';
26
    const WARNING   = 'warning';
27
    const NOTICE    = 'notice';
28
    const INFO      = 'info';
29
    const DEBUG     = 'debug';
30
    const SQL       = 'sql';
31
32
    /**
33
     * 应用对象
34
     * @var App
35
     */
36
    protected $app;
37
38
    /**
39
     * 日志信息
40
     * @var array
41
     */
42
    protected $log = [];
43
44
    /**
45
     * 日志通道
46
     * @var string
47
     */
48
    protected $channel;
49
50
    /**
51
     * 配置参数
52
     * @var array
53
     */
54
    protected $config = [];
55
56
    /**
57
     * 日志写入驱动
58
     * @var array
59
     */
60
    protected $driver = [];
61
62
    /**
63
     * 日志授权key
64
     * @var string
65
     */
66
    protected $key;
67
68
    /**
69
     * 是否允许日志写入
70
     * @var bool
71
     */
72
    protected $allowWrite = true;
73
74
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $app should have a doc-comment as per coding-style.
Loading history...
75
     * 构造方法
76
     * @access public
77
     */
78
    public function __construct(App $app)
79
    {
80
        $this->app    = $app;
81
        $this->config = $app->config->get('log');
82
83
        $this->channel();
84
    }
85
86
    /**
87
     * 切换日志通道
88
     * @access public
89
     * @param  string $name 日志通道名
90
     * @return $this
91
     */
92
    public function channel(string $name = '')
93
    {
94
        if ('' == $name) {
95
            $name = $this->config['default'] ?? 'think';
96
        }
97
98
        if (!isset($this->config['channels'][$name])) {
99
            throw new InvalidArgumentException('Undefined log config:' . $name);
0 ignored issues
show
Bug introduced by
The type think\InvalidArgumentException was not found. Did you mean InvalidArgumentException? If so, make sure to prefix the type with \.
Loading history...
100
        }
101
102
        $this->channel = $name;
103
        return $this;
104
    }
105
106
    /**
107
     * 实例化日志写入驱动
108
     * @access public
109
     * @param  string $name 日志通道名
110
     * @return object
111
     */
112
    protected function driver(string $name = '')
113
    {
114
        $name = $name ?: $this->channel;
115
116
        if (!isset($this->driver[$name])) {
117
            $config = $this->config['channels'][$name];
118
            $type   = !empty($config['type']) ? $config['type'] : 'File';
119
120
            $this->driver[$name] = App::factory($type, '\\think\\log\\driver\\', $config);
121
        }
122
123
        return $this->driver[$name];
124
    }
125
126
    /**
127
     * 获取日志信息
128
     * @access public
129
     * @param  string $channel 日志通道
130
     * @return array
131
     */
132
    public function getLog(string $channel = ''): array
133
    {
134
        $channel = $channel ?: $this->channel;
135
        return $this->log[$channel] ?? [];
136
    }
137
138
    /**
139
     * 记录日志信息
140
     * @access public
141
     * @param  mixed  $msg       日志信息
0 ignored issues
show
Coding Style introduced by
Expected 5 spaces after parameter name; 7 found
Loading history...
142
     * @param  string $type      日志级别
0 ignored issues
show
Coding Style introduced by
Expected 4 spaces after parameter name; 6 found
Loading history...
143
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
144
     * @return $this
145
     */
146
    public function record($msg, string $type = 'info', array $context = [])
147
    {
148
        if (!$this->allowWrite) {
149
            return;
150
        }
151
152
        if (is_string($msg) && !empty($context)) {
153
            $replace = [];
154
            foreach ($context as $key => $val) {
155
                $replace['{' . $key . '}'] = $val;
156
            }
157
158
            $msg = strtr($msg, $replace);
159
        }
160
161
        if ($this->app->runningInConsole()) {
162
            if (empty($this->config['level']) || in_array($type, $this->config['level'])) {
163
                // 命令行日志实时写入
164
                $this->write($msg, $type, true);
165
            }
166
        } elseif (isset($this->config['type_channel'][$type])) {
167
            $channels = (array) $this->config['type_channel'][$type];
168
            foreach ($channels as $channel) {
169
                $this->log[$channel][$type][] = $msg;
170
            }
171
        } else {
172
            $this->log[$this->channel][$type][] = $msg;
173
        }
174
175
        return $this;
176
    }
177
178
    /**
0 ignored issues
show
Coding Style introduced by
Parameter $log should have a doc-comment as per coding-style.
Loading history...
179
     * 记录批量日志信息
180
     * @access public
181
     * @param  array  $msg  日志信息
0 ignored issues
show
Coding Style introduced by
Doc comment for parameter $msg does not match actual variable name $log
Loading history...
182
     * @param  string $type 日志级别
183
     * @return $this
184
     */
185
    public function append(array $log, string $type = 'info')
186
    {
187
        if (!$this->allowWrite || empty($log)) {
188
            return $this;
189
        }
190
191
        if (isset($this->log[$this->channel][$type])) {
192
            $this->log[$this->channel][$type] += $log;
193
        } else {
194
            $this->log[$this->channel][$type] = $log;
195
        }
196
197
        return $this;
198
    }
199
200
    /**
201
     * 清空日志信息
202
     * @access public
203
     * @param  string  $channel 日志通道名
204
     * @return $this
205
     */
206
    public function clear(string $channel = '')
207
    {
208
        if ($channel) {
209
            $this->log[$channel] = [];
210
        } else {
211
            $this->log = [];
212
        }
213
214
        return $this;
215
    }
216
217
    /**
218
     * 当前日志记录的授权key
219
     * @access public
220
     * @param  string  $key  授权key
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
221
     * @return $this
222
     */
223
    public function key(string $key)
224
    {
225
        $this->key = $key;
226
227
        return $this;
228
    }
229
230
    /**
231
     * 检查日志写入权限
232
     * @access public
233
     * @param  array  $config  当前日志配置参数
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 2 found
Loading history...
234
     * @return bool
235
     */
236
    public function check(array $config): bool
237
    {
238
        if ($this->key && !empty($config['allow_key']) && !in_array($this->key, $config['allow_key'])) {
239
            return false;
240
        }
241
242
        return true;
243
    }
244
245
    /**
246
     * 关闭本次请求日志写入
247
     * @access public
248
     * @return $this
249
     */
250
    public function close()
251
    {
252
        $this->allowWrite = false;
253
        $this->log        = [];
254
255
        return $this;
256
    }
257
258
    /**
259
     * 保存日志信息
260
     * @access public
261
     * @param  string $channel 日志通道名
262
     * @return bool
263
     */
264
    public function save(string $channel = ''): bool
0 ignored issues
show
Unused Code introduced by
The parameter $channel is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

264
    public function save(/** @scrutinizer ignore-unused */ string $channel = ''): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
265
    {
266
        if (empty($this->log) || !$this->allowWrite) {
267
            return true;
268
        }
269
270
        if (!$this->check($this->config)) {
271
            // 检测日志写入权限
272
            return false;
273
        }
274
275
        foreach ($this->log as $channel => $logs) {
276
            $log = [];
277
278
            foreach ($logs as $level => $info) {
279
                if (!$this->app->isDebug() && 'debug' == $level) {
280
                    continue;
281
                }
282
283
                if (empty($this->config['level']) || in_array($level, $this->config['level'])) {
284
                    $log[$level] = $info;
285
                }
286
            }
287
288
            $result = $this->driver($channel)->save($log);
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
289
290
            $this->log[$channel] = [];
291
        }
292
293
        return true;
294
    }
295
296
    /**
297
     * 实时写入日志信息 并支持行为
298
     * @access public
299
     * @param  mixed  $msg   调试信息
300
     * @param  string $type  日志级别
301
     * @param  bool   $force 是否强制写入
302
     * @return bool
303
     */
304
    public function write($msg, string $type = 'info', bool $force = false): bool
305
    {
306
        // 封装日志信息
307
        if (empty($this->config['level'])) {
308
            $force = true;
309
        }
310
311
        $log = [];
312
313
        if (true === $force || in_array($type, $this->config['level'])) {
314
            $log[$type][] = $msg;
315
        } else {
316
            return false;
317
        }
318
319
        // 监听LogWrite
320
        $this->app->event->trigger('LogWrite', $log);
321
322
        // 写入日志
323
        return $this->driver()->save($log, false);
324
    }
325
326
    /**
327
     * 记录日志信息
328
     * @access public
329
     * @param  string $level     日志级别
0 ignored issues
show
Coding Style introduced by
Expected 3 spaces after parameter name; 5 found
Loading history...
330
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
331
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
332
     * @return void
333
     */
334
    public function log($level, $message, array $context = []): void
335
    {
336
        $this->record($message, $level, $context);
337
    }
338
339
    /**
340
     * 记录emergency信息
341
     * @access public
342
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
343
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
344
     * @return void
345
     */
346
    public function emergency($message, array $context = []): void
347
    {
348
        $this->log(__FUNCTION__, $message, $context);
349
    }
350
351
    /**
352
     * 记录警报信息
353
     * @access public
354
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
355
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
356
     * @return void
357
     */
358
    public function alert($message, array $context = []): void
359
    {
360
        $this->log(__FUNCTION__, $message, $context);
361
    }
362
363
    /**
364
     * 记录紧急情况
365
     * @access public
366
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
367
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
368
     * @return void
369
     */
370
    public function critical($message, array $context = []): void
371
    {
372
        $this->log(__FUNCTION__, $message, $context);
373
    }
374
375
    /**
376
     * 记录错误信息
377
     * @access public
378
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
379
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
380
     * @return void
381
     */
382
    public function error($message, array $context = []): void
383
    {
384
        $this->log(__FUNCTION__, $message, $context);
385
    }
386
387
    /**
388
     * 记录warning信息
389
     * @access public
390
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
391
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
392
     * @return void
393
     */
394
    public function warning($message, array $context = []): void
395
    {
396
        $this->log(__FUNCTION__, $message, $context);
397
    }
398
399
    /**
400
     * 记录notice信息
401
     * @access public
402
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
403
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
404
     * @return void
405
     */
406
    public function notice($message, array $context = []): void
407
    {
408
        $this->log(__FUNCTION__, $message, $context);
409
    }
410
411
    /**
412
     * 记录一般信息
413
     * @access public
414
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
415
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
416
     * @return void
417
     */
418
    public function info($message, array $context = []): void
419
    {
420
        $this->log(__FUNCTION__, $message, $context);
421
    }
422
423
    /**
424
     * 记录调试信息
425
     * @access public
426
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
427
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
428
     * @return void
429
     */
430
    public function debug($message, array $context = []): void
431
    {
432
        $this->log(__FUNCTION__, $message, $context);
433
    }
434
435
    /**
436
     * 记录sql信息
437
     * @access public
438
     * @param  mixed  $message   日志信息
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
439
     * @param  array  $context   替换内容
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after parameter name; 3 found
Loading history...
440
     * @return void
441
     */
442
    public function sql($message, array $context = []): void
443
    {
444
        $this->log(__FUNCTION__, $message, $context);
445
    }
446
}
447