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

2021-03-22 17:47:53 浏览数 (1)

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

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

代码语言:javascript复制
 调用:
 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文件,进行下列配置

代码语言:javascript复制
 <?php
 ​
 use AppLoggingLogstashJsonFormatter;
 ​
 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

实现自定义格式化日志类

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

代码语言:javascript复制
 <?php
 ​
 namespace AppLogging;
 ​
 use AppLoggingFormatterLogStashFormatter as CustomerLogstashFormatter;
 use IlluminateLogLogger;
 use MonologFormatterLogstashFormatter as MonoLogstashFormatter;
 use MonologProcessorMemoryUsageProcessor;
 use MonologProcessorProcessIdProcessor;
 use MonologProcessorWebProcessor;
 ​
 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

0 人点赞