PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/components/mallocworks/Logger/Logger.php

https://github.com/cheungyang/Utopia3
PHP | 265 lines | 219 code | 29 blank | 17 comment | 28 complexity | 3378911e3ae56a715167723513b0750a MD5 | raw file
  1. <?php
  2. namespace Utopia\Components\Logger;
  3. use Utopia\Components\Core\ComponentRoot;
  4. use Utopia\Components\Core\DataObject;
  5. use Utopia\Components\ConfigurationBundle\ConfigurationBundle;
  6. class Logger extends ComponentRoot{
  7. private $_data; //DataObject
  8. static function isSingleton(){
  9. return true;
  10. }
  11. public function initialize($mixed=false){
  12. $c = ConfigurationBundle::summon()
  13. ->setMasterFile(dirname(__FILE__).'/'.ComponentRoot::MASTER_CONF);
  14. $fileConfs = $c->get_value('logger.files', array());
  15. foreach($fileConfs as $conf){
  16. $this->registerFileStream($conf['filename'], $conf['level']);
  17. }
  18. $responseConfs = $c->get_value('logger.responses', array());
  19. foreach($responseConfs as $conf){
  20. $this->registerResponse(
  21. $conf['level'],
  22. isset($conf['classes'])? $conf['classes']: array()
  23. );
  24. }
  25. $printConfs = $c->get_value('logger.prints', array());
  26. foreach($printConfs as $conf){
  27. $this->registerPrint(
  28. $conf['level'],
  29. isset($conf['color'])? $conf['color']: "off",
  30. isset($conf['classes'])? $conf['classes']: array()
  31. );
  32. }
  33. $errorlogConfs = $c->get_value('logger.errorlog', array());
  34. foreach($errorlogConfs as $conf){
  35. $this->registerErrorlog(
  36. $conf['level'],
  37. isset($conf['color'])? $conf['color']: "off",
  38. isset($conf['classes'])? $conf['classes']: array()
  39. );
  40. }
  41. date_default_timezone_set($c->{'logger>region'});
  42. }
  43. public function __construct() {
  44. $this->_data = new DataObject();
  45. }
  46. public function __destruct() {
  47. //remove file handlers
  48. $this->_data->setPointer('filehandlers');
  49. foreach($this->_data as $fh) {
  50. fclose($fh);
  51. }
  52. }
  53. public function registerFileStream($filename, $level=999) {
  54. if (empty($filename)){
  55. return $this;
  56. }
  57. $this->_data->push("file>{$level}", $filename);
  58. if (!isset($this->_data->{"filehandlers>$filename"})) {
  59. $dir = dirname($filename);
  60. if (!file_exists($dir)){
  61. mkdir($dir, 0755, true);
  62. }
  63. $handle = fopen($filename, "a");
  64. if ($handle !== false) {
  65. $this->_data->{"filehandlers>$filename"} = $handle;
  66. } else {
  67. throw new MallocworksException("file $filename cannot be opened", LEVEL_ERROR);
  68. }
  69. }
  70. return $this;
  71. }
  72. public function registerResponse($level=999, $classes=array()) {
  73. $this->_data->push("response>{$level}", array(
  74. 'classes'=>$classes
  75. ));
  76. return $this;
  77. }
  78. public function registerPrint($level=999, $color="off", $classes=array()) {
  79. $this->_data->push("print>{$level}", array(
  80. 'color'=> 'off'===$color? false: true,
  81. 'classes'=>$classes
  82. ));
  83. return $this;
  84. }
  85. public function registerErrorlog($level=999, $color="off", $classes=array()) {
  86. $this->_data->push("errorlog>{$level}", array(
  87. 'color'=> 'off'===$color? false: true,
  88. 'classes'=>$classes
  89. ));
  90. return $this;
  91. }
  92. public function log($string, $level=ComponentRoot::LEVEL_ERROR) {
  93. $pdate = date('[Y-m-d H:i:s]');
  94. $pdate_colored = $this->_getColorString($pdate,
  95. ConfigurationBundle::summon()->{"logger>timestamp_foreground"},
  96. ConfigurationBundle::summon()->{"logger>timestamp_background"}
  97. );
  98. $pconf = ConfigurationBundle::summon()->{"logger.log.config>".$level};
  99. $pclass= $this->_getCalledClass();
  100. //print to log file
  101. $this->_data->setPointer('file');
  102. foreach($this->_data as $reg_level => $files) {
  103. if ($level < $reg_level) {
  104. continue;
  105. }
  106. foreach($files as $filename) {
  107. $handle = $this->_data->{"filehandlers>$filename"};
  108. if (is_resource($handle)) {
  109. fwrite($handle, "$pdate{$pconf['text']}[$pclass]$string\n");
  110. }
  111. }
  112. }
  113. //print to screen
  114. $this->_data->setPointer('print');
  115. foreach($this->_data as $reg_level => $confs) {
  116. foreach($confs as $conf) {
  117. //check if the level is high enough
  118. if ($level < $reg_level) {
  119. continue;
  120. }
  121. //check if the class should be recorded
  122. if (!empty($conf['classes']) && !in_array(strstr($pclass, "::", true), $conf['classes'])){
  123. continue;
  124. }
  125. //print colored string or not
  126. if ($conf['color']) {
  127. echo $pdate_colored
  128. .$this->_getColorString("{$pconf['text']}[$pclass]", $pconf['foreground'], $pconf['background'])
  129. ."$string\n";
  130. } else {
  131. echo "$pdate{$pconf['text']}[$pclass]$string\n";
  132. }
  133. }
  134. }
  135. //save to response
  136. $this->_data->setPointer('response');
  137. foreach($this->_data as $reg_level => $confs) {
  138. foreach($confs as $conf) {
  139. //check if the level is high enough
  140. if ($level < $reg_level) {
  141. continue;
  142. }
  143. //check if the class should be recorded
  144. if (!empty($conf['classes']) && !in_array(strstr($pclass, "::", true), $conf['classes'])){
  145. continue;
  146. }
  147. $this->_data->push('response_data', htmlentities("$pdate{$pconf['text']}[$pclass]$string"));
  148. }
  149. }
  150. //print to error_log
  151. $this->_data->setPointer('errorlog');
  152. foreach($this->_data as $reg_level => $confs) {
  153. foreach($confs as $conf) {
  154. //check if the level is high enough
  155. if ($level < $reg_level) {
  156. continue;
  157. }
  158. //check if the class should be recorded
  159. if (!empty($conf['classes']) && !in_array(strstr($pclass, "::", true), $conf['classes'])){
  160. continue;
  161. }
  162. //print colored string or not
  163. if ($conf['color']) {
  164. error_log("[log]".
  165. $pdate_colored
  166. .$this->_getColorString("{$pconf['text']}[$pclass]", $pconf['foreground'], $pconf['background'])
  167. .$string
  168. );
  169. } else {
  170. error_log("[log]$pdate{$pconf['text']}[$pclass]$string");
  171. }
  172. }
  173. }
  174. }
  175. public function backtrace(){
  176. $bt = debug_backtrace();
  177. $i = 1;
  178. while($i<10 && isset($bt[$i])){
  179. $o = $bt[$i];
  180. $this->log("[$i]{$o['class']}::{$o['function']}({$o['line']})", ComponentRoot::LEVEL_DEBUG);
  181. $i++;
  182. }
  183. }
  184. public function getResponses($format="") {
  185. $responses = $this->_data->get('response_data', array());
  186. switch($format){
  187. case 'html':
  188. $config = ConfigurationBundle::summon()->get_value("logger.log.config");
  189. foreach($responses as &$r){
  190. //22 is the length of the timestamp
  191. $type = substr($r, 21, strpos($r,']',22)-20);
  192. $levels = array_keys($config);
  193. $i = 0;
  194. while(isset($config[$levels[$i]]["text"]) && $type != $config[$levels[$i]]["text"]){ $i++;}
  195. if (isset($config[$levels[$i]]['foreground'])){
  196. $foreground = $config[$levels[$i]]['foreground'];
  197. if (!empty($foreground)){
  198. $r = str_replace($type, '<font color="'.$foreground.'">'.$type.'</font>', $r);
  199. }
  200. }
  201. $r = '<font color="green">'.substr($r, 0, 21).'</font>'.substr($r, 21);
  202. }
  203. break;
  204. default:
  205. }
  206. //should not delete as it will be share in many layers
  207. //$this->_data->del('response_data'.SEP.$identifier);
  208. return $responses;
  209. }
  210. private function _getColorString($string, $fg="", $bg="") {
  211. $colored_string = '';
  212. $fg = ConfigurationBundle::summon()->get_value("logger.color.foreground>$fg", "");
  213. if (!empty($fg)) {
  214. $colored_string .= "\033[" . $fg . "m";
  215. }
  216. $bg = ConfigurationBundle::summon()->get_value("logger.color.foreground>$bg", "");
  217. if (!empty($bg)) {
  218. $colored_string .= "\033[" . $bg . "m";
  219. }
  220. // Add string and end coloring
  221. $colored_string .= $string . "\033[0m";
  222. return $colored_string;
  223. }
  224. private function _getCalledClass(){
  225. $arr = debug_backtrace(false);
  226. foreach($arr as $i){
  227. if ("Utopia\Components\Logger\Logger"!=$i['class']) {
  228. $pos = strrpos($i['class'], "\\");
  229. return 0<$pos
  230. ? substr($i['class'], $pos+1).'::'.$i['function']
  231. : $i['class'].'::'.$i['function'];
  232. }
  233. }
  234. return "";
  235. }
  236. }