0%

laravel/lumen中自定义日志(json)和processor

[TOC]

项目上线后,有一些场景需要收集日志进行业务分析或者进行业务监控用,通常需要将日志转为json的格式,这里记录下laravel框架中如何最小化改动进行日志格式化,完成收集

先看一下最终收集的数据格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
调用:
Log::info("code登陆后解析返回的数据", is_array($result) ? $result : [$result]);
日志记录:
{
"@timestamp":"2021-03-22T14:42:44.538683+08:00",
"@version":1,
"host":"7468a43f9a91",
"message":"code登陆后解析返回的数据",
"type":"legendage",
"channel":"prod",
"level":"INFO",
"monolog_level":200,
"extra":{
"request_id":"e5031cbd2ea6f3a86c8a9c41a1d637b827171",
"process_id":89,
"memory_usage":"2 MB",
"url":"/api/auth/login?code=023A051w37kB4W2GNn3w3hueAU2A0516",
"ip":"1.85.216.155",
"http_method":"GET",
"server":"api.domain.cn",
"referrer":"https://servicewechat.com/appid/devtools/page-frame.html"
},
"context":{
"session_key":"SuW7afBI0sYjOHmExBwIMw==",
"openid":"o9GF_5dZ5ZS1-wLyx4ziY1z2Shds"
}
}

一般说来除了extra可以进行自定义添加附加的数据,其他的数据均由框架自动生成,原有的日志生成方法不变,接下来演示下如何配置:

logging文件修改

找到src/config/logging.php文件,进行下列配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php

use App\Logging\LogstashJsonFormatter;

return [
'default' => env('LOG_CHANNEL', 'stack'),
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily'],
],

'single' => [
'driver' => 'single',
'path' => storage_path('logs/lumen.log'),
'level' => 'debug',
],

'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/app/' . date('Y/m/d/\h-H', time()) . '.log'),
'level' => 'debug',
'days' => 14,
'permission' => 0755,
'tap' => [LogstashJsonFormatter::class,], // 重点是这一句
],
],
];

具体说明可参考官方文档:https://learnku.com/docs/laravel/8.x/logging/9376#customizing-monolog-for-channels

实现自定义格式化日志类

官方的自定义格式化类示例是在App\Logging命名空间下,所以我们在app目录下创建我们的自定义格式化类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php

namespace App\Logging;

use App\Logging\Formatter\LogStashFormatter as CustomerLogstashFormatter;
use Illuminate\Log\Logger;
use Monolog\Formatter\LogstashFormatter as MonoLogstashFormatter;
use Monolog\Processor\MemoryUsageProcessor;
use Monolog\Processor\ProcessIdProcessor;
use Monolog\Processor\WebProcessor;

class LogstashJsonFormatter
{
/**
* 自定义给定的日志实例
*
* @param Logger $logger
*
* @return void
*/
public function __invoke(Logger $logger)
{
foreach ($logger->getHandlers() as $handler) {
$handler->setFormatter(new CustomerLogstashFormatter(env("APP_NAME")));
$handler->pushProcessor(new WebProcessor());
$handler->pushProcessor(new MemoryUsageProcessor());
$handler->pushProcessor(new ProcessIdProcessor());
// 进行额外扩展数据的添加
$handler->pushProcessor(
function ($record) {
$record['extra']['request_id'] = REQUEST_ID;
return $record;
}
);
}
}
}

参考上面的实现就可以完成上面说的json格式的日志

参考文档

Using Monolog:http://seldaek.github.io/monolog/doc/01-usage.html

[Proposal] Add processors option to monolog:https://github.com/laravel/ideas/issues/1796