PHP自定义业务日志(monolog源码学习)

聊聊自己从开始工作到如今,对日志的认识。

在离校实习前,也多多少少做过一些自个玩的项目,后台管理系统、公众号都有整过,对所谓的日志没有什么概念,需要做什么记录都是操作数据库的自定义log表。

开始实习后,慢慢有接触到一些所谓日志的概念,最先接触的是ThinkPHP3.1的框架,不过有使用到的都是自定义打印日志,对想要记录的数组写入到自定义日志文件里。比如每次想要打印数据,调用一个公共函数,依赖系统函数fopen、fwrite、fclose,日志文件名以日期加调用方法名定义。

 

随着一天天的使用,到了某一日,也许是觉得这样的日志都集中在一个目录下,数量太过庞大;也许是觉得一个日志文件写入内容太多,如果是通过浏览器访问日志文件要等待特别久时间,甚至会卡死;也许是发现业务日志即调用即写入的方法,在并发量不低的情况下,导致不同用户的日志内容混杂,不利于排错;也许是发现了TP3.1项目Runtime内的代码执行LOG随时间、又随日志大小切割很好用;也许是看了TP3.1源码打印日志的部分,发现日志还能这么用。

也忘了具体是什么原因了,也许是一个个原因的积累,总之决定换个日志记录方式。

 

看了下TP3.1源码的日志实现部分,两个部分让我感觉像是发现了新大陆,一个是register_shutdown_function函数(细节不说明了,另外的博客里有详细解释),一个是每次调用日志,都将内容存在一个数组增量内,即保存在内存,在所有业务逻辑执行完成后,register_shutdown_function函数注册的方法将被执行,在此处将日志刷新到日志文件内,同时具体输出到哪个日志文件呢?这个也有讲究,首先日志文件名也是按照年月日来命令,但是在输出前,会优先判断当前日志文件的大小,若超过预定义最大值,则将当前文件重命名,加上时间戳的前缀来标识,新生成日志文件来存储日志。这种实现方式的好处在于,日志大容量被切割成多个文件,避免一个文件过大。个人认为也有不好的地方,比如所有日志文件都存储一个目录下,随着时间增长这个目录的文件数会越来越多。

日志暂存储在内存,封装后一次调用error_log函数打印。现在说来可能只是个基础的概念,不过对当时的自己来说,确实觉得神奇了好久。

想自己重新实现一种打印日志的方式,首先要满足几点要求:

1、日志能满足大小超过设置最大值后进行切割;

2、单个用户的请求日志,不会被并发影响,保证每次的排错日志相邻内容都是一个用户的;

3、可以根据不同的业务模块打印日志;

4、日志文件存储目录与日期相关,保证一个目录文件数不会太多,同时想定位到指定日期日志方便查找。

 

日志工具类实现源码:

<?php
class LogModel {
    static $logArr = array();
    static $logRootPath = '';
    static $class = '';
    static $method = '';

    /**
     * 日志工具初始化
     * */
    public static function init() {
        //获取日志文件目录
        if (empty(self::$logRootPath)) self::$logRootPath = realpath(APP_PATH.'Log') . DIRECTORY_SEPARATOR;
    }
    /**
     * 日志内容保存
     * @static
     * @access public
     * @param  $logName  日志模块名称
     * @param  $content  日志内容
     * @param  $logTitle 日志内容头部
     * @return void
     * */
    public static function writeLog($content, $logName = 'Common', $logFile = 'common', $logTitle = '') {
        //获取日志文件目录
        if (empty(self::$logRootPath)) self::$logRootPath = realpath(APP_PATH.'Log') . DIRECTORY_SEPARATOR;

        if (empty(self::$logArr[$logName][$logFile])) {
            self::$logArr[$logName][$logFile] = '----------------start---------------------'.PHP_EOL;
        }
        if (is_array($content)) {
            if(version_compare(PHP_VERSION,'5.4.0','<')){
                $tempStr = json_encode($content);
                $content = preg_replace_callback("#\\\u([0-9a-f]{4})#i",function($matchs)                            {
                    return iconv('UCS-2BE', 'UTF-8', pack('H4', $matchs[1]));
                },$tempStr);
            } else $content = json_encode($content, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
        }

        if (!empty($logTitle)) $logTitle .= ':';
        self::$logArr[$logName][$logFil
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值