CLogFilter.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. /**
  3. * CLogFilter class file
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.yiiframework.com/
  7. * @copyright 2008-2013 Yii Software LLC
  8. * @license http://www.yiiframework.com/license/
  9. */
  10. /**
  11. * CLogFilter preprocesses the logged messages before they are handled by a log route.
  12. *
  13. * CLogFilter is meant to be used by a log route to preprocess the logged messages
  14. * before they are handled by the route. The default implementation of CLogFilter
  15. * prepends additional context information to the logged messages. In particular,
  16. * by setting {@link logVars}, predefined PHP variables such as
  17. * $_SERVER, $_POST, etc. can be saved as a log message, which may help identify/debug
  18. * issues encountered.
  19. *
  20. * @author Qiang Xue <qiang.xue@gmail.com>
  21. * @package system.logging
  22. */
  23. class CLogFilter extends CComponent implements ILogFilter
  24. {
  25. /**
  26. * @var boolean whether to prefix each log message with the current user session ID.
  27. * Defaults to false.
  28. */
  29. public $prefixSession=false;
  30. /**
  31. * @var boolean whether to prefix each log message with the current user
  32. * {@link CWebUser::name name} and {@link CWebUser::id ID}. Defaults to false.
  33. */
  34. public $prefixUser=false;
  35. /**
  36. * @var boolean whether to log the current user name and ID. Defaults to true.
  37. */
  38. public $logUser=true;
  39. /**
  40. * @var array list of the PHP predefined variables that should be logged.
  41. * Note that a variable must be accessible via $GLOBALS. Otherwise it won't be logged.
  42. */
  43. public $logVars=array('_GET','_POST','_FILES','_COOKIE','_SESSION','_SERVER');
  44. /**
  45. * @var callable or function which will be used to dump context information.
  46. * Defaults to `var_export`. If you're experiencing issues with circular references
  47. * problem change it to `print_r`. Any kind of callable (static methods, user defined
  48. * functions, lambdas, etc.) could also be used.
  49. * @since 1.1.14
  50. */
  51. public $dumper='var_export';
  52. /**
  53. * Filters the given log messages.
  54. * This is the main method of CLogFilter. It processes the log messages
  55. * by adding context information, etc.
  56. * @param array $logs the log messages
  57. * @return array
  58. */
  59. public function filter(&$logs)
  60. {
  61. if (!empty($logs))
  62. {
  63. if(($message=$this->getContext())!=='')
  64. array_unshift($logs,array($message,CLogger::LEVEL_INFO,'application',YII_BEGIN_TIME));
  65. $this->format($logs);
  66. }
  67. return $logs;
  68. }
  69. /**
  70. * Formats the log messages.
  71. * The default implementation will prefix each message with session ID
  72. * if {@link prefixSession} is set true. It may also prefix each message
  73. * with the current user's name and ID if {@link prefixUser} is true.
  74. * @param array $logs the log messages
  75. */
  76. protected function format(&$logs)
  77. {
  78. $prefix='';
  79. if($this->prefixSession && ($id=session_id())!=='')
  80. $prefix.="[$id]";
  81. if($this->prefixUser && ($user=Yii::app()->getComponent('user',false))!==null)
  82. $prefix.='['.$user->getName().']['.$user->getId().']';
  83. if($prefix!=='')
  84. {
  85. foreach($logs as &$log)
  86. $log[0]=$prefix.' '.$log[0];
  87. }
  88. }
  89. /**
  90. * Generates the context information to be logged.
  91. * The default implementation will dump user information, system variables, etc.
  92. * @return string the context information. If an empty string, it means no context information.
  93. */
  94. protected function getContext()
  95. {
  96. $context=array();
  97. if($this->logUser && ($user=Yii::app()->getComponent('user',false))!==null)
  98. $context[]='User: '.$user->getName().' (ID: '.$user->getId().')';
  99. if($this->dumper==='var_export' || $this->dumper==='print_r')
  100. {
  101. foreach($this->logVars as $name)
  102. if(($value=$this->getGlobalsValue($name))!==null)
  103. $context[]="\${$name}=".call_user_func($this->dumper,$value,true);
  104. }
  105. else
  106. {
  107. foreach($this->logVars as $name)
  108. if(($value=$this->getGlobalsValue($name))!==null)
  109. $context[]="\${$name}=".call_user_func($this->dumper,$value);
  110. }
  111. return implode("\n\n",$context);
  112. }
  113. /**
  114. * @param string[] $path
  115. * @return string|null
  116. */
  117. private function getGlobalsValue(&$path)
  118. {
  119. if(is_scalar($path))
  120. return !empty($GLOBALS[$path]) ? $GLOBALS[$path] : null;
  121. $pathAux=$path;
  122. $parts=array();
  123. $value=$GLOBALS;
  124. do
  125. {
  126. $value=$value[$parts[]=array_shift($pathAux)];
  127. }
  128. while(!empty($value) && !empty($pathAux) && !is_string($value));
  129. $path=implode('.',$parts);
  130. return $value;
  131. }
  132. }