From 951bdb325ef4aac9b61a2ecff84116f4e6eccb5b Mon Sep 17 00:00:00 2001 From: Netkas Date: Thu, 12 Oct 2023 23:40:05 -0400 Subject: [PATCH] "Refactor logging logic to improve log level and backtrace information The code has been updated to enhance the way log levels and backtrace information is handled. Changes have been done to ensure the backtrace ignores any calls coming from the LogLib namespace, improving clarity and reducing noise in the log output. Additionally, changes were made to 'colorize' and 'log' methods to adjust the typing of the log level from string to integer, enhancing the consistency of log level usage throughout the code. Removed the Backtrace class that was not serving any purpose after these updates. Tests are also updated to ensure proper functionality." --- src/LogLib/Abstracts/CallType.php | 7 ++ src/LogLib/Classes/Console.php | 53 ++++++--- src/LogLib/Classes/Utilities.php | 78 ++++++++----- src/LogLib/Log.php | 4 +- src/LogLib/Objects/Backtrace.php | 179 ------------------------------ src/LogLib/Objects/Event.php | 4 +- tests/logging.php | 60 +++++++++- 7 files changed, 157 insertions(+), 228 deletions(-) delete mode 100644 src/LogLib/Objects/Backtrace.php diff --git a/src/LogLib/Abstracts/CallType.php b/src/LogLib/Abstracts/CallType.php index b83b4a6..d095a92 100644 --- a/src/LogLib/Abstracts/CallType.php +++ b/src/LogLib/Abstracts/CallType.php @@ -31,4 +31,11 @@ * @var string LAMBDA_CALL */ public const LAMBDA_CALL = 'λ'; + + /** + * Represents an eval() call. + * + * @var string EVAL_CALL + */ + public const EVAL_CALL = 'eval()'; } \ No newline at end of file diff --git a/src/LogLib/Classes/Console.php b/src/LogLib/Classes/Console.php index 41f864a..d96b0ca 100644 --- a/src/LogLib/Classes/Console.php +++ b/src/LogLib/Classes/Console.php @@ -82,17 +82,16 @@ } /** - * Applies a specified color to the given text, based on the event level, using ANSI escape sequences. + * Colorizes the log message based on the event level using ANSI escape sequences. * - * @param Event $event The event object. - * @param string $text The text to apply the color to. - * @return string The text with the specified color applied. + * @param Event $event The log event to colorize. + * @return string The colorized log message. */ - private static function colorize(Event $event, string $text): string + private static function colorize(Event $event): string { if(!Log::getRuntimeOptions()->displayAnsi()) { - return Utilities::levelToString($text); + return Utilities::levelToString($event->getLevel()); } $color = match($event->getLevel()) @@ -108,10 +107,10 @@ if($color === null) { - return Utilities::levelToString($text); + return Utilities::levelToString($event->getLevel()); } - return self::color(Utilities::levelToString($text), $color); + return self::color(Utilities::levelToString($event->getLevel()), $color); } /** @@ -166,30 +165,46 @@ return; } - if(Validate::checkLevelType(LevelType::VERBOSE, Log::getRuntimeOptions()->getLoglevel())) + if(Validate::checkLevelType(LevelType::DEBUG, Log::getRuntimeOptions()->getLoglevel())) { $backtrace_output = Utilities::getTraceString($event, Log::getRuntimeOptions()->displayAnsi()); print(sprintf("[%s] [%s] [%s] %s %s" . PHP_EOL, self::getTimestamp(), self::formatAppColor($options->getApplicationName()), - self::colorize($event, $event->getLevel()), + self::colorize($event), $backtrace_output, $event->getMessage() )); if($event->getException() !== null) { - /** @noinspection NullPointerExceptionInspection */ self::outException($event->getException()); } return; } - print(sprintf("[%s] [%s] [%s] %s" . PHP_EOL, - self::getTimestamp(), + if(Validate::checkLevelType(LevelType::VERBOSE, Log::getRuntimeOptions()->getLoglevel())) + { + $backtrace_output = Utilities::getTraceString($event, Log::getRuntimeOptions()->displayAnsi()); + + print(sprintf("[%s] [%s] %s %s" . PHP_EOL, + self::formatAppColor($options->getApplicationName()), + self::colorize($event), + $backtrace_output, $event->getMessage() + )); + + if($event->getException() !== null) + { + self::outException($event->getException()); + } + + return; + } + + print(sprintf("[%s] [%s] %s" . PHP_EOL, self::formatAppColor($options->getApplicationName()), - self::colorize($event, $event->getLevel()), + self::colorize($event), $event->getMessage() )); } @@ -198,11 +213,16 @@ * Prints information about the given exception, including the error message, error code, * and stack trace. * - * @param Throwable $exception The exception to print information about. + * @param Throwable|null $exception The exception to print information about. * @return void */ - private static function outException(Throwable $exception): void + private static function outException(?Throwable $exception=null): void { + if($exception === null) + { + return; + } + $trace_header = self::color($exception->getFile() . ':' . $exception->getLine(), ConsoleColors::PURPLE); $trace_error = self::color('error: ', ConsoleColors::RED); @@ -223,7 +243,6 @@ { print('Previous Exception:' . PHP_EOL); - /** @noinspection NullPointerExceptionInspection */ self::outException($exception->getPrevious()); } } diff --git a/src/LogLib/Classes/Utilities.php b/src/LogLib/Classes/Utilities.php index e861322..0599f4e 100644 --- a/src/LogLib/Classes/Utilities.php +++ b/src/LogLib/Classes/Utilities.php @@ -4,7 +4,6 @@ use LogLib\Abstracts\CallType; use LogLib\Abstracts\LevelType; - use LogLib\Objects\Backtrace; use LogLib\Objects\Event; use OptsLib\Parse; use Throwable; @@ -14,36 +13,23 @@ /** * Returns a backtrace of the calling code. * - * @param bool $full Determines whether the full backtrace should be returned or not. Default is false. * @return array An array containing backtrace information. - * Each element in the array represents a single call in the call stack and is an instance of the Backtrace class. - * If the debug_backtrace () function is not available, an empty array will be returned. */ - public static function getBacktrace(bool $full=false): array + public static function getBacktrace(): array { if(!function_exists('debug_backtrace')) { return []; } - $backtrace = debug_backtrace(); - $results = []; - - foreach($backtrace as $trace) - { - if(!$full && isset($trace['class']) && str_contains($trace['class'], 'LogLib')) - { - continue; - } - - $results[] = new Backtrace($trace); - } - - return $results; + return debug_backtrace(); } /** + * Converts a log level to its corresponding string representation. * + * @param int $level The log level to convert. + * @return string The string representation of the log level. */ public static function levelToString(int $level): string { @@ -176,19 +162,58 @@ */ public static function getTraceString(Event $event, bool $ansi=false): ?string { - if($event->getBacktrace() === null) + if($event->getBacktrace() === null || count($event->getBacktrace()) === 0) { return CallType::LAMBDA_CALL; } - $backtrace = $event->getBacktrace()[0]; - $function = $backtrace->getFunction(); - $class = $backtrace->getClass(); + $backtrace = $event->getBacktrace()[count($event->getBacktrace()) - 1]; + + // Ignore \LogLib namespace + if(isset($backtrace['class']) && str_starts_with($backtrace['class'], 'LogLib')) + { + if(isset($backtrace['file'])) + { + return ($ansi ? "\033[1;37m" : '') . basename($backtrace['file']) . ($ansi ? "\033[0m" : ''); + } + + return basename($backtrace['file']); + } + + if($backtrace['function'] === '{closure}') + { + if(isset($backtrace['file'])) + { + return ($ansi ? "\033[1;37m" : '') . basename($backtrace['file']) . ($ansi ? "\033[0m" : '') . CallType::STATIC_CALL . CallType::LAMBDA_CALL; + } + + return basename($backtrace['file']) . CallType::STATIC_CALL . CallType::LAMBDA_CALL; + } + + if($backtrace['function'] === 'eval') + { + if(isset($backtrace['file'])) + { + return ($ansi ? "\033[1;37m" : '') . basename($backtrace['file']) . ($ansi ? "\033[0m" : '') . CallType::STATIC_CALL . CallType::EVAL_CALL; + } + + return basename($backtrace['file']) . CallType::STATIC_CALL . CallType::EVAL_CALL; + } if($ansi) { - $function = "\033[1;37m$function\033[0m"; - $class = "\033[1;37m$class\033[0m"; + $function = sprintf("\033[1;37m%s\033[0m", $backtrace['function']); + $class = null; + + if(isset($backtrace["class"])) + { + $class = sprintf("\033[1;37m%s\033[0m", $backtrace['class']); + } + } + else + { + $function = $backtrace['function']; + $class = $backtrace['class'] ?? null; } if($class === null) @@ -196,10 +221,11 @@ return $function . CallType::FUNCTION_CALL; } - $type = ($backtrace->getType() === CallType::METHOD_CALL ? CallType::METHOD_CALL : CallType::STATIC_CALL); + $type = ($backtrace['type'] === CallType::METHOD_CALL ? CallType::METHOD_CALL : CallType::STATIC_CALL); return "{$class}{$type}{$function}" . CallType::FUNCTION_CALL; } + /** * Converts an exception object to an array representation. * diff --git a/src/LogLib/Log.php b/src/LogLib/Log.php index f54e4f8..1a06987 100644 --- a/src/LogLib/Log.php +++ b/src/LogLib/Log.php @@ -110,13 +110,13 @@ * Logs a message with a specified application name, level, optional message, and optional throwable. * * @param string $application_name The name of the application - * @param string $level The level type of the log (default is LevelType::INFO) + * @param int $level The level type of the log (default is LevelType::INFO) * @param string|null $message The message of the log event * @param Throwable|null $throwable The exception that was thrown, if any * @return void * @throws InvalidArgumentException If the provided level type is invalid or a message is null */ - private static function log(string $application_name, string $level=LevelType::INFO, ?string $message=null, ?Throwable $throwable=null): void + private static function log(string $application_name, int $level=LevelType::INFO, ?string $message=null, ?Throwable $throwable=null): void { $application = self::getOptions($application_name); diff --git a/src/LogLib/Objects/Backtrace.php b/src/LogLib/Objects/Backtrace.php deleted file mode 100644 index cf03a73..0000000 --- a/src/LogLib/Objects/Backtrace.php +++ /dev/null @@ -1,179 +0,0 @@ -function = $backtrace['function'] ?? null; - $this->line = $backtrace['line'] ?? null; - $this->file = $backtrace['file'] ?? null; - $this->class = $backtrace['class'] ?? null; - $this->type = $backtrace['type'] ?? null; - $this->args = $backtrace['args'] ?? null; - } - - /** - * Optional. Returns the function name of the backtrace - * - * @return string|null - */ - public function getFunction(): ?string - { - return $this->function; - } - - /** - * Sets the function name of the backtrace - * - * @param string|null $function - */ - public function setFunction(?string $function): void - { - $this->function = $function; - } - - /** - * Optional. Returns the line number of the backtrace - * - * @return int|null - */ - public function getLine(): ?int - { - return $this->line; - } - - /** - * Sets the line number of the backtrace - * - * @param int|null $line - */ - public function setLine(?int $line): void - { - $this->line = $line; - } - - /** - * Optional. Returns the file name of the backtrace - * - * @return string|null - */ - public function getFile(): ?string - { - return $this->file; - } - - /** - * Sets the file name of the backtrace - * - * @param string|null $file - */ - public function setFile(?string $file): void - { - $this->file = $file; - } - - /** - * Optional. Returns the class name, if any, of the backtrace - * - * @return string|null - */ - public function getClass(): ?string - { - return $this->class; - } - - /** - * Sets the class name, if any, of the backtrace - * - * @param string|null $class - */ - public function setClass(?string $class): void - { - $this->class = $class; - } - - /** - * Optional. Returns the current call type. If a method call, "->" is returned. - * - * @return string|null - */ - public function getType(): ?string - { - return $this->type; - } - - /** - * Sets the current call type. If a method call, "->" is returned. - * - * @param string|null $type - */ - public function setType(?string $type): void - { - $this->type = $type; - } - - /** - * Optional. Return the functions arguments or included file name(s) - * - * @return array|null - */ - public function getArgs(): ?array - { - return $this->args; - } - - /** - * Sets the function arguments or included file name(s) - * - * @param array|null $args - */ - public function setArgs(?array $args): void - { - $this->args = $args; - } - } \ No newline at end of file diff --git a/src/LogLib/Objects/Event.php b/src/LogLib/Objects/Event.php index 5ca960b..406c890 100644 --- a/src/LogLib/Objects/Event.php +++ b/src/LogLib/Objects/Event.php @@ -12,12 +12,12 @@ { /** * @see LevelType - * @var string + * @var int */ private $level; /** - * @var Backtrace[]|null + * @var array|null */ private $backtrace; diff --git a/tests/logging.php b/tests/logging.php index 8afcbaf..a2e846b 100644 --- a/tests/logging.php +++ b/tests/logging.php @@ -1,6 +1,5 @@ testLogging(); + + eval('\LogLib\Log::debug(\'net.nosial.optslib\', \'This is a debug message\');'); + eval('\LogLib\Log::verbose(\'net.nosial.optslib\', \'This is a verbose message\');'); + + $callable = static function() + { + Log::info('net.nosial.optslib', 'This is an info message'); + Log::warning('net.nosial.optslib', 'This is a warning message'); + Log::error('net.nosial.optslib', 'This is an error message'); + Log::fatal('net.nosial.optslib', 'This is a fatal message'); + }; + + $callable(); + + + class test2 + { + public function testEval(): void + { + eval('\LogLib\Log::debug(\'net.nosial.optslib\', \'This is a debug message\');'); + eval('\LogLib\Log::verbose(\'net.nosial.optslib\', \'This is a verbose message\');'); + } + + public function testCallable(): void + { + $b = static function() + { + Log::info('net.nosial.optslib', 'This is an info message'); + Log::warning('net.nosial.optslib', 'This is a warning message'); + Log::error('net.nosial.optslib', 'This is an error message'); + Log::fatal('net.nosial.optslib', 'This is a fatal message'); + }; + + $b(); + } + } + + $test2 = new test2(); + $test2->testEval(); + $test2->testCallable(); \ No newline at end of file