laravel 5.6日志理解及日志格式定义「建议收藏」

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"}

大功告成!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111805.html原文链接:https://javaforall.net

(0)
上一篇 2022年2月14日 下午6:00
下一篇 2022年2月14日 下午6:00


相关推荐

  • 牛客:数据库实战—1—查找最晚入职员工的所有信息、查找入职员工时间排名倒数第三的员工所有信息

    牛客:数据库实战—1—查找最晚入职员工的所有信息、查找入职员工时间排名倒数第三的员工所有信息1、查找最晚入职员工的所有信息CREATE TABLE `employees` (`emp_no` int(11) NOT NULL,`birth_date` date NOT NULL,`first_name` varchar(14) NOT NULL,`last_name` varchar(16) NOT NULL,`gender` char(1) NOT NULL,`hir…

    2022年6月13日
    50
  • log4j使用方法_altium16详细使用教程

    log4j使用方法_altium16详细使用教程日志是应用软件中不可缺少的部分,Apache的开源项目Log4j是一个功能强大的日志组件,提供方便的日志记录。在apache网站:jakarta.apache.org/log4j可以免费下载到Log4j最新版本的软件包。

    2025年9月15日
    7
  • java文件压缩成zip_java的实例

    java文件压缩成zip_java的实例本文整理匯總了Java中org.apache.commons.compress.archivers.zip.ZipFile.getEntries方法的典型用法代碼示例。如果您正苦於以下問題:JavaZipFile.getEntries方法的具體用法?JavaZipFile.getEntries怎麽用?JavaZipFile.getEntries使用的例子?那麽恭喜您,這裏精選的方法代碼示例…

    2025年11月21日
    4
  • SuperBlock损坏修复

    SuperBlock损坏修复SuperBlock 损坏修复 nbsp 大家可能遇到过这样的情况 root dhcp 0 142 mount dev sdb1 mnt sdb1mount wrongfstype badoption badsuperbloc dev sdb1 missingcodep

    2026年3月19日
    2
  • 字符数组初始化问题解法_字符数组和字符串的区别

    字符数组初始化问题解法_字符数组和字符串的区别在C语言编程中,当我们声明一个字符串数组的时候,常常需要把它初始化为空串。总结起来有以下三种方式:(1)chara[10]=””; (2)chara[10]={‘\0′}; (3)chara[10];str[0]=’\0’;第1,2种方式是将a数组的所有元素都初始化为’\0’,而第3种方式是只将str数组的第一个元素初始化为’\0’。如果数组的size非常大,那么前两种方式…

    2022年8月31日
    6
  • RocketMQ原理刨析

    RocketMQ原理刨析RocketMQ 原理本文类容基本上和 RocketMQdesi 类似 并无过多的改动 主要内容包括 RocketMQ 概述 主要是概念上的一些内容 RocketMQ 的特点以及消息发送 消费模型 RocketMQ 原理 mmap write 文件系统 数据存储结构 队列 刷盘策略 消息查询 消息过滤 事务消息 发送 订阅负载均衡 同步双写 异步复制 充分利用内存 消息堆积能力以及解决办法一 RocketMQ 概述 1 MessageFilte Broker 端消息过滤

    2026年3月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号