2019-04-20 10:48:51 7107次浏览 4条回答 0 悬赏 10 金钱

请问一下 Yii2 日志操作(log)如何写入错误日志呢?

最佳答案

  • 灰太狼 发布于 2019-04-20 14:50 举报

    第一,日志是个组件,需要先配置在components下,配置如下:

    'components' => [
        'log' => [  //日志组件id
            'targets' => [  //targets是代表使用哪个方式存储日志,共有4个方式,下面是使用文件
                'error_file' => [  //error_file是自定义的,方便见名知道意思
                    'logFile' => '@admin/Runtime/logs/error.'.date('Ymd').'.log',//日志存放目录
                    'class' => 'yii\log\FileTarget', //指定使用4个方式其中之以的文件存储方式
                    'levels' => ['error'],//存放级别,错误级别的
                    'maxLogFiles' => 100,//最多存放的日志文件数
                ],
                'warning_file' => [
                    ...
                ],
                'info_file' => [
                    ...
                ]
            ]
        ]
    ]
    

    然后使用:Yii::info('信息!');

    既然说到了日志组件,不仅要知道怎么使用,还要知道他的实现原理:阐述一下个人见解,有错误请指出。

    yii框架在启动的时候已经加载里日志组件,(其实这里说日志组件是他确实是个组件,用来记录日志),但实际它加载的是另一个组件(日志分发器组件--我就这么叫的)
    在实例化这个分发器的时候会创建日志组件,注意这里会创建一个日志组件对象啊啊啊啊啊.
    多说两句:那么在哪里执行了这个 分发器的实例化呢?
    看你的配置main.php,是否有一项:'bootstrap' => ['log'],就是这个引导在框架启动的时候会执行。

    PS:创建日志组件时yii这里预留了一个扩展,就是在配置日志组件的时候,可以自己定义一个logger记录器
    $config['logger'];

    同时,把这个分发器对象给日志的dispatche属性(也就是在日志里可以使用分发器对象了)。
    然后我们 在使用 Yii::info('信息!'); 其实它执行的步骤是:

    public function info($message,$category = 'application')
    {
        static::getLogger()->log($message,Logger::LEVEL_INFO,$category);
    }
    
    //这里是获取一个日志对象,用来执行->log($日志信息)
    //这里是上面说的框架启动的时候会  创建一个日志组件对象啊啊啊啊啊  ,在执行Yii::info();还会执行,
    //因为初始户已经有了这个日志组件对象self::$_logger已经有值了,直接返回这个对象就行了。
    //
    public function getlogger()
    {
        if(self::$_logger !== null){
            return self::$_logger;
        } else {
            return self::$_logger = static::createObject('yii\log\Logger')
        }
    }
    

    日志对象有了就可以 ->log(); 执行了。

    public function log()
    {
        //主要是这句
        $this->flush();
    }
    
    public function flush($final = false)
    {
         //??$this->dispatcher 是在哪里来的?
         // 看上面介绍 -- 同时,同时,把这个分发器对象给日志的dispatche属性
         //所以 $this->dispatche就是 Dispatche对象了
        if($this->dispatcher instanceof Dispatcher){
            $this->dispatcher->dispatch($message,$final)
        }
    }
    

    下面的就一直调用下去就行了

    public function dispatch()
    {
        //这里就是循环你配置的那个日志组件数组;
        foreach($this->targets as $target){
            $target->collect($message,$final);//调用基类
            //后面不写了自己去基类看吧,
            //基类调用子类重写的exprot();输出了日志;
        }
    }
    
您需要登录后才可以回答。登录 | 立即注册
PHP学院的中学生
副总裁

PHP学院的中学生

注册时间:2018-10-23
最后登录:2024-04-07
在线时长:168小时1分
  • 粉丝29
  • 金钱4730
  • 威望30
  • 积分6710

热门问题