• laravel 5.6日志理解及日志格式定义


    Laravel/Lumen的日志简单系统介绍:

    Laravel/Lumen的日志默认是基于Monolog进行了一层封装,如果要求不高,用起来还是十分容易的,本文基于laravel5.6/Lumen5.6版本进行解说。5.6版对日志系统做了升级,将日志的配置单独放以了config/logging.php 配置文件中,所以现在实用多了。


    基本配置(解决日志路径文件名和保存周期等)

    开始使用Laravel5.5时经常遇到有人问Laravel中日志的为什么只有一个文件,能不能修改日志目录,能不能修改日志文件名?刚开始用时我也有这样的困惑,由于早期项目简单(其实是懒),没有去深入研究。后来跟到了5.6,官方终于发飙了,完美通过配置解决问题(5.5的版本其实也有解决方案,可以自行搜索一下,顺便吐槽一下Lavavel官方文档太简单了,感觉一大半的强大功能都没有提及如何深度使用)。以下代理示例,大概的备注了一下参数说明,还有一些可以挖掘。

    <?php
    // 配置文件路径:/config/logging.php
    return [
        // 默认用哪个
        'default' => env('LOG_CHANNEL', 'stack'),
    
        'channels' => [
            //自定义频道
            'myapplog' => [
                // 日志驱动模式:
                'driver' => 'daily',                            
                // 日志存放路径
                'path' => storage_path('logs/myapplog.log'),
                // 日志等级:
                'level' => 'info',
                // 日志分片周期,多少天一个文件
                'days' => 1,
            ],
    
            // 系统默认,可以合并几个频道,按等级对应记录,符合等级条件的都记录
            'stack' => [
                'driver' => 'stack',
                'channels' => ['single','daily'],
            ],
            'single' => [
                'driver' => 'single',
                'path' => storage_path('logs/laravel.log'),
                'level' => 'debug',
            ],
            'daily' => [
                'driver' => 'daily',
                'path' => storage_path('logs/laravel.log'),
                'level' => 'info',
                'days' => 7,
            ],
        ],
    ];
    

    日志使用:

    <?php
    use Log;
    
    class LogTestController extends Controller
    {
      $message = 'Some message';
      $log = ['user_id'=>1,'user_name'=>'abcd']; 
      Log::channel('myapplog')->info($message, $log);  //Log后的数组会自动转成Json存到日志记录中
    

    查看记录到的效果:

    [2018-02-23 10:22:28] local.INFO: Some message {'user_id':1,'user_name':'abcd'}
    

    高阶定制:(完全定义日志格式,本例为全Json格式)

    踩了好多坑,开始尝试直接自己 new 一个 monolog 的方案,虽然也实现了全 Json 记录了,但有很多不想要的字段。达不到要求。
    几经折腾,发现 Monolog 有很多可以用的 Formatter ,但发现官方的把字段写死在里边了,抓狂到了想直接改官方源码的龌龊地步了,还是不死心,最终发现Laravel5.6的logging参数中有一个tap的接口可以用。顺着这条线,最终通过重定义 Formatter 的 format() 方法实现了需求 :
    1、配置logging.php中的 tap项:

    return [
        'default' => env('LOG_CHANNEL', 'myapplog'),
        'channels' => [
            'myapplog' => [
                'driver' => 'daily',                            
                'path' => storage_path('logs/myapplog.log'),
                // 挂载日志格式接口(重点)
                'tap' => [App\Logging\ApplogFormatter::class],
                'level' => 'info',
                'days' => 1,
            ],
        ],
    ];
    

    新建App/Logging/ApplogFormatter.php

    <?php
    namespace App\Logging;
    
    use App\Logging\JsonFormatter;
    
    class ApplogFormatter
    {
        /**
         * Customize the given logger instance.
         *
         * @param  \Illuminate\Log\Logger  $logger
         * @return void
         */
        public function __invoke($logger)
        {
            foreach ($logger->getHandlers() as $handler) {
                $handler->setFormatter(new JsonFormatter());
            }
        }
    }
    
    

    重点:新建/App/Logging/JsonFormatter.php

    <?php
    namespace App\Logging;
    
    use Monolog\Formatter\JsonFormatter as BaseJsonFormatter;
    
    class JsonFormatter extends BaseJsonFormatter
    {
        public function format(array $record)
        {
            // 这个就是最终要记录的数组,最后转成Json并记录进日志
            $newRecord = [
                'time' => $record['datetime']->format('Y-m-d H:i:s'),
                'message' => $record['message'],
            ];
    
            if (!empty($record['context'])) {
                $newRecord = array_merge($newRecord, $record['context']);
            }
            //$json = 'aaa,bbb,ccc';  // 这是最终返回的记录串,可以按自己的需求改
            $json = $this->toJson($this->normalize($newRecord), true) . ($this->appendNewline ? "\n" : '');
    
            return $json;
        }
    }
    
    

    Log的记录方法还是一样用:

    class LogTestController extends Controller
    {
      $message = 'Some message';
      $log = ['user_id'=>1,'user_name'=>'abcd']; 
      Log::channel('myapplog')->info($message, $log);  //Log后的数组会自动转成Json存
    

    看看最终的效果:

    {"time":"2018-06-09 13:39:39","message":"Some message","user_id":1,"user_name":"abcd"}
    

    大功告成!

  • 相关阅读:
    文本框小写变大写控制
    SQL2005 递归查询示例,非常方便
    GridView分页后进行添加,删除操作后,仍返回到当前页码
    从ASP.NET 1.1升级到ASP.NET 2.0要考虑的Cookie问题
    英语常用口语
    ASP.NET会话(Session)保存模式
    .NET2005文档自动生成
    JavaScript 弹出窗口总结
    SQL SERVER和SYBASE的渊源
    A versatile HDR Video Production System笔记
  • 原文地址:https://www.cnblogs.com/lxwphp/p/15452840.html
Copyright © 2020-2023  润新知