Yii2 之日志实践总结

▪ 前言

Yii2 详细的日志使用参见 官方教程,这里我们仅对 Yii2 日志相关的疑难问题做些笔记以及在人性化方面做一点点的小改造。

▪ 消息跟踪级别

在官方教程中有个 消息跟踪级别 的配置:

'components' => [
    'log' => [
        'traceLevel' => YII_DEBUG ? 3 : 0,
        'targets' => [...],
    ],
],

官方的说明是:上面的应用配置设置了 yii\log\Dispatcher::traceLevel 的层级,假如 YII_DEBUG 开启则是3,否则是0。 这意味着,假如 YII_DEBUG 开启,每个日志消息在日志消息被记录的时候, 将被追加最多3个调用堆栈层级;假如 YII_DEBUG 关闭, 那么将没有调用堆栈信息被包含。

但是在实际测试中发现无论 traceLevel 设置为什么值,错误日志的 Stack trace 还是全部输出,而并非只有3条:

==================================================
2017-06-17 06:37:56 [IP:127.0.0.1] [UID:-] [SID:-]
==================================================
[error][yii\base\ErrorException:4] exception 'yii\base\ErrorException' with message 'syntax error, unexpected 'return' (T_RETURN)' in D:\Development\wamp\www\lengdo.new\frontend\modules\kernel\controllers\IndexController.php:37
Stack trace:
#0 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Module.php(633): ::spl_autoload_call()
#1 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Module.php(633): ::class_exists()
#2 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Module.php(591): yii\base\Module->createControllerByID()
#3 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Module.php(583): yii\base\Module->createController()
#4 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Module.php(517): yii\base\Module->createController()
#5 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\web\Application.php(102): yii\base\Module->runAction()
#6 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Application.php(380): yii\web\Application->handleRequest()
#7 D:\Development\wamp\www\lengdo.new\frontend\web\index.php(17): yii\base\Application->run()
#8 {main}

一直没解决,知道的朋友分享下这个 traceLevel 究竟是指什么?

▪ 美化日志格式

默认,我们一般配置日志的输出目标为 FileTarget

# main.php

'components' => [
    'log' => [
        'targets' => [
            [
                'class' => 'yii\log\FileTarget',
                'levels' => ['error', 'warning'],
            ]
        ],
    ],
],

yii\log\FileTarget 默认将日志信息记录在 Yii::$app->getRuntimePath().'/logs/app.log' 文件里,内容大概如下:

2017-06-15 09:29:28 [-][1][9sc6291lqmftgo2pnjgfu69h44][error][yii\base\UnknownPropertyException] exception 'yii\base\UnknownPropertyException' with message 'Getting unknown property: frontend\modules\kernel\controllers\IndexController::aa' in D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Component.php:147
Stack trace:
#0 D:\Development\wamp\www\lengdo.new\frontend\modules\kernel\controllers\IndexController.php(37): yii\base\Component->__get('aa')
#1 [internal function]: frontend\modules\kernel\controllers\IndexController->actionIndex()
#2 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\InlineAction.php(57): call_user_func_array(Array, Array)
#3 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Controller.php(156): yii\base\InlineAction->runWithParams(Array)
#4 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Module.php(523): yii\base\Controller->runAction('index', Array)
#5 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\web\Application.php(102): yii\base\Module->runAction('kernel/index/in...', Array)
#6 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Application.php(380): yii\web\Application->handleRequest(Object(yii\web\Request))
#7 D:\Development\wamp\www\lengdo.new\frontend\web\index.php(17): yii\base\Application->run()
#8 {main}
2017-06-15 09:29:28 [-][1][9sc6291lqmftgo2pnjgfu69h44][info][application] $_GET = [
    'r' => 'kernel/index/index'
]

......

上述的内容里显示了两条错误的详细信息,第一眼真的很难区分哪几个信息是属于一条错误的、哪行开始是另一条错误的。尤其在很多条错误的的时候就更难区分了。

出于上述的考虑,需要基于 FileTarget 重新美化日志信息的输出格式,美化后效果如下:

===========================================================================
2017-06-15 09:29:28 [IP:127.0.0.1] [UID:1] [SID:9sc6291lqmftgo2pnjgfu69h44]
===========================================================================
[error][yii\base\UnknownPropertyException] exception 'yii\base\UnknownPropertyException' with message 'Getting unknown property: frontend\modules\kernel\controllers\IndexController::aa' in D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Component.php:147
Stack trace:
#0 D:\Development\wamp\www\lengdo.new\frontend\modules\kernel\controllers\IndexController.php(36): yii\base\Component->__get('aa')
#1 [internal function]: frontend\modules\kernel\controllers\IndexController->actionIndex()
#2 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\InlineAction.php(57): call_user_func_array(Array, Array)
#3 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Controller.php(156): yii\base\InlineAction->runWithParams(Array)
#4 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Module.php(523): yii\base\Controller->runAction('index', Array)
#5 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\web\Application.php(102): yii\base\Module->runAction('kernel/index/in...', Array)
#6 D:\Development\wamp\www\lengdo.new\vendor\yiisoft\yii2\base\Application.php(380): yii\web\Application->handleRequest(Object(yii\web\Request))
#7 D:\Development\wamp\www\lengdo.new\frontend\web\index.php(17): yii\base\Application->run()
#8 {main}


===========================================================================
2017-06-15 09:29:28 [IP:127.0.0.1] [UID:1] [SID:9sc6291lqmftgo2pnjgfu69h44]
===========================================================================
[info][application] $_GET = [

.....

美化的核心代码:

# main.php

'components' => [
    'log' => [
        'targets' => [
            [
                'class' => 'common\log\FileTargetExtend',
                'levels' => ['error', 'warning'],
            ]
        ],
    ],
],
# common\log\FileTargetExtend.php

<?php
namespace common\log;

use Yii;
use yii\web\Request;
use yii\log\FileTarget;

/**
 * FileTarget 扩展
 * 由于 Yii2 的 FileTarget 在记录日志时其输出信息格式不是很便于阅读
 * 所以此处基于 FileTarget 类创建一个扩展类,主要功能就是重新格式化输出的信息,便于阅读
 */
class FileTargetExtend extends FileTarget
{
    /**
     * 格式化消息
     *
     * @param array $message  原始消息
     * @return string
     */
    public function formatMessage( $message )
    {
        // 重构消息
        $message = explode("\n", parent::formatMessage($message));
        $message[0] = str_pad('',strlen($message[0]),'=')."\n".$message[0]."\n".str_pad('',strlen($message[0]),'=');

        // 返回消息
        return implode($message,"\n")."\n\n";
    }

    /**
     * 构建消息的前戳
     *
     * @param array $message  原始消息
     * @return string
     */
    public function getMessagePrefix( $message )
    {
        if( $this->prefix !== null ) return call_user_func($this->prefix, $message);
        if( Yii::$app === null ) return '';

        $request = Yii::$app->getRequest();
        $ip = $request instanceof Request ? $request->getUserIP() : '-';

        /* @var $user \yii\web\User */
        $user = Yii::$app->has('user', true) ? Yii::$app->get('user') : null;
        $userID = $user && ($identity = $user->getIdentity(false)) ? $identity->getId() : '-';

        /* @var $session \yii\web\Session */
        $session = Yii::$app->has('session', true) ? Yii::$app->get('session') : null;
        $sessionID = $session && $session->getIsActive() ? $session->getId() : '-';

        return "[IP:$ip] [UID:$userID] [SID:$sessionID]\n";
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值