1,规范化错误处理和错误日志捕获非常重要;
2,用户需要知道的错误才会以错误形式返回给前端,而开发者层面的参数错误,异常,以及数据处理错误,则应该记录在错误日志中,未来通过结合redis的方式,给手机发送消息通知,及时告警
原理:
用target设定一些规则,尤其是categoys,是一个过滤规则,支持“*” 匹配,一般传入都是__METHOD__ 作为\Yii::trace($message, __METHOD__)第二个参数传入,这样该函数会调用配置的targets来进行循环匹配,将匹配到的日志模板,写入日志文件,邮件或者数据库中。
深入配置解读(错误存放在多文件中设置):
方法一(不推荐,不规范):
Yii::$app->log->targets[0]->logFile = Yii::getAlias('@runtime').DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR.'app2.log;
Yii::warning($message);
方法二:(推荐,遵照Java配置规范)
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
'logVars' => ['*'],
//'categories' => ['application'],
//'logFile' => '@runtime/logs/app.log',
],
[
'class' => 'yii\log\FileTarget',
'categories' => ['pay'],
'levels' => ['error', 'warning'],
'logVars' => ['*'],
'logFile' => '@runtime/logs/pay.log',
],
[
'class' => 'yii\log\FileTarget',
'categories' => ['order'],
'levels' => ['error', 'warning'],
'logVars' => ['*'],
'logFile' => '@runtime/logs/order.log',
],
],
]
/** 使用 **/
Yii::warning($message,'pay')
traceLevel解读:
这个一开始还理解错误了,这个在$e->getTraceAsString()时,提取的调用栈数量,YII_DEBUG模式下打印3层,非DEBUG模式只打印当前层,一开始我以为是错误级别,这里也提醒后面的学习者这个问题;
categories格式解读:
官方给的是一个带有星号的匹配模式:
除了这一种还有其他的吗?并且这个让我们误以为,只能根据当前函数的类来进行匹配日志target,实际上不是,如果你给了__METHOD__,它就会按照这个走,但如果你\YII::error($message, "pay") 这里给了具体的值,也是可以的。我们来看底层的匹配逻辑
except的案例:
官方配置案例:
对应源码结构:
日志结构解释:红框就是prefix前缀,最前面的时间是改变不了的
写入日志:
flushInterval是属于日志组件的属性:
日志export,也有数量限制,默认1000,在target类中有个exportInterval属性可以进行配置
将全局变量$_POST,$GET,$_SERVER写入到日志中
getMessagePrefix函数:
collect收集函数,往里面塞了什么?
$message[5] 是什么?是当时内存使用量
总结:
只需要关心targets的配置,而targets配置也不是特别复杂,就可以随时随地记录制定日志了,这点跟hyperf不一样,hyperf是指定你写日志,这个过程是主动的,并且很准确地告诉了系统,你要写那个日志,记录什么。
而yii2的模式是被动式,过程中你可以一直写日志,而是这条日志会不会被拦截并输出到指定文件中,邮箱中,或者数据库中,则取决于你的配置文件,但是整体系统却不会报错,这种设计模式是正确的。
什么意思呢?如果你写了一个\Yii::trace($message, __METHOD__),如果配置文件没有过滤该__METHOD__,则该事件直接忽略了,但如果是主动发起的话,很容易触发该日志配置找不到而抛异常。