_items = []; $prefix = ('production' == V::get('P5_ENV', 'production', $_SERVER)) ? "" : "dev-"; $this->_logFileName = "/tmp/{$prefix}se-debug-" . implode('-', [ date("Y-m-d"), User::getLogin(), Request::getUserIp(), substr(session_id(), 0, 6), V::get('REQUEST_TIME', '', $_SERVER)// [REQUEST_TIME] => 1485770466 ]) . '.log'; } function _addLog($mixedArg, $type, $msg, $trace, $moreMsg) { $microTime = date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6); $this->_items[] = [ $microTime, $mixedArg, $type, $msg, $trace, $moreMsg ]; } function __destruct() { $startSaveLog = date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6); $firstItem = reset($this->_items); foreach ($this->_items as $logItem) { // $logItem: [ $mixedArg, $type, $msg, $logFileName ] list($microTime, $mixedArg, $type, $msg, $trace, $moreMsg) = $logItem; self::saveLogItemToFile($this->_logFileName, $microTime, $type, $msg, $moreMsg, $trace); } $endSaveLog = date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6); self::saveLogItemToFile($this->_logFileName, $startSaveLog, $type = 'string', $msg = "Start saving log"); self::saveLogItemToFile($this->_logFileName, $endSaveLog, $type = 'string', $msg = "End saving log"); self::saveLogItemToFile($this->_logFileName, $endSaveLog, $type = 'array', $msg = "Summary", $moreMsg = implode("\n", [ "{$firstItem[0]} diff(-----) - first log entry", "{$startSaveLog} diff(" . V::milisecondsStringDiff($startSaveLog, $firstItem[0]) . ") - start saving log to file", "{$endSaveLog} diff(" . V::milisecondsStringDiff($endSaveLog, $startSaveLog) . ") - end saving log to file", ])); } static function getInstance() { static $instance; if (!$instance) $instance = new DebugLazyLogger(); return $instance; } static function log($mixedArg, $type = '', $msg = '') { $logger = self::getInstance(); $trace = ''; $moreMsg = ''; if ($mixedArg instanceof Exception) { $type = 'Exception'; if (!empty($msg)) $msg .= ". "; $msg .= $mixedArg->getMessage(); $moreMsg = [ 'code' => $mixedArg->getCode(), 'line' => $mixedArg->getLine(), 'file' => str_replace(APP_PATH_ROOT, 'SE', $mixedArg->getFile()), ]; $trace = $mixedArg->getTraceAsString();// getTrace } else if (is_string($mixedArg)) { if ('sql' == $type) { if (!$type) $type = 'sql'; if (empty($msg)) $msg = "sql"; $moreMsg = $mixedArg; } else { if (empty($type)) $type = 'string'; if (empty($msg)) { $msg = $mixedArg; $moreMsg = ''; } else { $moreMsg = $mixedArg; } } ob_start(); debug_print_backtrace(); $trace = ob_get_clean(); } else if ('array' == $type || is_array($mixedArg)) { $mixedArg = (array)$mixedArg; if (!$type) $type = 'array'; if (!empty($msg) && !empty($mixedArg['msg'])) $msg .= ". {$mixedArg['msg']}"; else if (empty($msg) && !empty($mixedArg['msg'])) $msg = $mixedArg['msg']; if (!empty($mixedArg['msg'])) unset($mixedArg['msg']); $moreMsg = $mixedArg; ob_start(); debug_print_backtrace(); $trace = ob_get_clean(); } if (!empty($trace) && 'Exception' !== $type) {// remove #0 and #1 (DBG::log and DBG::_log) $pos = strpos($trace, "\n#2"); // if (false !== $pos) $trace = substr($trace, $pos + 1); // TODO } $trace = str_replace(APP_PATH_ROOT, 'SE', $trace); $trace .= (("\n" == substr($trace, -1)) ? '' : "\n") . "#URI: " . V::get('REQUEST_URI', '', $_SERVER); if (!$type) $type = 'unknown'; $logger->_addLog($mixedArg, $type, $msg, $trace, $moreMsg); } static function saveLogItemToFile($logFileName, $microTime, $type, $msg, $moreMsg = '', $trace = '') { $logInfo = [ 'date' => $microTime, 'type' => $type, 'msg' => $msg, 'log' => $moreMsg, 'trace' => $trace, ]; if (!empty($logInfo['trace'])) { $trace = array_map(function ($part) { if ('URI: ' === substr($part, 0, strlen('URI: '))) return "#{$part}"; if ($pos = strpos($part, '{closure}')) { // #10 Route_Storage_AclStruct->{closure}(Array ([namespace] => default_db/BI_audit_ENERGA_PRAC ... ) return "#" . substr($part, 0, 200) . ( strlen($part) > 200 ? '...' : '' ); } if ($pos = strrpos($part, ' called at [')) { $spacePos = strpos($part, ' '); $spacePos = (' ' === $part[$spacePos + 1]) ? $spacePos + 1 : $spacePos; $spacePos = (' ' === $part[$spacePos + 1]) ? $spacePos + 1 : $spacePos; $spacePos += 1; $called = substr($part, $pos + strlen(' called at ['), -1); $nr = substr($part, 0, $spacePos); $line = substr($part, $spacePos, ($pos > 200) ? 200 : $pos - $spacePos); if ($pos > 200) $line .= "..."; $line = str_replace("\n", '\\n', $line); return "#{$nr}{$called}: {$line}"; } return "#" . substr($part, 0, 200) . ( strlen($part) > 200 ? '...' : '' ); }, explode("\n#", $logInfo['trace'])); array_shift($trace); $logInfo['trace'] = implode("\n", $trace); } error_log( json_encode($logInfo) . "\n" , 3 , $logFileName ); } }