个人对于 Log 的建议2

我们可以修改 CLogger 的 init方法:




	private $_hasInitLog = false;

	private $_needLogLevels = array();

	

	public function log($message,$level='info',$category='application')

	{

		if ( ! $this->_hasInitLog)

		{

			$this->_hasInitLog = true;

			$this->_needLogLevels = Yii::app()->log->getNeedLogLeves();

		}


		// 不需要路由的级别,直接放弃

		if ($this->_needLogLevels && ! in_array($level, $this->_needLogLevels))

		{

			return;

		}







<?php


/**

 * 重写了 CLogRouter ,将 router 的初始化推迟

 * 并分析路由的配置信息,将需要路由的级别传递给 CLogger ,以直接放弃掉不需要路由的信息,例如profile级别的,以节省内存开销

 * 其实分类也可以像上面那么干的,但是我们一般日志路由会记录所有的分类吧

 */


class MyLogRouter extends CApplicationComponent

{

	private $_routes=array();


	private $_routeInitialized = false;


	private $_needLogLevels = array();


	public function init()

	{

		parent::init();

		Yii::getLogger()->attachEventHandler('onFlush',array($this,'collectLogs'));

		Yii::app()->attachEventHandler('onEndRequest',array($this,'processLogs'));

	}


	protected function initRoute()

	{

		if ( ! $this->_routeInitialized)

		{

			foreach($this->_routes as $name=>$route)

			{

				$route=Yii::createComponent($route);

				$route->init();

				$this->_routes[$name]=$route;

			}


			$this->_routeInitialized = true;

		}

	}


	public function getNeedLogLeves()

	{

		return $this->_needLogLevels ? array_unique($this->_needLogLevels) : array();

	}


	public function getRoutes()

	{

		return new CMap($this->_routes);

	}


	public function setRoutes($config)

	{

		foreach($config as $name=>$route)

		{

			$this->_routes[$name]=$route;

			if (isset($this->_needLogLevels) && isset($route['levels']) && trim($route['levels']) != '')

			{

				$this->_needLogLevels = array_merge($this->_needLogLevels, preg_split('/[\s,]+/',strtolower($route['levels']),-1,PREG_SPLIT_NO_EMPTY));

			}

			else

			{

				$this->_needLogLevels = null;

			}

		}

	}


	public function collectLogs($event)

	{

		$this->initRoute();

		$logger=Yii::getLogger();

		$dumpLogs=isset($event->params['dumpLogs']) && $event->params['dumpLogs'];

		foreach($this->_routes as $route)

		{

			if($route->enabled)

				$route->collectLogs($logger,$dumpLogs);

		}

	}


	public function processLogs($event)

	{

		$this->initRoute();

		$logger=Yii::getLogger();

		foreach($this->_routes as $route)

		{

			if($route->enabled)

				$route->collectLogs($logger,true);

		}

	}

}




这样的话,完全不需要预加载 log 组件。

在发生日志记录的时候,初始化 log 组件。

还可以放弃记录需要要路由的信息,减小内存开销