/framework/Util/TLogger.php

https://bitbucket.org/volatileeight/prado · PHP · 234 lines · 100 code · 9 blank · 125 comment · 26 complexity · 6bf9825a61f5945fb9fdea6aa8f2d59d MD5 · raw file

  1. <?php
  2. /**
  3. * TLogger class file
  4. *
  5. * @author Qiang Xue <qiang.xue@gmail.com>
  6. * @link http://www.pradosoft.com/
  7. * @copyright Copyright &copy; 2005-2014 PradoSoft
  8. * @license http://www.pradosoft.com/license/
  9. * @package System.Util
  10. */
  11. /**
  12. * TLogger class.
  13. *
  14. * TLogger records log messages in memory and implements the methods to
  15. * retrieve the messages with filter conditions, including log levels,
  16. * log categories, and by control.
  17. *
  18. * @author Qiang Xue <qiang.xue@gmail.com>
  19. * @package System.Util
  20. * @since 3.0
  21. */
  22. class TLogger extends TComponent
  23. {
  24. /**
  25. * Log levels.
  26. */
  27. const DEBUG=0x01;
  28. const INFO=0x02;
  29. const NOTICE=0x04;
  30. const WARNING=0x08;
  31. const ERROR=0x10;
  32. const ALERT=0x20;
  33. const FATAL=0x40;
  34. /**
  35. * @var array log messages
  36. */
  37. private $_logs=array();
  38. /**
  39. * @var integer log levels (bits) to be filtered
  40. */
  41. private $_levels;
  42. /**
  43. * @var array list of categories to be filtered
  44. */
  45. private $_categories;
  46. /**
  47. * @var array list of control client ids to be filtered
  48. */
  49. private $_controls;
  50. /**
  51. * @var float timestamp used to filter
  52. */
  53. private $_timestamp;
  54. /**
  55. * Logs a message.
  56. * Messages logged by this method may be retrieved via {@link getLogs}.
  57. * @param string message to be logged
  58. * @param integer level of the message. Valid values include
  59. * TLogger::DEBUG, TLogger::INFO, TLogger::NOTICE, TLogger::WARNING,
  60. * TLogger::ERROR, TLogger::ALERT, TLogger::FATAL.
  61. * @param string category of the message
  62. * @param string|TControl control of the message
  63. */
  64. public function log($message,$level,$category='Uncategorized', $ctl=null)
  65. {
  66. if($ctl) {
  67. if($ctl instanceof TControl)
  68. $ctl = $ctl->ClientId;
  69. else if(!is_string($ctl))
  70. $ctl = null;
  71. } else
  72. $ctl = null;
  73. $this->_logs[]=array($message,$level,$category,microtime(true),memory_get_usage(),$ctl);
  74. }
  75. /**
  76. * Retrieves log messages.
  77. * Messages may be filtered by log levels and/or categories and/or control client ids and/or timestamp.
  78. * A level filter is specified by an integer, whose bits indicate the levels interested.
  79. * For example, (TLogger::INFO | TLogger::WARNING) specifies INFO and WARNING levels.
  80. * A category filter is specified by an array of categories to filter.
  81. * A message whose category name starts with any filtering category
  82. * will be returned. For example, a category filter array('System.Web','System.IO')
  83. * will return messages under categories such as 'System.Web', 'System.IO',
  84. * 'System.Web.UI', 'System.Web.UI.WebControls', etc.
  85. * A control client id filter is specified by an array of control client id
  86. * A message whose control client id starts with any filtering naming panels
  87. * will be returned. For example, a category filter array('ctl0_body_header',
  88. * 'ctl0_body_content_sidebar')
  89. * will return messages under categories such as 'ctl0_body_header', 'ctl0_body_content_sidebar',
  90. * 'ctl0_body_header_title', 'ctl0_body_content_sidebar_savebutton', etc.
  91. * A timestamp filter is specified as an interger or float number.
  92. * A message whose registered timestamp is less or equal the filter value will be returned.
  93. * Level filter, category filter, control filter and timestamp filter are combinational, i.e., only messages
  94. * satisfying all filter conditions will they be returned.
  95. * @param integer level filter
  96. * @param array category filter
  97. * @param array control filter
  98. * @return array list of messages. Each array elements represents one message
  99. * with the following structure:
  100. * array(
  101. * [0] => message
  102. * [1] => level
  103. * [2] => category
  104. * [3] => timestamp (by microtime(), float number));
  105. * [4] => memory in bytes
  106. * [5] => control client id
  107. */
  108. public function getLogs($levels=null,$categories=null,$controls=null,$timestamp=null)
  109. {
  110. $this->_levels=$levels;
  111. $this->_categories=$categories;
  112. $this->_controls=$controls;
  113. $this->_timestamp=$timestamp;
  114. if(empty($levels) && empty($categories) && empty($controls) && is_null($timestamp))
  115. return $this->_logs;
  116. $logs = $this->_logs;
  117. if(!empty($levels))
  118. $logs = array_values(array_filter( array_filter($logs,array($this,'filterByLevels')) ));
  119. if(!empty($categories))
  120. $logs = array_values(array_filter( array_filter($logs,array($this,'filterByCategories')) ));
  121. if(!empty($controls))
  122. $logs = array_values(array_filter( array_filter($logs,array($this,'filterByControl')) ));
  123. if(!is_null($timestamp))
  124. $logs = array_values(array_filter( array_filter($logs,array($this,'filterByTimeStamp')) ));
  125. return $logs;
  126. }
  127. /**
  128. * Deletes log messages from the queue.
  129. * Messages may be filtered by log levels and/or categories and/or control client ids and/or timestamp.
  130. * A level filter is specified by an integer, whose bits indicate the levels interested.
  131. * For example, (TLogger::INFO | TLogger::WARNING) specifies INFO and WARNING levels.
  132. * A category filter is specified by an array of categories to filter.
  133. * A message whose category name starts with any filtering category
  134. * will be deleted. For example, a category filter array('System.Web','System.IO')
  135. * will delete messages under categories such as 'System.Web', 'System.IO',
  136. * 'System.Web.UI', 'System.Web.UI.WebControls', etc.
  137. * A control client id filter is specified by an array of control client id
  138. * A message whose control client id starts with any filtering naming panels
  139. * will be deleted. For example, a category filter array('ctl0_body_header',
  140. * 'ctl0_body_content_sidebar')
  141. * will delete messages under categories such as 'ctl0_body_header', 'ctl0_body_content_sidebar',
  142. * 'ctl0_body_header_title', 'ctl0_body_content_sidebar_savebutton', etc.
  143. * A timestamp filter is specified as an interger or float number.
  144. * A message whose registered timestamp is less or equal the filter value will be returned.
  145. * Level filter, category filter, control filter and timestamp filter are combinational, i.e., only messages
  146. * satisfying all filter conditions will they be returned.
  147. * @param integer level filter
  148. * @param array category filter
  149. * @param array control filter
  150. */
  151. public function deleteLogs($levels=null,$categories=null,$controls=null,$timestamp=null)
  152. {
  153. $this->_levels=$levels;
  154. $this->_categories=$categories;
  155. $this->_controls=$controls;
  156. $this->_timestamp=$timestamp;
  157. if(empty($levels) && empty($categories) && empty($controls) && is_null($timestamp))
  158. {
  159. $this->_logs=array();
  160. return;
  161. }
  162. $logs = $this->_logs;
  163. if(!empty($levels))
  164. $logs = array_filter( array_filter($logs,array($this,'filterByLevels')) );
  165. if(!empty($categories))
  166. $logs = array_filter( array_filter($logs,array($this,'filterByCategories')) );
  167. if(!empty($controls))
  168. $logs = array_filter( array_filter($logs,array($this,'filterByControl')) );
  169. if(!is_null($timestamp))
  170. $logs = array_filter( array_filter($logs,array($this,'filterByTimeStamp')) );
  171. $this->_logs = array_values( array_diff_key($this->_logs, $logs) );
  172. }
  173. /**
  174. * Filter function used by {@link getLogs}.
  175. * @param array element to be filtered
  176. */
  177. private function filterByCategories($value)
  178. {
  179. foreach($this->_categories as $category)
  180. {
  181. // element 2 is the category
  182. if($value[2]===$category || strpos($value[2],$category.'.')===0)
  183. return $value;
  184. }
  185. return false;
  186. }
  187. /**
  188. * Filter function used by {@link getLogs}
  189. * @param array element to be filtered
  190. */
  191. private function filterByLevels($value)
  192. {
  193. // element 1 are the levels
  194. if($value[1] & $this->_levels)
  195. return $value;
  196. else
  197. return false;
  198. }
  199. /**
  200. * Filter function used by {@link getLogs}
  201. * @param array element to be filtered
  202. */
  203. private function filterByControl($value)
  204. {
  205. // element 5 are the control client ids
  206. foreach($this->_controls as $control)
  207. {
  208. if($value[5]===$control || strpos($value[5],$control)===0)
  209. return $value;
  210. }
  211. return false;
  212. }
  213. /**
  214. * Filter function used by {@link getLogs}
  215. * @param array element to be filtered
  216. */
  217. private function filterByTimeStamp($value)
  218. {
  219. // element 3 is the timestamp
  220. if($value[3] <= $this->_timestamp)
  221. return $value;
  222. else
  223. return false;
  224. }
  225. }