DebugLazyLogger.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. // @usage: DebugLazyLogger::log($mixedArg, $type, $msg, $logFileName);
  3. class DebugLazyLogger {
  4. function __construct() {
  5. $this->_items = [];
  6. $prefix = ('production' == V::get('P5_ENV', 'production', $_SERVER)) ? "" : "dev-";
  7. $this->_logFileName = "/tmp/{$prefix}se-debug-" . implode('-', [
  8. date("Y-m-d"),
  9. User::getLogin(),
  10. Request::getUserIp(),
  11. substr(session_id(), 0, 6),
  12. V::get('REQUEST_TIME', '', $_SERVER)// [REQUEST_TIME] => 1485770466
  13. ]) . '.log';
  14. }
  15. function _addLog($mixedArg, $type, $msg, $trace, $moreMsg) {
  16. $microTime = date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6);
  17. $this->_items[] = [ $microTime, $mixedArg, $type, $msg, $trace, $moreMsg ];
  18. }
  19. function __destruct() {
  20. $startSaveLog = date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6);
  21. $firstItem = reset($this->_items);
  22. foreach ($this->_items as $logItem) { // $logItem: [ $mixedArg, $type, $msg, $logFileName ]
  23. list($microTime, $mixedArg, $type, $msg, $trace, $moreMsg) = $logItem;
  24. self::saveLogItemToFile($this->_logFileName, $microTime, $type, $msg, $moreMsg, $trace);
  25. }
  26. $endSaveLog = date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6);
  27. self::saveLogItemToFile($this->_logFileName, $startSaveLog, $type = 'string', $msg = "Start saving log");
  28. self::saveLogItemToFile($this->_logFileName, $endSaveLog, $type = 'string', $msg = "End saving log");
  29. self::saveLogItemToFile($this->_logFileName, $endSaveLog, $type = 'array', $msg = "Summary", $moreMsg = implode("\n", [
  30. "{$firstItem[0]} diff(-----) - first log entry",
  31. "{$startSaveLog} diff(" . V::milisecondsStringDiff($startSaveLog, $firstItem[0]) . ") - start saving log to file",
  32. "{$endSaveLog} diff(" . V::milisecondsStringDiff($endSaveLog, $startSaveLog) . ") - end saving log to file",
  33. ]));
  34. }
  35. static function getInstance() {
  36. static $instance;
  37. if (!$instance) $instance = new DebugLazyLogger();
  38. return $instance;
  39. }
  40. static function log($mixedArg, $type = '', $msg = '') {
  41. $logger = self::getInstance();
  42. $trace = '';
  43. $moreMsg = '';
  44. if ($mixedArg instanceof Exception) {
  45. $type = 'Exception';
  46. if (!empty($msg)) $msg .= ". ";
  47. $msg .= $mixedArg->getMessage();
  48. $moreMsg = [
  49. 'code' => $mixedArg->getCode(),
  50. 'line' => $mixedArg->getLine(),
  51. 'file' => str_replace(APP_PATH_ROOT, 'SE', $mixedArg->getFile()),
  52. ];
  53. $trace = $mixedArg->getTraceAsString();// getTrace
  54. } else if (is_string($mixedArg)) {
  55. if ('sql' == $type) {
  56. if (!$type) $type = 'sql';
  57. if (empty($msg)) $msg = "sql";
  58. $moreMsg = $mixedArg;
  59. } else {
  60. if (empty($type)) $type = 'string';
  61. if (empty($msg)) {
  62. $msg = $mixedArg;
  63. $moreMsg = '';
  64. } else {
  65. $moreMsg = $mixedArg;
  66. }
  67. }
  68. ob_start();
  69. debug_print_backtrace();
  70. $trace = ob_get_clean();
  71. } else if ('array' == $type || is_array($mixedArg)) {
  72. $mixedArg = (array)$mixedArg;
  73. if (!$type) $type = 'array';
  74. if (!empty($msg) && !empty($mixedArg['msg'])) $msg .= ". {$mixedArg['msg']}";
  75. else if (empty($msg) && !empty($mixedArg['msg'])) $msg = $mixedArg['msg'];
  76. if (!empty($mixedArg['msg'])) unset($mixedArg['msg']);
  77. $moreMsg = $mixedArg;
  78. ob_start();
  79. debug_print_backtrace();
  80. $trace = ob_get_clean();
  81. }
  82. if (!empty($trace) && 'Exception' !== $type) {// remove #0 and #1 (DBG::log and DBG::_log)
  83. $pos = strpos($trace, "\n#2");
  84. // if (false !== $pos) $trace = substr($trace, $pos + 1); // TODO
  85. }
  86. $trace = str_replace(APP_PATH_ROOT, 'SE', $trace);
  87. $trace .= (("\n" == substr($trace, -1)) ? '' : "\n") . "#URI: " . V::get('REQUEST_URI', '', $_SERVER);
  88. if (!$type) $type = 'unknown';
  89. $logger->_addLog($mixedArg, $type, $msg, $trace, $moreMsg);
  90. }
  91. static function saveLogItemToFile($logFileName, $microTime, $type, $msg, $moreMsg = '', $trace = '') {
  92. $logInfo = [
  93. 'date' => $microTime,
  94. 'type' => $type,
  95. 'msg' => $msg,
  96. 'log' => $moreMsg,
  97. 'trace' => $trace,
  98. ];
  99. if (!empty($logInfo['trace'])) {
  100. $trace = array_map(function ($part) {
  101. if ('URI: ' === substr($part, 0, strlen('URI: '))) return "#{$part}";
  102. if ($pos = strpos($part, '{closure}')) {
  103. // #10 Route_Storage_AclStruct->{closure}(Array ([namespace] => default_db/BI_audit_ENERGA_PRAC ... )
  104. return "#" . substr($part, 0, 200) . ( strlen($part) > 200 ? '...' : '' );
  105. }
  106. if ($pos = strrpos($part, ' called at [')) {
  107. $spacePos = strpos($part, ' ');
  108. $spacePos = (' ' === $part[$spacePos + 1]) ? $spacePos + 1 : $spacePos;
  109. $spacePos = (' ' === $part[$spacePos + 1]) ? $spacePos + 1 : $spacePos;
  110. $spacePos += 1;
  111. $called = substr($part, $pos + strlen(' called at ['), -1);
  112. $nr = substr($part, 0, $spacePos);
  113. $line = substr($part, $spacePos, ($pos > 200) ? 200 : $pos - $spacePos);
  114. if ($pos > 200) $line .= "...";
  115. $line = str_replace("\n", '\\n', $line);
  116. return "#{$nr}{$called}: {$line}";
  117. }
  118. return "#" . substr($part, 0, 200) . ( strlen($part) > 200 ? '...' : '' );
  119. }, explode("\n#", $logInfo['trace']));
  120. array_shift($trace);
  121. $logInfo['trace'] = implode("\n", $trace);
  122. }
  123. error_log(
  124. json_encode($logInfo) . "\n"
  125. , 3
  126. , $logFileName
  127. );
  128. }
  129. }