PageRenderTime 56ms CodeModel.GetById 21ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/Days/Log.php

http://phpdays.googlecode.com/
PHP | 210 lines | 126 code | 9 blank | 75 comment | 13 complexity | 7175d487144d9f3274a027c942a371bf MD5 | raw file
  1. <?php
  2. /**
  3. * Log - user for save application runtime errors to storage (file or database).
  4. *
  5. * Part of "php:Days - php5 framework" project (http://phpdays.googlecode.com).
  6. *
  7. * @copyright Copyright (c) 2009 phpDays foundation (http://phpdays.org)
  8. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  9. * @link http://code.google.com/p/phpdays/wiki/EnLibDaysLog
  10. * @package Days
  11. * @subpackage Days
  12. * @author Anton Danilchenko <happy@phpdays.org>
  13. */
  14. class Days_Log {
  15. const TRACE = 1;
  16. const WARNING = 2;
  17. const ERROR = 4;
  18. const INFO = 8;
  19. const PROFILE = 16;
  20. private static $_errors = array();
  21. public static function add($message, $category='app', $level=self::INFO) {
  22. // add unique message
  23. if ('' != $message AND ! in_array($message, self::$_errors))
  24. self::$_errors[] = array($message, $category, $level, microtime(true));
  25. }
  26. public static function profile($message, $category='app') {
  27. // not send message
  28. if (! Days_Config::load()->get('engine/debug', false))
  29. return;
  30. // send message now
  31. switch (strtolower(Days_Config::load()->get('log/type', 'file'))) {
  32. // send to FirePHP
  33. case 'fb':
  34. case 'firebug':
  35. case 'firephp':
  36. self::logtoFirephp(array($message), self::PROFILE);
  37. break;
  38. }
  39. }
  40. public static function save() {
  41. if (! empty(self::$_errors)) {
  42. // prepare data
  43. $sErrorFile = str_replace(':', '.', $_SERVER['HTTP_HOST']);
  44. $sLogDir = Days_Engine::appPath() . 'system/log/';
  45. // get current application error levels
  46. $level = Days_Config::load()->get('log/level');
  47. // save log
  48. if (Days_Config::load()->get('engine/debug', false)) {
  49. $messages = self::getMessages($level);
  50. if(count($messages)==0)
  51. return;
  52. switch (strtolower(Days_Config::load()->get('log/type', 'file'))) {
  53. // save to SQLite
  54. case 'sqlite':
  55. self::logtoSqlite($messages, $sErrorFile, $sLogDir);
  56. break;
  57. //send to browser
  58. case 'browser':
  59. self::logtoBrowser($messages);
  60. break;
  61. // send to FirePHP
  62. case 'fb':
  63. case 'firebug':
  64. case 'firephp':
  65. self::logtoFirephp($messages);
  66. break;
  67. // save to FILE
  68. case 'file':
  69. default:
  70. self::logtoFile($messages, $sErrorFile, $sLogDir);
  71. }
  72. }
  73. // clear saved errors
  74. self::$_errors = array();
  75. }
  76. }
  77. /**
  78. * Save error log to sqlite-database
  79. *
  80. * CREATE TABLE "error_log" (
  81. * "error_date" DATETIME,
  82. * "error_ip" VARCHAR,
  83. * "error_url" VARCHAR,
  84. * "error_referer" VARCHAR,
  85. * "error_text" VARCHAR,
  86. * "error_trace" TEXT,
  87. * "error_count" INTEGER DEFAULT 0
  88. * )
  89. *
  90. * @param $messages: error messages
  91. * @param $sErrorFile: database file
  92. * @param $sLogDir: directory for database file
  93. */
  94. protected static function logtoSqlite($messages, $sErrorFile, $sLogDir) {
  95. // create connection to sqlite db
  96. $db_sqlt = Zend_Db::factory('Pdo_Sqlite', array('dbname'=>$sLogDir."".$sErrorFile.".err.sqlite"));
  97. // increase count of exists error
  98. $select = $db_sqlt->select();
  99. $select->from('error_log', 'count(*)')
  100. ->where('error_date=?', date('Y-m-d'))
  101. ->where('error_text=?', $messages[0]);
  102. if ((int) $db_sqlt->fetchOne($select) > 0) {
  103. $sql = "update error_log set error_count=error_count+1 where error_date=? and error_text=?";
  104. $db_sqlt->query($sql, array(date('Y-m-d'), $messages[0]));
  105. }
  106. // create new error
  107. else {
  108. $error_data = array(
  109. 'error_date' => date('Y-m-d'),
  110. 'error_ip' => $_SERVER['REMOTE_ADDR'],
  111. 'error_url' => 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'],
  112. 'error_referer' => (isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''),
  113. 'error_text' => $messages[0],
  114. 'error_trace' => implode("\n", $messages) . "\n\n",
  115. 'error_count' => 1);
  116. $db_sqlt->insert('error_log', $error_data);
  117. }
  118. unset ($db_sqlt);
  119. }
  120. /**
  121. * Save error log to file
  122. *
  123. * @param $messages: error messages
  124. * @param $sErrorFile: filename for error log
  125. * @param $sLogDir: directory for $sErrorFile
  126. */
  127. protected static function logtoFile($messages, $sErrorFile, $sLogDir) {
  128. $sSystemInfo = date('[j/n/Y H:i:s]') . "\n";
  129. $sSystemInfo .= ' IP: ' . $_SERVER['REMOTE_ADDR'] . "\n";
  130. $sSystemInfo .= ' Query string: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] . "\n";
  131. // set previous page adress
  132. if(isset($_SERVER['HTTP_REFERER']))
  133. $sSystemInfo .= ' Previous page: ' . $_SERVER['HTTP_REFERER'] . "\n";
  134. $sMessages = implode("\n", $messages) . "\n\n";
  135. error_log($sSystemInfo . $sMessages, 3, "{$sLogDir}/{$sErrorFile}.err");
  136. }
  137. /**
  138. * Display error log in Firephp
  139. *
  140. * @param string $messages Error messages
  141. * @param string $level Error type
  142. */
  143. protected static function logtoFirephp($messages, $level=self::INFO) {
  144. foreach ($messages as $message)
  145. Firephp::getInstance(true)->log($message, self::getLevel($level));
  146. }
  147. /**
  148. * Display error log in Browser
  149. *
  150. * @param string $messages Error messages
  151. */
  152. protected static function logtoBrowser($messages){
  153. $messages=implode("<br>",$messages);
  154. $popup="<script language='javascript'>
  155. winopen=window.open('','ErrorPage','width=500,height=250,location=0,toolbar=0,menubar=0,status=1,scrollbars=1,resizable=1,top=10,left=750');
  156. winopen.document.write('<html><head><title>ErrorPage</title></head><body>{$messages}</body></html>');
  157. winopen.document.close();
  158. </script>";
  159. echo $popup;
  160. }
  161. /**
  162. * Return messages with specified error level.
  163. *
  164. * @param int $level Error levels joined with `&` operation
  165. * @return array All messages with specified level
  166. */
  167. protected static function getMessages($level=null) {
  168. $errMessages = array ();
  169. foreach (self::$_errors as $errorInfo)
  170. // get messages with specified level
  171. if (is_null($level) OR ($level & $errorInfo[2]))
  172. $errMessages[] = $errorInfo[0];//"{$errorInfo[3]}: {$errorInfo[0]}";
  173. return $errMessages;
  174. }
  175. /**
  176. * Convert error level to string.
  177. *
  178. * @param int $level Level constant
  179. */
  180. protected static function getLevel($level) {
  181. $levelName = 'undefined';
  182. switch ($level) {
  183. case self::TRACE:
  184. $levelName = 'TRACE';
  185. break;
  186. case self::WARNING:
  187. $levelName = 'WARNING';
  188. break;
  189. case self::ERROR:
  190. $levelName = 'ERROR';
  191. break;
  192. case self::INFO:
  193. $levelName = 'INFO';
  194. break;
  195. case self::PROFILE:
  196. $levelName = 'PROFILE';
  197. break;
  198. }
  199. return $levelName;
  200. }
  201. }