_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) { $microTime = date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6); $this->_items[] = [ $microTime, $mixedArg, $type, $msg ]; } 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) = $logItem; self::saveLogItemToFile($microTime, $mixedArg, $type, $msg, $this->_logFileName); } $endSaveLog = date("Y-m-d H:i:s") . substr((string)microtime(), 1, 6); self::saveLogItemToFile($startSaveLog, $mixedArg = null, $type = 'string', $msg = "Start saving log", $this->_logFileName); self::saveLogItemToFile($endSaveLog, $mixedArg = null, $type = 'string', $msg = "End saving log", $this->_logFileName); self::saveLogItemToFile($endSaveLog, $mixedArg = [ "{$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", ], $type = 'array', $msg = "Summary", $this->_logFileName); } static function getInstance() { static $instance; if (!$instance) $instance = new DebugLazyLogger(); return $instance; } static function log($mixedArg, $type, $msg) { $logger = self::getInstance(); $logger->addLog($mixedArg, $type, $msg); } static function saveLogItemToFile($microTime ,$mixedArg, $type, $msg, $logFileName) { $logInfo = [ 'date' => $microTime, 'type' => $type, 'msg' => $msg, 'log' => '', 'trace' => '', ]; if ($mixedArg instanceof Exception) { $logInfo['type'] = 'Exception'; if (!empty($logInfo['msg'])) $logInfo['msg'] .= ". "; $logInfo['msg'] .= $mixedArg->getMessage(); $logInfo['log'] = [ 'code' => $mixedArg->getCode(), 'line' => $mixedArg->getLine(), 'file' => str_replace(APP_PATH_ROOT, 'SE', $mixedArg->getFile()), ]; $logInfo['trace'] = $mixedArg->getTraceAsString();// getTrace } else if (is_string($mixedArg)) { if ('sql' == $type) { if (!$logInfo['type']) $logInfo['type'] = 'sql'; if (empty($logInfo['msg'])) $logInfo['msg'] = "sql"; $logInfo['log'] = $mixedArg; } else { if (empty($logInfo['type'])) $logInfo['type'] = 'string'; if (empty($msg)) { $logInfo['msg'] = $mixedArg; $logInfo['log'] = ''; } else { $logInfo['msg'] = $msg; $logInfo['log'] = $mixedArg; } } ob_start(); debug_print_backtrace(); $logInfo['trace'] = ob_get_clean(); } else if ('array' == $type || is_array($mixedArg)) { $mixedArg = (array)$mixedArg; if (!$logInfo['type']) $logInfo['type'] = 'array'; if (!empty($logInfo['msg']) && !empty($mixedArg['msg'])) $logInfo['msg'] .= ". {$mixedArg['msg']}"; else if (empty($logInfo['msg']) && !empty($mixedArg['msg'])) $logInfo['msg'] = $mixedArg['msg']; if (!empty($mixedArg['msg'])) unset($mixedArg['msg']); $logInfo['log'] = $mixedArg; ob_start(); debug_print_backtrace(); $logInfo['trace'] = ob_get_clean(); } if (!empty($logInfo['trace']) && 'Exception' !== $logInfo['type']) {// remove #0 and #1 (DBG::log and DBG::_log) $pos = strpos($logInfo['trace'], "\n#2"); // if (false !== $pos) $logInfo['trace'] = substr($logInfo['trace'], $pos + 1); // TODO } $logInfo['trace'] = str_replace(APP_PATH_ROOT, 'SE', $logInfo['trace']); $logInfo['trace'] .= (("\n" == substr($logInfo['trace'], -1)) ? '' : "\n") . "#URI: " . V::get('REQUEST_URI', '', $_SERVER); if (!$logInfo['type']) $logInfo['type'] = 'unknown'; 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 ); } }