`
OrangeHolic
  • 浏览: 259527 次
  • 来自: 北京
社区版块
存档分类
最新评论

Yii的log分析

    博客分类:
  • Yii
Yii 
阅读更多
我们可以通过Yii的日志级别和信息分类进行归类,所选的信息还可以进一步设置信息路由到答不同的目的地,例如一个文件,数据库,Email,浏览器窗口等。

日志级别有:

*      trace: 这是在 Yii::trace 中使用的级别。它用于在开发中 跟踪程序的执行流程。
*      info: 这个用于记录普通的信息。
*      profile: 这个是性能概述(profile)。下面马上会有更详细的说明。
*      warning: 这个用于警告(warning)信息。
*      error: 这个用于致命错误(fatal error)信息。

在 Yii 中,有下列几种日志路由可用:

* CDbLogRoute: 将信息保存到数据库的表中。
* CEmailLogRoute: 发送信息到指定的 Email 地址。
* CFileLogRoute: 保存信息到应用程序 runtime 目录中的一个文件中。
* CWebLogRoute: 将 信息 显示在当前页面的底部。
* CProfileLogRoute: 在页面的底部显示概述(profiling)信息。

信息可以通过 Yii::log 或 Yii::trace 记录。其 区别是后者只在当应用程序运行在 调试模式(debug mode) 中时才会记录信息。
Yii::log($message, $level, $category);
Yii::trace($message, $category);


示例:
需先在main.php中进行配置,例子选择将日志存储在文件(系统默认为webapp\protected\runtime\application.log)中,为只存储trace和error级别,过滤以orange开始的log。
'components'=>array(
     ...............
     'log'=>array(
               'class'=>'CLogRouter',
               'routes'=>array(
                    array(
                         'class'=>'CFileLogRoute',
                         'levels'=>'trace,error',
                         'categories'=>'orange.*'
                    ),
               ),
          ),
     ...............
)

 
在控制器中定义方法并执行,在此为OrangeController控制器
 public function actionTest(){
        Yii::log('This is a  trace log','trace','orange.test');
    }

执行以后可在日志文件中看到我们的trace信息,为
2012/09/28 15:40:11 [trace] [orange.test] This is a  trace log
in D:\PHP\www\yii\orange\protected\controllers\OrangeController.php (24)



Yii的日志主要由CLogger,CLogRoute,CLogRouter三类来完成,其中CLogger在内存中记录日志信息,CLogRoute用不同的方式处理日志信息,CLogRouter将CLogger记录的信息发送给各个CLogRoute进行处理。类图如下:

在此简单介绍一下路由的整个过程:
1.Yii类中CLogger的实例化,调用 Yii::log('This is a  trace log','trace','orange.test');时,Yii类(其实是YiiBase是如何反应的。
代码路径:framework\YiiBase.php#461
public static function log($msg,$level=CLogger::LEVEL_INFO,$category='application')
     {
          if(self::$_logger===null)
               self::$_logger=new CLogger;//如果_logger为null,则实例化Clogger类
          if(YII_DEBUG && YII_TRACE_LEVEL>0 && $level!==CLogger::LEVEL_PROFILE)
          {
            // YII_TRACE_LEVEL 设置backtrace 显示的内容条数,
            //这个常量会在debug_backtrace 函数返回信息中,获取指定条数,
            //如果为0(默认) 则为全部显示
               $traces=debug_backtrace();
               //debug_backtrace() 函数生成一个 backtrace,返回关联数组的数组,可以参考文档
               $count=0;
               foreach($traces as $trace)
               {
                    if(isset($trace['file'],$trace['line']) && strpos($trace['file'],YII_PATH)!==0)
                    {
                         $msg.="\nin ".$trace['file'].' ('.$trace['line'].')';
                         if(++$count>=YII_TRACE_LEVEL)
                              break;
                    }
               }
          }
          self::$_logger->log($msg,$level,$category);//调用_logger的方法处理日志
     }

主要功能就是上下2条语句。
2.CLogger的log方法
class CLogger extends CComponent
{
     const LEVEL_TRACE='trace';
     const LEVEL_WARNING='warning';
     const LEVEL_ERROR='error';
     const LEVEL_INFO='info';
     const LEVEL_PROFILE='profile';
     .......................
    public function log($message,$level='info',$category='application')
     {
        //保存日志(日志为一个数组,包括信息、级别、过滤、发生时间4内容)
          $this->_logs[]=array($message,$level,$category,microtime(true));
          //记录的日志个数自增1
          $this->_logCount++;
        //autoFlush为整数,表示在它们被刷新到目录前多少信息应该被记录。
        //默认到10,000, 意味着每10,000条信息,这个flush方法自动被发起一次信息。
        //如果为0,它意味着信息不会被自动刷新,一直保存到_logs[]中,直到调用raise onFlush事。
        //_processing表示我们是否正在处理log
          if($this->autoFlush>0 && $this->_logCount>=$this->autoFlush && !$this->_processing)
          {
               $this->_processing=true;
            //autoDump默认时,这个属性为false,意味着每次flush()日志之后已经过滤的信息仍然保存在内在中。
            //如果为true,已过滤的信息被保存在实际的媒介中
               $this->flush($this->autoDump);
               $this->_processing=false;
          }
     }
  ...........................
     public function flush($dumpLogs=false)
     {
          $this->onFlush(new CEvent($this, array('dumpLogs'=>$dumpLogs)));
          $this->_logs=array();//清空日志
          $this->_logCount=0;
     }

     public function onFlush($event)
     {
        //唤醒绑定在onFlush事件处理函数
          $this->raiseEvent('onFlush', $event);
     }
................................
}

3.绑定在onFlush事件处理函数
这是我们的CLogRouter就出场了,CWebApplication根据mian.php中的配置实例化CLogRouter,并执行其init方法
class CLogRouter extends CApplicationComponent
{
     private $_routes=array();
     public function init()
     {
          parent::init();
          foreach($this->_routes as $name=>$route)
          {
            //读取各个CLogRoute的配置,实例化
               $route=Yii::createComponent($route);
            //调用各个CLogRoute的init方法
               $route->init();
            //保存各个CLogRoute到_routes中
               $this->_routes[$name]=$route;
          }
        //给CLogger onFlush事件绑定处理函数,为本类的collectLogs方法
          Yii::getLogger()->attachEventHandler('onFlush',array($this,'collectLogs'));
         //给CWebApplication  onEndRequest事件绑定处理函数,为本类的processLogs方法
          Yii::app()->attachEventHandler('onEndRequest',array($this,'processLogs'));
     }
    ..........................
     //收集log
   public function collectLogs($event)
     {
          $logger=Yii::getLogger();
          $dumpLogs=isset($event->params['dumpLogs']) && $event->params['dumpLogs'];
          foreach($this->_routes as $route)
          {
               if($route->enabled)
                    //调用各个CLogRoute的collectLogs到记录所有日志的CLogger类中按照
                   //自己的level和categories取出自己处理的log,也可立刻处理log(这也要看dumplogs的真假,为真则为立即处理)
                    $route->collectLogs($logger,$dumpLogs);
          }
     }
  //收集处理log
     public function processLogs($event)
     {
          $logger=Yii::getLogger();
          foreach($this->_routes as $route)
          {
               if($route->enabled)
                    //同上,但是此处为立刻处理log
                    $route->collectLogs($logger,true);
          }
     }
..................
}


4.调用各个CLogRoute处理日志,CLogRoute的collectLogs方法
abstract class CLogRoute extends CComponent
{
       public $levels='';//过滤log用
       public $categories='';//过滤log用
       ........................
      public function collectLogs($logger, $processLogs=false)
     {
          //按照过滤条件到CLogger中去log
          $logs=$logger->getLogs($this->levels,$this->categories);
          $this->logs=empty($this->logs) ? $logs : array_merge($this->logs,$logs);
          //如果设置要立刻处理
          if($processLogs && !empty($this->logs))
          {
               if($this->filter!==null)
                    Yii::createComponent($this->filter)->filter($this->logs);
               if($this->logs!==array())
                    //处理
                    $this->processLogs($this->logs);
               $this->logs=array();
          }
     }

     /**
     *处理日志信息并发送它们到指定的目标。 派生子类必须实现这个方法。
     *$logs为信息列表。每一个数组元素表示一个信息, 有下面的结构: array(
     *[0] => message (string)
     *[1] => level (string)
     *[2] => category (string)
     *[3] => timestamp (float, 从 microtime(true)获取)
     *  )
     */
     abstract protected function processLogs($logs);
  ........................
}


  其中CDbLogRoute实现方式为

   
 protected function processLogs($logs)
     {
          $command=$this->getDbConnection()->createCommand();
          foreach($logs as $log)
          {
               //遍历数组插入到数据库
               $command->insert($this->logTableName,array(
                    'level'=>$log[1],
                    'category'=>$log[2],
                    'logtime'=>(int)$log[3],
                    'message'=>$log[0],
               ));
          }
     }









  • 大小: 59.8 KB
分享到:
评论
1 楼 xq_blessing 2012-09-29  
Yii framework非常好的php框架,偶也正在研究中!学习了

相关推荐

    YII2框架中日志的配置与使用方法实例分析

    主要介绍了YII2框架中日志的配置与使用方法,结合实例形式分析了YII2框架中日志的功能、配置方法及使用相关操作技巧,需要的朋友可以参考下

    Yii2实现log输出到file及database的方法

    主要介绍了Yii2实现log输出到file及database的方法,结合实例形式分析了Yii2日志输出到文件及数据库的相关设置与实现技巧,需要的朋友可以参考下

    Yii2框架中日志的使用方法分析

    Yii::log($message, $level, $category); Yii::trace($message, $category); 后者仅在调试模式下记录日志。 这里的log方法是YiiBase的静态方法。 在Yii2中,面向对象的设计贯彻得更加彻底,日志记录功能被转移到...

    Yii2框架配置文件(Application属性)与调试技巧实例分析

    本文实例讲述了Yii2框架配置文件(Application属性)与调试技巧。分享给大家供大家参考,具体如下: 配置文件 ... 'bootstrap' => ['log'], 'components' => [ 'request' => [ // !!! insert a secret key

    yii2-mougrim-logger

    该扩展提供了所有期望分析的日志。好处具有下一个优点: 灵活的配置; 类似于Apache log4php的界面(具有调试日志级别); 高于yii2记录器性能。 有关更多信息和基准测试结果,请参见。安装安装此扩展的首选方法是...

    Yii框架弹出窗口组件CJuiDialog用法分析

    本文实例讲述了Yii框架弹出窗口组件CJuiDialog用法。分享给大家供大家参考,具体如下: CJuiDialog组件在手册zii.widgets.jui下 在视图下使用以下代码 $this->beginWidget('zii.widgets.jui.CJuiDialog', array( ...

    YII Framework框架教程之日志用法详解

    YII中的日志很好很强大,允许你把日志信息存放到数据库,发送到制定email,存放咋文件中,意见显示页面是,甚至可以用来做性能分析。 YII中日志的基本配置:/yii_dev/testwebap/protected/config/main.php 'log'=>...

    Yii框架在页面输出执行sql语句以方便调试的实现方法

    本文实例讲述了Yii框架在页面输出执行sql语句以方便调试的实现方法。分享给大家供大家参考。具体分析如下: 我们使用:yiidebugtb来调试(因为用他界面比较美观,不影响界面其他元素)。 1.下载yiidebugtb,并且放入...

    解决File size limit exceeded 错误的方法

    开始分析,不可能是Yii框架的问题,此乃linux操作系统异常问题与框架无光,也不是 日志文件大小,仔细查看了所有设置的log路径下的文件,均小的可以忽略,即使是将Yii的debug关掉,也出现了相同的问题。 那么换个...

    MySQL的慢查询与常见的查找方法(顺序查找,二分查找)

    目录: 慢查询 常见慢查询优化 ...直接分析mysql慢查询日志 ,利用explain关键字可以模拟优化器执行SQL查询语句,来分析sql慢查询语句 例如:执行EXPLAIN SELECT * FROM res_user ORDER BYmodifiedtime L

Global site tag (gtag.js) - Google Analytics