不积跬步无以至千里

记录精彩的程序人生

  • 首页
  • Java
  • Golang
  • PHP
  • Python
  • Nodejs
  • Lua
  • Docker
  • DevOps
  • 文章归档
  • 默认分类
  • 关于
  • 标签

  • 搜索
PostgreSQL hbase 时间同步 nexus 开机启动 nexus, 开机启动 jenkins安装配置 gitlab安装配置 gitlab安装 文件系统 fastdfs gcc切换 gcc升级 mysql8 交换空间 虚拟内存 tcp thrift lua tag test VPN SoftEtherVPN homebrew asm spring tomcat maven jdk ios mac 图案字符 figlet mysql半同步复制 mysql主从同步 一主多从 一主一从 主从同步 反向代理 密码重置 test 虚拟机扩容 swap 虚拟空间 docker ldocker grpc-gateway protobuf 微服务 go grp GRPC 授权登录 OAuth2.0 SOA supervisord supervisor RPC CentOS rabbitmq 环境变量 php-fpm php.ini error php7 lnmp 编译安装 mysql nginx linux java php python redis 字符串操作 mysql5.7 Solo

Yii日志记录

发表于 2020-12-24 | 分类于 默认分类 | 0 | 阅读次数 1704

Yii的自带组件有一个很实用的日志记录组件,使用方法可以参考Yii官方文档:http://www.yiiframework.com/doc/guide/1.1/zh_cn/topics.logging,在文档中提到,只要我们在应用程序配置文件中配置了log组件,那么就可以使用

Php代码  收藏代码
  1. Yii::log($msg, $level, $category);

进行日志记录了。 配置项示例如下:

Php代码  收藏代码
  1. array(
  2. ......
  3. 'preload'=>array('log'),
  4. 'components'=>array(
  5. ......
  6. 'log'=>array(
  7. 'class'=>'CLogRouter',
  8. 'routes'=>array(
  9. array(
  10. 'class'=>'CFileLogRoute',
  11. 'levels'=>'trace, info',
  12. 'categories'=>'system.*',
  13. ),
  14. array(
  15. 'class'=>'CEmailLogRoute',
  16. 'levels'=>'error, warning',
  17. 'emails'=>'admin@example.com',
  18. ),
  19. ),
  20. ),
  21. ),
  22. )

log组件的核心是CLogRouter,如果想使用多种方式记录日志,就必须配置routes,可用的route有: •    CDbLogRoute: 将信息保存到数据库的表中。 •    CEmailLogRoute: 发送信息到指定的 Email 地址。 •    CFileLogRoute: 保存信息到应用程序 runtime 目录中的一个文件中。 •    CWebLogRoute: 将 信息 显示在当前页面的底部。 •    CProfileLogRoute: 在页面的底部显示概述(profiling)信息。 下面分析一下log的实现: 首先看一下CLogRouter的代码:

Php代码  收藏代码
  1. /**
  2. * Initializes this application component.
  3. * This method is required by the IApplicationComponent interface.
  4. */
  5. public function init()
  6. {
  7. parent::init();
  8. foreach($this->_routes as $name=>$route)
  9. {
  10. //初始化从配置文件读取的route,保存在成员变量里
  11. $route=Yii::createComponent($route);
  12. $route->init();
  13. $this->_routes[$name]=$route;
  14. }
  15. //绑定事件,如果触发了一个onFlush事件,则调用CLogRouter的collectLogs方法
  16. Yii::getLogger()->attachEventHandler('onFlush',array($this,'collectLogs'));
  17. //绑定事件,如果触发了一个onEndRequest事件,则调用ClogRouter的processLogs方法
  18. Yii::app()->attachEventHandler('onEndRequest',array($this,'processLogs'));
  19. }
  20. /**
  21. * Collects log messages from a logger.
  22. * This method is an event handler to the {@link CLogger::onFlush} event.
  23. * @param CEvent $event event parameter
  24. */
  25. public function collectLogs($event)
  26. {
  27. $logger=Yii::getLogger();
  28. //调用每个route的collectLogs方法
  29. foreach($this->_routes as $route)
  30. {
  31. if($route->enabled)
  32. $route->collectLogs($logger,false);
  33. }
  34. }

接着,我们看一下在调用Yii::log();时,发生了什么:

Php代码  收藏代码
  1. /**
  2. * Logs a message.
  3. * Messages logged by this method may be retrieved via {@link CLogger::getLogs}
  4. * and may be recorded in different media, such as file, email, database, using
  5. * {@link CLogRouter}.
  6. * @param string $msg message to be logged
  7. * @param string $level level of the message (e.g. 'trace', 'warning', 'error'). It is case-insensitive.
  8. * @param string $category category of the message (e.g. 'system.web'). It is case-insensitive.
  9. */
  10. public static function log($msg,$level=CLogger::LEVEL_INFO,$category='application')
  11. {
  12. if(self::$_logger===null)
  13. self::$_logger=new CLogger;
  14. if(YII_DEBUG && YII_TRACE_LEVEL>0 && $level!==CLogger::LEVEL_PROFILE)
  15. {
  16. $traces=debug_backtrace();
  17. $count=0;
  18. foreach($traces as $trace)
  19. {
  20. if(isset($trace['file'],$trace['line']) && strpos($trace['file'],YII_PATH)!==0)
  21. {
  22. $msg.="nin ".$trace['file'].' ('.$trace['line'].')';
  23. if(++$count>=YII_TRACE_LEVEL)
  24. break;
  25. }
  26. }
  27. }
  28. 调用CLogger的log方法
  29. self::$_logger->log($msg,$level,$category);
  30. }

继续看CLogger:

Php代码  收藏代码
  1. class CLogger extends CComponent
  2. {
  3. const LEVEL_TRACE='trace';
  4. const LEVEL_WARNING='warning';
  5. const LEVEL_ERROR='error';
  6. const LEVEL_INFO='info';
  7. const LEVEL_PROFILE='profile';
  8. /**
  9. * @var integer how many messages should be logged before they are flushed to destinations.
  10. * Defaults to 10,000, meaning for every 10,000 messages, the {@link flush} method will be
  11. * automatically invoked once. If this is 0, it means messages will never be flushed automatically.
  12. * @since 1.1.0
  13. */
  14. public $autoFlush=10000;
  15. ……
  16. /**
  17. * Logs a message.
  18. * Messages logged by this method may be retrieved back via {@link getLogs}.
  19. * @param string $message message to be logged
  20. * @param string $level level of the message (e.g. 'Trace', 'Warning', 'Error'). It is case-insensitive.
  21. * @param string $category category of the message (e.g. 'system.web'). It is case-insensitive.
  22. * @see getLogs
  23. */
  24. public function log($message,$level='info',$category='application')
  25. {
  26. //将日志信息保存在成员变量(数组)中
  27. $this->_logs[]=array($message,$level,$category,microtime(true));
  28. $this->_logCount++;
  29. //如果数组数量到了autoFlush定义的数量,那么调用flush方法
  30. if($this->autoFlush>0 && $this->_logCount>=$this->autoFlush)
  31. $this->flush();
  32. }
  33. /**
  34. * Removes all recorded messages from the memory.
  35. * This method will raise an {@link onFlush} event.
  36. * The attached event handlers can process the log messages before they are removed.
  37. * @since 1.1.0
  38. */
  39. public function flush()
  40. {
  41. //触发onflush方法,这时会触发CLogRouter的onflush事件
  42. //参见上面CLogRouter的代码,会调用collectLogs方法
  43. $this->onFlush(new CEvent($this));
  44. //清空日志数据
  45. $this->_logs=array();
  46. $this->_logCount=0;
  47. }

回到CLogRouter,调用collectLogs实际是调用配置中的每一个Route的collectlogs方法 ,这个方法是所有route继承自CLogRoute(注意,不是CLogRouter)的:

Php代码  收藏代码
  1. /**
  2. * Retrieves filtered log messages from logger for further processing.
  3. * @param CLogger $logger logger instance
  4. * @param boolean $processLogs whether to process the logs after they are collected from the logger
  5. */
  6. public function collectLogs($logger, $processLogs=false)
  7. {
  8. //获取日志记录
  9. $logs=$logger->getLogs($this->levels,$this->categories);
  10. $this->logs=emptyempty($this->logs) ? $logs : array_merge($this->logs,$logs);
  11. if($processLogs && !emptyempty($this->logs))
  12. {
  13. if($this->filter!==null)
  14. Yii::createComponent($this->filter)->filter($this->logs);
  15. //调用processlog方法
  16. $this->processLogs($this->logs);
  17. }
  18. }
  19. /**
  20. * Processes log messages and sends them to specific destination.
  21. * Derived child classes must implement this method.
  22. * @param array $logs list of messages.  Each array elements represents one message
  23. * with the following structure:
  24. * array(
  25. *   [0] => message (string)
  26. *   [1] => level (string)
  27. *   [2] => category (string)
  28. *   [3] => timestamp (float, obtained by microtime(true));
  29. */
  30. //processlog是由CLogRoute的各个route子类实现的
  31. //例如数据库route用数据库存储,文件route用文件存储……
  32. abstract protected function processLogs($logs);

至此,整个记录日志的过程就清楚了,下图是类关系:

Yii日志记录类关系

$this->redirect ,Yii::app()->createUrl的路由设置
Yii分析13:Yii核心组件之AssetManager
  • 文章目录
  • 站点概览
ken

ken

记录精彩的程序人生

498 日志
9 分类
77 标签
RSS
Creative Commons
Links
  • 酷壳
0%
© 2010 — 2025 ken
由 Halo 强力驱动
鄂ICP备18013899号-1