全面解读PHP的Yii框架中的日志功能
Yii页面级日志开启在 Main.php中 log段添加、 下面显示页面日志 array( 'class'=>'CWebLogRoute','levels'=>'trace',//级别为trace 'categories'=>'system.db.*' //只显示关于数据库信息,包括数据库连接,数据库执行语句 ), 完整如下: array( 'class'=>'CLogRouter','routes'=>array( array( 'class'=>'CFileLogRoute','levels'=>'error,warning',),// 下面显示页面日志 array( 'class'=>'CWebLogRoute',//级别为trace 'categories'=>'system.db.*' //只显示关于数据库信息,数据库执行语句 ),// uncomment the following to show log messages on web pages /* array( 'class'=>'CWebLogRoute',*/ ),
扩展 Yii2 自带的日志组件/**
use Yii; class FileTarget extends yiilogFileTarget
/**
private $_logFilePath = ''; public function init()
} 在配置文件中这样使用: [ 'log' => [ 'traceLevel' => YII_DEBUG ? 3 : 0,'targets' => [ /** * 错误级别日志:当某些需要立马解决的致命问题发生的时候,调用此方法记录相关信息。 * 使用方法:Yii::error() */ [ 'class' => 'commoncomponentsFileTarget',// 日志等级 'levels' => ['error'],// 被收集记录的额外数据 'logVars' => ['_GET','_POST','_FILES','_COOKIE','_SESSION','_SERVER'],// 指定日志保存的文件名 'logFile' => '@app/runtime/logs/error/app.log',// 是否开启日志 (@app/runtime/logs/error/20151223_app.log) 'enableDatePrefix' => true,'maxFileSize' => 1024 * 1,'maxLogFiles' => 100,],/** * 警告级别日志:当某些期望之外的事情发生的时候,使用该方法。 * 使用方法:Yii::warning() */ [ 'class' => 'commoncomponentsFileTarget',// 日志等级 'levels' => ['warning'],// 指定日志保存的文件名 'logFile' => '@app/runtime/logs/warning/app.log',// 是否开启日志 (@app/runtime/logs/warning/20151223_app.log) 'enableDatePrefix' => true,/** * info 级别日志:在某些位置记录一些比较有用的信息的时候使用。 * 使用方法:Yii::info() */ [ 'class' => 'commoncomponentsFileTarget',// 日志等级 'levels' => ['info'],// 指定日志保存的文件名 'logFile' => '@app/runtime/logs/info/app.log',// 是否开启日志 (@app/runtime/logs/info/20151223_app.log) 'enableDatePrefix' => true,/** * trace 级别日志:记录关于某段代码运行的相关消息。主要是用于开发环境。 * 使用方法:Yii::trace() */ [ 'class' => 'commoncomponentsFileTarget',// 日志等级 'levels' => ['trace'],// 指定日志保存的文件名 'logFile' => '@app/runtime/logs/trace/app.log',// 是否开启日志 (@app/runtime/logs/trace/20151223_app.log) 'enableDatePrefix' => true,yii日志的逻辑Yii使用层次的日志处理机制,即日志的收集与日志最终的处理(如显示、保存到文件、保存到数据数)是分离的。 日志信息的收集由CLogger(日志记录器)完成,而日志信息的分发处理,则在CLogRouter的调度(称为日志路由管理器)下,分发给处理对象(如CFileLogRoute以及logging目录下继承自CLogRoute的类,称为日志处理器),经过反复阅读其源代码,我更是为Yii的设计思想所折服,如此的分层处理,使得其易于灵活扩展。 而日志信息有级别之分,如普通的info,profile,trace,warning,error级别,可以在日志路由中设置过虑条件,如设置CFileRoute的levels属性,即可只处理指定级别的日志信息。 如在程序中调用:对应的流程可能如下:
问题:日志是在何时被写入文件的?经过反复跟踪,我发现在CLogRouter类的init方法中为Application对象的OnEndRequest事件绑定处理器CLogRouter::processLogs()。同时也给Yii::$_logger的onFlush事件绑定事件处理器CLogRouter::collectLogs方法,用于在Yii::log()中当日志消息量过多时,及时将日志刷新写入文件。代码如下:_routes as $name=>$route) {
$route=Yii::createComponent($route);
$route->init();
$this->_routes[$name]=$route;
}
Yii::getLogger()->attachEventHandler('onFlush',array($this,'collectLogs'));
Yii::app()->attachEventHandler('onEndRequest','processLogs'));}
而在CApplication::run()方法中定义了: hasEventHandler('onEndRequest')) { $this->onEndRequest(new CEvent($this)); }到这里我们可以理解CLogger (Yii::$_logger)仅仅是将日志进行收集(记录到内容结构之中),然后在程序结束时,由$app对象调用CLogRouter的processLogs进行日志的处理。Yii支持日志多道路由,比如:同一份日志即可写入至文件,又可显示到页面上,甚至同时以电子邮件发送,更甚至同时记录到数据库中,这是由配置文件中的log:routes配置实现的,为log:routes配置多个元素,实现多个路由分发。日志信息的过滤,记录均是由最终的日志处理器处理。 日志处理器要完成的任务主要包含以下几点: 从CLogger中取得所有日志,并进行过滤(主要是levels,categories两项定义log:routes:levels/categories) 先进行过滤参考CFileLogRoute::collectLogs()中的逻辑: getLogs($this->levels,$this->categories); //执行过滤,只得到期望信息日志过滤已经完成接下来就要对日志进行最终处理(如写入到文件,记录至数据库等) 但这个函数之中,有个小bug,只判断日志目录是否可写,没有判断日志文件本身是否可写.CFileLogRoute实现了类似Linux的日志轮换功能(LogRoate),并规定了日志文件的大小,考虑得很周到,很完善! 我也要向其学习并吸收其思想! protected/config/main.php中的配置: array('log'),components => array( 'log'=>array( 'class'=>'CLogRouter','routes'=>array( array( 'class'=>'CFileLogRoute',trace',) ) )定义log组件需要预先加载(实例化)。配置使用CLogRouter作为日志路由管理器,并设置了其日志路由处理器(routes属性)及其配置属性。而preload,log属性的定义,均要应用到CWebApplication对象上(请参阅CApplication::__construct中的configure调用,configure从CModule继承而来)。而在CWebApplication的构造函数中执行preloadComponents(),就创建了log对象(即CLogRouter的实例)。 创建并初始化一个组件时,实际上调用的是CModule::getComponent,这个调用中使用YiiBase::createComponent创建组件对象,并再调用组件的init初始化之。 再阅读CLogRouter::init()过程,在这里有两个关键之处,一是创建日志路由处理器(即决定日志的最终处理方式:写入文件,邮件发送等等),二是给应用程序对象绑定onEndRequest事件处理CLogRouter::processLogs()。而在CApplication::run()确实有相关代码用于运行onEndRequest事件处理句柄: hasEventHandler('onEndRequest')) { $this->onEndRequest(new CEvent($this)); }也就是说,日志的最终处理(比如写入文件,系统日志,发送邮件)是发生在应用程序运行完毕之后的。Yii使用事件机制,巧妙地实现了事件与处理句柄的关联。 也就是说,当应用程序运行完毕,将执行CLogRouter::processLogs,对日志进行处理,。CLogRouter被称之为日志路由管理器。每个日志路由处理器从CLooger对象中取得相应的日志(使用过滤机制),作最终处理。 具体而言Yii的日志系统,分为以下几个层次: (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
