diff --git a/server/Fury/Kernel/Logging.php b/server/Fury/Kernel/Logging.php index a0419b4..ee916b2 100644 --- a/server/Fury/Kernel/Logging.php +++ b/server/Fury/Kernel/Logging.php @@ -134,9 +134,15 @@ 'context' => $this -> redact($context), ]; - $line = json_encode($entry, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n"; + $line = json_encode($entry, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + if ($line === false) { + $entry['context'] = ['error' => 'Context serialization failed: ' . json_last_error_msg()]; + $line = json_encode($entry, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); + } + $line .= "\n"; $path = $this -> get_jsonl_path(); + $is_new_file = !file_exists($path); $this -> rotate_if_needed($path); $this -> cleanup_if_needed(); @@ -150,7 +156,9 @@ flock($fp, LOCK_UN); } fclose($fp); - chmod($path, 0644); + if ($is_new_file) { + chmod($path, 0644); + } return true; } diff --git a/server/Fury/Modules/ErrorHandler/ErrorHandler.php b/server/Fury/Modules/ErrorHandler/ErrorHandler.php index a7267e9..aac4498 100644 --- a/server/Fury/Modules/ErrorHandler/ErrorHandler.php +++ b/server/Fury/Modules/ErrorHandler/ErrorHandler.php @@ -42,18 +42,12 @@ } public function exception_handler(\Throwable $e) { - logging() -> error('php:ErrorHandler', $e -> getMessage(), [ - 'code' => $e -> getCode(), - 'file' => $e -> getFile(), - 'line' => $e -> getLine(), - 'trace' => $e -> getTraceAsString(), - ]); - $this -> error_handler( - (int) $e -> getCode(), + E_ERROR, $e -> getMessage(), $e -> getFile(), - $e -> getLine() + $e -> getLine(), + $e -> getTraceAsString() ); } @@ -77,18 +71,23 @@ /** * Handle of error */ - public function error_handler(Int $errno, String $errstr, String $errfile, Int $errline){ + public function error_handler(Int $errno, String $errstr, String $errfile, Int $errline, ?string $trace = null){ $err_type = $this -> get_err_type($errno); if(!$this -> error_is_important($err_type)){ return true; } - logging() -> error('php:ErrorHandler', $errstr, [ + $context = [ 'errno' => $errno, 'errtype' => $err_type, 'errfile' => $errfile, 'errline' => $errline, - ]); + ]; + if ($trace !== null) { + $context['trace'] = $trace; + } + + logging() -> error('php:ErrorHandler', $errstr, $context); $this -> view_fatal_error($errno, $errstr, $errfile, $errline); return true; diff --git a/server/SHServ/Middleware/RequestLogger.php b/server/SHServ/Middleware/RequestLogger.php index 78e52dc..2771fbe 100644 --- a/server/SHServ/Middleware/RequestLogger.php +++ b/server/SHServ/Middleware/RequestLogger.php @@ -16,8 +16,24 @@ protected static ?float $start_time = null; protected static bool $completed = false; protected static ?string $action_name = null; + protected static bool $initialized = false; + + public static function reset(): void { + self::$initialized = false; + self::$start_time = null; + self::$completed = false; + self::$action_name = null; + } public function __construct() { + if (self::$initialized) { + return; + } + self::$initialized = true; + self::$start_time = null; + self::$completed = false; + self::$action_name = null; + global $argv; $is_cli = isset($argv); diff --git a/server/SHServ/Middleware/SqlQueryLogger.php b/server/SHServ/Middleware/SqlQueryLogger.php index 5e29aac..28b430c 100644 --- a/server/SHServ/Middleware/SqlQueryLogger.php +++ b/server/SHServ/Middleware/SqlQueryLogger.php @@ -21,19 +21,29 @@ if ($sql === '') { return; } - self::$pending[$sql] = microtime(true); + self::$pending[] = ['sql' => $sql, 'start' => microtime(true)]; }); events() -> handler('module:ThinBuilder.query', function(Array $params) { $sql = $params['sql'] ?? ''; $result = $params['result'] ?? null; - if ($sql === '' || !isset(self::$pending[$sql])) { + if ($sql === '') { return; } - $start = self::$pending[$sql]; - unset(self::$pending[$sql]); + $start = null; + foreach (self::$pending as $i => $item) { + if ($item['sql'] === $sql) { + $start = $item['start']; + unset(self::$pending[$i]); + break; + } + } + + if ($start === null) { + return; + } $duration_ms = round((microtime(true) - $start) * 1000, 3); $level = $duration_ms > 1000 ? 'WARN' : 'INFO'; @@ -44,6 +54,8 @@ $row_count = count($result); } elseif (is_int($result) || is_numeric($result)) { $row_count = (int) $result; + } elseif (is_bool($result)) { + $row_count = $result ? 1 : 0; } $context = [ @@ -63,9 +75,9 @@ if (empty(self::$pending)) { return; } - foreach (self::$pending as $sql => $start) { + foreach (self::$pending as $item) { logging() -> info('php:ThinBuilder', 'Query planned but not executed', [ - 'sql' => $sql, + 'sql' => $item['sql'], ]); } self::$pending = [];