PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/spcc/include/php/klogger.php

https://bitbucket.org/nchlssmith1/modified_crayon
PHP | 411 lines | 183 code | 39 blank | 189 comment | 20 complexity | a54ff94822f0f537d905218076218966 MD5 | raw file
  1. <?php
  2. /**
  3. * Finally, a light, permissions-checking logging class.
  4. *
  5. * Originally written for use with wpSearch
  6. *
  7. * Usage:
  8. * $log = new KLogger('/var/log/', KLogger::INFO);
  9. * $log->logInfo('Returned a million search results'); //Prints to the log file
  10. * $log->logFatal('Oh dear.'); //Prints to the log file
  11. * $log->logDebug('x = 5'); //Prints nothing due to current severity threshhold
  12. *
  13. * @author Kenny Katzgrau <katzgrau@gmail.com>
  14. * @since July 26, 2008 — Last update July 1, 2012
  15. * @link http://codefury.net
  16. * @version 0.2.0
  17. */
  18. /**
  19. * Class documentation
  20. */
  21. class KLogger
  22. {
  23. /**
  24. * Error severity, from low to high. From BSD syslog RFC, secion 4.1.1
  25. * @link http://www.faqs.org/rfcs/rfc3164.html
  26. */
  27. const EMERG = 0; // Emergency: system is unusable
  28. const ALERT = 1; // Alert: action must be taken immediately
  29. const CRIT = 2; // Critical: critical conditions
  30. const ERR = 3; // Error: error conditions
  31. const WARN = 4; // Warning: warning conditions
  32. const NOTICE = 5; // Notice: normal but significant condition
  33. const INFO = 6; // Informational: informational messages
  34. const DEBUG = 7; // Debug: debug messages
  35. //custom logging level
  36. /**
  37. * Log nothing at all
  38. */
  39. const OFF = 8;
  40. /**
  41. * Alias for CRIT
  42. * @deprecated
  43. */
  44. const FATAL = 2;
  45. /**
  46. * Internal status codes
  47. */
  48. const STATUS_LOG_OPEN = 1;
  49. const STATUS_OPEN_FAILED = 2;
  50. const STATUS_LOG_CLOSED = 3;
  51. /**
  52. * We need a default argument value in order to add the ability to easily
  53. * print out objects etc. But we can't use NULL, 0, FALSE, etc, because those
  54. * are often the values the developers will test for. So we'll make one up.
  55. */
  56. const NO_ARGUMENTS = 'KLogger::NO_ARGUMENTS';
  57. /**
  58. * Current status of the log file
  59. * @var integer
  60. */
  61. private $_logStatus = self::STATUS_LOG_CLOSED;
  62. /**
  63. * Holds messages generated by the class
  64. * @var array
  65. */
  66. private $_messageQueue = array();
  67. /**
  68. * Path to the log file
  69. * @var string
  70. */
  71. private $_logFilePath = null;
  72. /**
  73. * Current minimum logging threshold
  74. * @var integer
  75. */
  76. private $_severityThreshold = self::INFO;
  77. /**
  78. * This holds the file handle for this instance's log file
  79. * @var resource
  80. */
  81. private $_fileHandle = null;
  82. /**
  83. * Standard messages produced by the class. Can be modified for il8n
  84. * @var array
  85. */
  86. private $_messages = array(
  87. //'writefail' => 'The file exists, but could not be opened for writing. Check that appropriate permissions have been set.',
  88. 'writefail' => 'The file could not be written to. Check that appropriate permissions have been set.',
  89. 'opensuccess' => 'The log file was opened successfully.',
  90. 'openfail' => 'The file could not be opened. Check permissions.',
  91. );
  92. /**
  93. * Default severity of log messages, if not specified
  94. * @var integer
  95. */
  96. private static $_defaultSeverity = self::DEBUG;
  97. /**
  98. * Valid PHP date() format string for log timestamps
  99. * @var string
  100. */
  101. private static $_dateFormat = 'Y-m-d G:i:s';
  102. /**
  103. * Octal notation for default permissions of the log file
  104. * @var integer
  105. */
  106. private static $_defaultPermissions = 0777;
  107. /**
  108. * Array of KLogger instances, part of Singleton pattern
  109. * @var array
  110. */
  111. private static $instances = array();
  112. /**
  113. * Partially implements the Singleton pattern. Each $logDirectory gets one
  114. * instance.
  115. *
  116. * @param string $logDirectory File path to the logging directory
  117. * @param integer $severity One of the pre-defined severity constants
  118. * @return KLogger
  119. */
  120. public static function instance($logDirectory = false, $severity = false)
  121. {
  122. if ($severity === false) {
  123. $severity = self::$_defaultSeverity;
  124. }
  125. if ($logDirectory === false) {
  126. if (count(self::$instances) > 0) {
  127. return current(self::$instances);
  128. } else {
  129. $logDirectory = dirname(__FILE__);
  130. }
  131. }
  132. if (in_array($logDirectory, self::$instances)) {
  133. return self::$instances[$logDirectory];
  134. }
  135. self::$instances[$logDirectory] = new self($logDirectory, $severity);
  136. return self::$instances[$logDirectory];
  137. }
  138. /**
  139. * Class constructor
  140. *
  141. * @param string $logDirectory File path to the logging directory
  142. * @param integer $severity One of the pre-defined severity constants
  143. * @return void
  144. */
  145. public function __construct($logDirectory, $severity)
  146. {
  147. date_default_timezone_set('America/Chicago');
  148. $logDirectory = rtrim($logDirectory, '\\/');
  149. if ($severity === self::OFF) {
  150. return;
  151. }
  152. $this->_logFilePath = $logDirectory
  153. . DIRECTORY_SEPARATOR
  154. . 'log_'
  155. . date('Y-m-d')
  156. . '.txt';
  157. $this->_severityThreshold = $severity;
  158. if (!file_exists($logDirectory)) {
  159. mkdir($logDirectory, self::$_defaultPermissions, true);
  160. }
  161. if (file_exists($this->_logFilePath) && !is_writable($this->_logFilePath)) {
  162. $this->_logStatus = self::STATUS_OPEN_FAILED;
  163. $this->_messageQueue[] = $this->_messages['writefail'];
  164. return;
  165. }
  166. if (($this->_fileHandle = fopen($this->_logFilePath, 'a'))) {
  167. $this->_logStatus = self::STATUS_LOG_OPEN;
  168. $this->_messageQueue[] = $this->_messages['opensuccess'];
  169. } else {
  170. $this->_logStatus = self::STATUS_OPEN_FAILED;
  171. $this->_messageQueue[] = $this->_messages['openfail'];
  172. }
  173. }
  174. /**
  175. * Class destructor
  176. */
  177. public function __destruct()
  178. {
  179. if ($this->_fileHandle) {
  180. fclose($this->_fileHandle);
  181. }
  182. }
  183. /**
  184. * Writes a $line to the log with a severity level of DEBUG
  185. *
  186. * @param string $line Information to log
  187. * @return void
  188. */
  189. public function logDebug($line, $args = self::NO_ARGUMENTS)
  190. {
  191. $this->log($line, self::DEBUG);
  192. }
  193. /**
  194. * Returns (and removes) the last message from the queue.
  195. * @return string
  196. */
  197. public function getMessage()
  198. {
  199. return array_pop($this->_messageQueue);
  200. }
  201. /**
  202. * Returns the entire message queue (leaving it intact)
  203. * @return array
  204. */
  205. public function getMessages()
  206. {
  207. return $this->_messageQueue;
  208. }
  209. /**
  210. * Empties the message queue
  211. * @return void
  212. */
  213. public function clearMessages()
  214. {
  215. $this->_messageQueue = array();
  216. }
  217. /**
  218. * Sets the date format used by all instances of KLogger
  219. *
  220. * @param string $dateFormat Valid format string for date()
  221. */
  222. public static function setDateFormat($dateFormat)
  223. {
  224. self::$_dateFormat = $dateFormat;
  225. }
  226. /**
  227. * Writes a $line to the log with a severity level of INFO. Any information
  228. * can be used here, or it could be used with E_STRICT errors
  229. *
  230. * @param string $line Information to log
  231. * @return void
  232. */
  233. public function logInfo($line, $args = self::NO_ARGUMENTS)
  234. {
  235. $this->log($line, self::INFO, $args);
  236. }
  237. /**
  238. * Writes a $line to the log with a severity level of NOTICE. Generally
  239. * corresponds to E_STRICT, E_NOTICE, or E_USER_NOTICE errors
  240. *
  241. * @param string $line Information to log
  242. * @return void
  243. */
  244. public function logNotice($line, $args = self::NO_ARGUMENTS)
  245. {
  246. $this->log($line, self::NOTICE, $args);
  247. }
  248. /**
  249. * Writes a $line to the log with a severity level of WARN. Generally
  250. * corresponds to E_WARNING, E_USER_WARNING, E_CORE_WARNING, or
  251. * E_COMPILE_WARNING
  252. *
  253. * @param string $line Information to log
  254. * @return void
  255. */
  256. public function logWarn($line, $args = self::NO_ARGUMENTS)
  257. {
  258. $this->log($line, self::WARN, $args);
  259. }
  260. /**
  261. * Writes a $line to the log with a severity level of ERR. Most likely used
  262. * with E_RECOVERABLE_ERROR
  263. *
  264. * @param string $line Information to log
  265. * @return void
  266. */
  267. public function logError($line, $args = self::NO_ARGUMENTS)
  268. {
  269. $this->log($line, self::ERR, $args);
  270. }
  271. /**
  272. * Writes a $line to the log with a severity level of FATAL. Generally
  273. * corresponds to E_ERROR, E_USER_ERROR, E_CORE_ERROR, or E_COMPILE_ERROR
  274. *
  275. * @param string $line Information to log
  276. * @return void
  277. * @deprecated Use logCrit
  278. */
  279. public function logFatal($line, $args = self::NO_ARGUMENTS)
  280. {
  281. $this->log($line, self::FATAL, $args);
  282. }
  283. /**
  284. * Writes a $line to the log with a severity level of ALERT.
  285. *
  286. * @param string $line Information to log
  287. * @return void
  288. */
  289. public function logAlert($line, $args = self::NO_ARGUMENTS)
  290. {
  291. $this->log($line, self::ALERT, $args);
  292. }
  293. /**
  294. * Writes a $line to the log with a severity level of CRIT.
  295. *
  296. * @param string $line Information to log
  297. * @return void
  298. */
  299. public function logCrit($line, $args = self::NO_ARGUMENTS)
  300. {
  301. $this->log($line, self::CRIT, $args);
  302. }
  303. /**
  304. * Writes a $line to the log with a severity level of EMERG.
  305. *
  306. * @param string $line Information to log
  307. * @return void
  308. */
  309. public function logEmerg($line, $args = self::NO_ARGUMENTS)
  310. {
  311. $this->log($line, self::EMERG, $args);
  312. }
  313. /**
  314. * Writes a $line to the log with the given severity
  315. *
  316. * @param string $line Text to add to the log
  317. * @param integer $severity Severity level of log message (use constants)
  318. */
  319. public function log($line, $severity, $args = self::NO_ARGUMENTS)
  320. {
  321. if ($this->_severityThreshold >= $severity) {
  322. $status = $this->_getTimeLine($severity);
  323. $line = "$status $line";
  324. if($args !== self::NO_ARGUMENTS) {
  325. /* Print the passed object value */
  326. $line = $line . '; ' . var_export($args, true);
  327. }
  328. $this->writeFreeFormLine($line . PHP_EOL);
  329. }
  330. }
  331. /**
  332. * Writes a line to the log without prepending a status or timestamp
  333. *
  334. * @param string $line Line to write to the log
  335. * @return void
  336. */
  337. public function writeFreeFormLine($line)
  338. {
  339. if ($this->_logStatus == self::STATUS_LOG_OPEN
  340. && $this->_severityThreshold != self::OFF) {
  341. if (fwrite($this->_fileHandle, $line) === false) {
  342. $this->_messageQueue[] = $this->_messages['writefail'];
  343. }
  344. }
  345. }
  346. private function _getTimeLine($level)
  347. {
  348. $time = date(self::$_dateFormat);
  349. switch ($level) {
  350. case self::EMERG:
  351. return "$time - EMERG -->";
  352. case self::ALERT:
  353. return "$time - ALERT -->";
  354. case self::CRIT:
  355. return "$time - CRIT -->";
  356. case self::FATAL: # FATAL is an alias of CRIT
  357. return "$time - FATAL -->";
  358. case self::NOTICE:
  359. return "$time - NOTICE -->";
  360. case self::INFO:
  361. return "$time - INFO -->";
  362. case self::WARN:
  363. return "$time - WARN -->";
  364. case self::DEBUG:
  365. return "$time - DEBUG -->";
  366. case self::ERR:
  367. return "$time - ERROR -->";
  368. default:
  369. return "$time - LOG -->";
  370. }
  371. }
  372. }