diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c416e4a..a1fc214 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,43 +1,42 @@ -image: php:8.1 +image: repo.n64.cc:443/nosial/ncc:latest -before_script: - # Install some stuff that the image doesn't come with - - apt update -yqq - - apt install git libpq-dev libzip-dev zip make wget gnupg -yqq +stages: + - build + - publish - # Install phive - - wget -O phive.phar https://phar.io/releases/phive.phar - - wget -O phive.phar.asc https://phar.io/releases/phive.phar.asc - - gpg --keyserver hkps://keys.openpgp.org --recv-keys 0x9D8A98B29B2D5D79 - - gpg --verify phive.phar.asc phive.phar - - chmod +x phive.phar - - mv phive.phar /usr/local/bin/phive - - # Install phab - - phive install phpab --global --trust-gpg-keys 0x2A8299CE842DD38C - - # Install the latest version of ncc (Nosial Code Compiler) - - git clone https://git.n64.cc/nosial/ncc.git - - cd ncc - - make redist - - php build/src/INSTALL --auto --install-composer - - cd .. && rm -rf ncc +variables: + PACKAGE_NAME: $CI_COMMIT_REF_NAME build: + stage: build script: - - ncc build --config release --log-level debug + - ncc build --config release --log-level debug -o "build/release/net.nosial.loglib.ncc" artifacts: paths: - - build/ - rules: - - if: $CI_COMMIT_BRANCH + - "build/release/net.nosial.loglib.ncc" -release: - stage: deploy +build_static: + stage: build script: - - ncc build --config release --log-level debug + - ncc build --config release_static --log-level debug -o "build/release/net.nosial.loglib_static.ncc" artifacts: paths: - - build/ - rules: - - if: $CI_COMMIT_TAG \ No newline at end of file + - "build/release/net.nosial.loglib_static.ncc" + +publish: + stage: publish + before_script: + - 'if [ "$CI_COMMIT_REF_NAME" == "master" ]; then PACKAGE_NAME="latest"; fi' + script: + - | + curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/release/net.nosial.loglib.ncc \ + "https://$CI_SERVER_HOST/api/v4/projects/$CI_PROJECT_ID/packages/generic/${PACKAGE_NAME}/${CI_COMMIT_SHA}/net.nosial.loglib.ncc" + +publish_static: + stage: publish + before_script: + - 'if [ "$CI_COMMIT_REF_NAME" == "master" ]; then PACKAGE_NAME="latest"; fi' + script: + - | + curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file build/release/net.nosial.loglib_static.ncc \ + "https://$CI_SERVER_HOST/api/v4/projects/$CI_PROJECT_ID/packages/generic/${PACKAGE_NAME}/${CI_COMMIT_SHA}/net.nosial.loglib_static.ncc" \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml index cb05848..d821935 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -12,8 +12,7 @@ - - + diff --git a/CHANGELOG.md b/CHANGELOG.md index af3fabb..82ac448 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.0] - Unreleased + +Updated loglib to work with ncc 2.+. + +### Changed + + - Various code improvements and optimizations + - Removed unused code + + ## [1.0.2] - 2023-07-06 ### Changed @@ -15,12 +25,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Fixed mistake in `\LogLib\Classes > Console > outException()` where the function attempts to print out a previous exception by calling `getPrevious()` as an array instead of a function call. + ## [1.0.1] - 2023-02-10 ### Added * Added PSR compatible LoggerInterface implementation (\LogLib\Psr) * Added new option `--log-level` to set the log level (Can also be applied via the environment variable `LOG_LEVEL`) + ## [1.0.0] - 2023-01-29 ### Added diff --git a/Makefile b/Makefile index 335f36b..9494615 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,37 @@ -build: - ncc build --config="release" --log-level debug +# Variables +NCC = ncc +PACKAGE_NAME = net.nosial.loglib.ncc +BUILD_CONFIG = release +BUILD_STATIC_CONFIG = release_static -install: - sudo ncc package install --package="build/release/net.nosial.loglib.ncc" --skip-dependencies --reinstall -y --log-level debug +# Directories +SRC_DIR = src +BUILD_DIR = build +RELEASE_BUILD_DIR = $(BUILD_DIR)/$(BUILD_CONFIG) +RELEASE_STATIC_BUILD_DIR = $(BUILD_DIR)/$(BUILD_STATIC_CONFIG) + +.PHONY: all release release_static install uninstall clean + +all: release release_static install + +release: prepare_build + $(NCC) build --config=$(BUILD_CONFIG) --out-dir=$(RELEASE_BUILD_DIR) + +release_static: prepare_build_static + $(NCC) build --config=$(BUILD_STATIC_CONFIG) --out-dir=$(RELEASE_STATIC_BUILD_DIR) + +install: prepare_build + $(NCC) package install --package="$(RELEASE_BUILD_DIR)/$(PACKAGE_NAME)" --skip-dependencies -y + +uninstall: + $(NCC) package uninstall -y --package="$(PACKAGE_NAME)" clean: - rm -rf build \ No newline at end of file + rm -rf $(RELEASE_BUILD_DIR) + rm -rf $(RELEASE_STATIC_BUILD_DIR) + +prepare_build: + mkdir -p $(RELEASE_BUILD_DIR) + +prepare_build_static: + mkdir -p $(RELEASE_STATIC_BUILD_DIR) \ No newline at end of file diff --git a/README.md b/README.md index 9d8d5b6..b3f760c 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ the `build.dependencies` section: { "name": "net.nosial.loglib", "version": "latest", - "source_type": "remote", "source": "nosial/libs.log=latest@n64" } ``` @@ -70,12 +69,12 @@ multiple error levels that can be used to log messages require 'ncc'; import('net.nosial.loglib'); - \LogLib\Log::debug('This is a debug message'); - \LogLib\Log::verbose('This is a verbose message'); - \LogLib\Log::info('This is an info message'); - \LogLib\Log::warning('This is a warning message'); - \LogLib\Log::error('This is an error message'); - \LogLib\Log::fatal('This is a fatal message'); + \LogLib\Log::debug('com.example.lib', 'This is a debug message'); + \LogLib\Log::verbose('com.example.lib', 'This is a verbose message'); + \LogLib\Log::info('com.example.lib', 'This is an info message'); + \LogLib\Log::warning('com.example.lib', 'This is a warning message'); + \LogLib\Log::error('com.example.lib', 'This is an error message'); + \LogLib\Log::fatal('com.example.lib', 'This is a fatal message'); ``` diff --git a/project.json b/project.json index 642b01a..3f75430 100644 --- a/project.json +++ b/project.json @@ -31,7 +31,6 @@ { "name": "net.nosial.optslib", "version": "latest", - "source_type": "remote", "source": "nosial/libs.opts=latest@n64" } ], @@ -39,10 +38,15 @@ { "name": "release", "build_type": "ncc", + "output": "build/release/%ASSEMBLY.PACKAGE%.ncc" + }, + { + "name": "release_static", + "build_type": "ncc", "options": { - "compression": "high" + "static": true }, - "output_path": "build/release" + "output": "build/release/%ASSEMBLY.PACKAGE%_static.ncc" } ] } diff --git a/src/LogLib/Abstracts/CallType.php b/src/LogLib/Abstracts/CallType.php index 5673b50..b83b4a6 100644 --- a/src/LogLib/Abstracts/CallType.php +++ b/src/LogLib/Abstracts/CallType.php @@ -2,9 +2,33 @@ namespace LogLib\Abstracts; - abstract class CallType + final class CallType { - const MethodCall = '->'; - const StaticCall = '::'; - const FunctionCall = ' '; + /** + * Represents a method call. + * + * @var string METHOD_CALL + */ + public const METHOD_CALL = '->'; + + /** + * Represents a static method call. + * + * @var string STATIC_CALL + */ + public const STATIC_CALL = '::'; + + /** + * Represents a function call. + * + * @var string FUNCTION_CALL + */ + public const FUNCTION_CALL = '()'; + + /** + * Represents a lambda function call. + * + * @var string LAMBDA_CALL + */ + public const LAMBDA_CALL = 'λ'; } \ No newline at end of file diff --git a/src/LogLib/Abstracts/ConsoleColors.php b/src/LogLib/Abstracts/ConsoleColors.php index 648c549..fe0f4cb 100644 --- a/src/LogLib/Abstracts/ConsoleColors.php +++ b/src/LogLib/Abstracts/ConsoleColors.php @@ -2,53 +2,74 @@ namespace LogLib\Abstracts; - abstract class ConsoleColors + final class ConsoleColors { - const Black = "0;30"; - const DarkGray = "1;30"; - const Blue = "0;34"; - const LightBlue = "1;34"; - const Green = "0;32"; - const LightGreen = "1;32"; - const Cyan = "0;36"; - const LightCyan = "1;36"; - const Red = "0;31"; - const LightRed = "1;31"; - const Purple = "0;35"; - const LightPurple = "1;35"; - const Brown = "0;33"; - const Yellow = "1;33"; - const LightGray = "0;37"; - const White = "1;37"; - const Reset = "0"; + public const BLACK = "0;30"; - const All = [ - self::Black, - self::DarkGray, - self::Blue, - self::LightBlue, - self::Green, - self::LightGreen, - self::Cyan, - self::LightCyan, - self::Red, - self::LightRed, - self::Purple, - self::LightPurple, - self::Brown, - self::Yellow, - self::LightGray, - self::White + public const DARK_GRAY = "1;30"; + + public const BLUE = "0;34"; + + public const LIGHT_BLUE = "1;34"; + + public const GREEN = "0;32"; + + public const LIGHT_GREEN = "1;32"; + + public const CYAN = "0;36"; + + public const LIGHT_CYAN = "1;36"; + + public const RED = "0;31"; + + public const LIGHT_RED = "1;31"; + + public const PURPLE = "0;35"; + + public const LIGHT_PURPLE = "1;35"; + + public const BROWN = "0;33"; + + public const YELLOW = "1;33"; + + public const LIGHT_GRAY = "0;37"; + + public const WHITE = "1;37"; + + public const RESET = "0"; + + /** + * Represents an array of all possible supported color values. + * + * @var array + */ + public const ALL = [ + self::BLACK, + self::DARK_GRAY, + self::BLUE, + self::LIGHT_BLUE, + self::GREEN, + self::LIGHT_GREEN, + self::CYAN, + self::LIGHT_CYAN, + self::RED, + self::LIGHT_RED, + self::PURPLE, + self::LIGHT_PURPLE, + self::BROWN, + self::YELLOW, + self::LIGHT_GRAY, + self::WHITE ]; /** * A list of random usable bright colors */ - const BrightColors = [ - self::LightBlue, - self::LightGreen, - self::LightCyan, - self::LightRed, - self::LightPurple, + public const BRIGHT_COLORS = [ + self::LIGHT_BLUE, + self::LIGHT_GREEN, + self::LIGHT_CYAN, + self::LIGHT_RED, + self::LIGHT_PURPLE, ]; } \ No newline at end of file diff --git a/src/LogLib/Abstracts/LevelType.php b/src/LogLib/Abstracts/LevelType.php index 661ee9b..8fddd47 100644 --- a/src/LogLib/Abstracts/LevelType.php +++ b/src/LogLib/Abstracts/LevelType.php @@ -2,26 +2,53 @@ namespace LogLib\Abstracts; - abstract class LevelType + final class LevelType { - const Silent = 0; - const Fatal = 1; - const Error = 2; - const Warning = 3; - const Info = 4; - const Verbose = 5; - const Debug = 6; + /** + * Silent type. + */ + public const SILENT = 0; + + /** + * Fatal type. + */ + public const FATAL = 1; + + /** + * Error type. + */ + public const ERROR = 2; + + /** + * + */ + public const WARNING = 3; + + /** + * Information type. + */ + public const INFO = 4; + + /** + * Verbose type. + */ + public const VERBOSE = 5; + + /** + * Debug type. + */ + public const DEBUG = 6; /** * All types. */ - const All = [ - self::Silent, - self::Fatal, - self::Error, - self::Warning, - self::Info, - self::Verbose, - self::Debug + public const ALL = [ + self::SILENT, + self::FATAL, + self::ERROR, + self::WARNING, + self::INFO, + self::VERBOSE, + self::DEBUG ]; } \ No newline at end of file diff --git a/src/LogLib/Classes/Console.php b/src/LogLib/Classes/Console.php index 0c2afb4..41f864a 100644 --- a/src/LogLib/Classes/Console.php +++ b/src/LogLib/Classes/Console.php @@ -4,11 +4,13 @@ namespace LogLib\Classes; + use Exception; use LogLib\Abstracts\ConsoleColors; use LogLib\Abstracts\LevelType; use LogLib\Log; use LogLib\Objects\Event; use LogLib\Objects\Options; + use RuntimeException; use Throwable; class Console @@ -20,30 +22,42 @@ /** - * @var float|int + * @var float|int|null */ private static $last_tick_time; /** - * @var int + * @var int|null */ private static $largest_tick_length; /** - * Formats the application color for the console + * Formats the application name with a color for the console * - * @param string $application - * @return string + * @param string $application The application name + * @return string The formatted application name + * @throws RuntimeException If unable to generate a random color for the application */ private static function formatAppColor(string $application): string { - if(!Log::getRuntimeOptions()->isDisplayAnsi()) + if(!Log::getRuntimeOptions()->displayAnsi()) + { return $application; + } if(!isset(self::$application_colors[$application])) { - $colors = ConsoleColors::BrightColors; - $color = $colors[array_rand($colors)]; + $colors = ConsoleColors::BRIGHT_COLORS; + + try + { + $color = $colors[random_int(0, count($colors) - 1)]; + } + catch (Exception $e) + { + throw new RuntimeException(sprintf('Unable to generate random color for application "%s"', $application), $e->getCode(), $e); + } + self::$application_colors[$application] = $color; } @@ -51,79 +65,72 @@ } /** - * Returns a color formatted string for the console + * Applies a specified color to the given text, using ANSI escape sequences. * - * @param string $text - * @param string $color - * @return string + * @param string $text The text to apply the color to. + * @param string $color The ANSI color code to apply to the text. + * @return string The text with the specified color applied. */ private static function color(string $text, string $color): string { - if(!Log::getRuntimeOptions()->isDisplayAnsi()) + if(!Log::getRuntimeOptions()->displayAnsi()) + { return $text; + } return "\033[" . $color . "m" . $text . "\033[0m"; } /** - * Colorizes a event string for the console + * Applies a specified color to the given text, based on the event level, using ANSI escape sequences. * - * @param Event $event - * @param string $text - * @return string + * @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. */ private static function colorize(Event $event, string $text): string { - if(!Log::getRuntimeOptions()->isDisplayAnsi()) - return Utilities::levelToString($text); - - $color = null; - switch($event->Level) + if(!Log::getRuntimeOptions()->displayAnsi()) { - case LevelType::Debug: - $color = ConsoleColors::LightPurple; - break; - case LevelType::Verbose: - $color = ConsoleColors::LightCyan; - break; - case LevelType::Info: - $color = ConsoleColors::White; - break; - case LevelType::Warning: - $color = ConsoleColors::Yellow; - break; - case LevelType::Fatal: - $color = ConsoleColors::Red; - break; - case LevelType::Error: - $color = ConsoleColors::LightRed; - break; + return Utilities::levelToString($text); } - if($color == null) + $color = match($event->getLevel()) + { + LevelType::DEBUG => ConsoleColors::LIGHT_PURPLE, + LevelType::VERBOSE => ConsoleColors::LIGHT_CYAN, + LevelType::INFO => ConsoleColors::WHITE, + LevelType::WARNING => ConsoleColors::YELLOW, + LevelType::FATAL => ConsoleColors::RED, + LevelType::ERROR => ConsoleColors::LIGHT_RED, + default => null, + }; + + if($color === null) + { return Utilities::levelToString($text); + } return self::color(Utilities::levelToString($text), $color); } /** - * Returns the current timestamp tick + * Retrieves the current timestamp as a formatted string. * - * @return string + * @return string The current timestamp. */ private static function getTimestamp(): string { $tick_time = (string)microtime(true); - if(strlen($tick_time) > self::$largest_tick_length) + if(!is_null(self::$largest_tick_length) && strlen($tick_time) > (int)self::$largest_tick_length) { self::$largest_tick_length = strlen($tick_time); } if(strlen($tick_time) < self::$largest_tick_length) { - /** @noinspection PhpRedundantOptionalArgumentInspection */ - $tick_time = str_pad($tick_time, (strlen($tick_time) + (self::$largest_tick_length - strlen($tick_time))), ' ', STR_PAD_RIGHT); + $tick_time = str_pad($tick_time, (strlen($tick_time) + (self::$largest_tick_length - strlen($tick_time)))); } $fmt_tick = $tick_time; @@ -133,11 +140,11 @@ if ($timeDiff > 1.0) { - $fmt_tick = \ncc\Utilities\Console::formatColor($tick_time, \ncc\Abstracts\ConsoleColors::LightRed); + $fmt_tick = self::color($tick_time, ConsoleColors::LIGHT_RED); } elseif ($timeDiff > 0.5) { - $fmt_tick = self::color($tick_time, ConsoleColors::Yellow); + $fmt_tick = self::color($tick_time, ConsoleColors::YELLOW); } } @@ -146,54 +153,58 @@ } /** - * Regular console output for the event object + * Outputs a log event to the console. * - * @param Options $options - * @param Event $event + * @param Options $options The options configuration object. + * @param Event $event The log event to output. * @return void */ public static function out(Options $options, Event $event): void { if(!Utilities::runningInCli()) - return; - - if(Validate::checkLevelType(LevelType::Verbose, Log::getRuntimeOptions()->getLogLevel())) { - $backtrace_output = Utilities::getTraceString($event, Log::getRuntimeOptions()->isDisplayAnsi()); + return; + } - print(sprintf( - "[%s] [%s] [%s] %s %s" . PHP_EOL, + if(Validate::checkLevelType(LevelType::VERBOSE, 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->Level), - $backtrace_output, $event->Message + self::colorize($event, $event->getLevel()), + $backtrace_output, $event->getMessage() )); - if($event->Exception !== null) - self::outException($event->Exception); + if($event->getException() !== null) + { + /** @noinspection NullPointerExceptionInspection */ + self::outException($event->getException()); + } return; } - print(sprintf( - "[%s] [%s] [%s] %s" . PHP_EOL, + print(sprintf("[%s] [%s] [%s] %s" . PHP_EOL, self::getTimestamp(), self::formatAppColor($options->getApplicationName()), - self::colorize($event, $event->Level), - $event->Message + self::colorize($event, $event->getLevel()), + $event->getMessage() )); } /** - * Prints out the exception details + * Prints information about the given exception, including the error message, error code, + * and stack trace. * - * @param Throwable $exception + * @param Throwable $exception The exception to print information about. * @return void */ private static function outException(Throwable $exception): void { - $trace_header = self::color($exception->getFile() . ':' . $exception->getLine(), ConsoleColors::Purple); - $trace_error = self::color('error: ', ConsoleColors::Red); + $trace_header = self::color($exception->getFile() . ':' . $exception->getLine(), ConsoleColors::PURPLE); + $trace_error = self::color('error: ', ConsoleColors::RED); print($trace_header . ' ' . $trace_error . $exception->getMessage() . PHP_EOL); print(sprintf('Error code: %s', $exception->getCode()) . PHP_EOL); @@ -204,13 +215,15 @@ print('Stack Trace:' . PHP_EOL); foreach($trace as $item) { - print( ' - ' . self::color($item['file'], ConsoleColors::Red) . ':' . $item['line'] . PHP_EOL); + print( ' - ' . self::color($item['file'], ConsoleColors::RED) . ':' . $item['line'] . PHP_EOL); } } if($exception->getPrevious() !== null) { 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 7e41eea..e861322 100644 --- a/src/LogLib/Classes/Utilities.php +++ b/src/LogLib/Classes/Utilities.php @@ -2,6 +2,7 @@ namespace LogLib\Classes; + use LogLib\Abstracts\CallType; use LogLib\Abstracts\LevelType; use LogLib\Objects\Backtrace; use LogLib\Objects\Event; @@ -11,23 +12,29 @@ class Utilities { /** - * Returns the current backtrace + * Returns a backtrace of the calling code. * - * @param bool $full - * @return array + * @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 { if(!function_exists('debug_backtrace')) + { return []; + } $backtrace = debug_backtrace(); $results = []; foreach($backtrace as $trace) { - if(isset($trace['class'] ) && str_contains($trace['class'], 'LogLib') && !$full) + if(!$full && isset($trace['class']) && str_contains($trace['class'], 'LogLib')) + { continue; + } $results[] = new Backtrace($trace); } @@ -36,34 +43,32 @@ } /** - * Returns the current level type as a string * - * @param int $level - * @return string */ public static function levelToString(int $level): string { return match ($level) { - LevelType::Debug => 'DBG', - LevelType::Verbose => 'VRB', - LevelType::Info => 'INF', - LevelType::Warning => 'WRN', - LevelType::Fatal => 'CRT', - LevelType::Error => 'ERR', + LevelType::DEBUG => 'DBG', + LevelType::VERBOSE => 'VRB', + LevelType::INFO => 'INF', + LevelType::WARNING => 'WRN', + LevelType::FATAL => 'CRT', + LevelType::ERROR => 'ERR', default => 'UNK', }; } /** - * A simple method to determine if the current environment is a CLI environment + * Determines whether the application is currently running in the command line interface (CLI) mode. * - * @return bool + * @return bool true if running in CLI mode, false otherwise. */ public static function runningInCli(): bool { if(function_exists('php_sapi_name')) { + /** @noinspection ConstantCanBeUsedInspection */ return strtolower(php_sapi_name()) === 'cli'; } @@ -76,68 +81,74 @@ } /** - * Attempts to determine the current log level from the command line arguments + * Returns the log level based on the configuration. * - * @return int + * @return int The log level. This value represents the severity or importance of the log messages. + * The returned value will be one of the constants defined in the LevelType class: + * - DEBUG (6) + * - VERBOSE (5) + * - INFO (4) + * - WARNING (3) + * - ERROR (2) + * - FATAL (1) + * - SILENT (0) + * If no log level is configured or the configured level is not recognized, the INFO level (4) will be returned by default. */ public static function getLogLevel(): int { $args = Parse::getArguments(); - $selected_level = ($args['log'] ?? $args['log-level'] ?? (getenv('LOG_LEVEL') ?: null) ?? null); - - if($selected_level === null) - return LevelType::Info; - - switch(strtolower($selected_level)) + switch(strtolower(($args['log'] ?? $args['log-level'] ?? (getenv('LOG_LEVEL') ?: null) ?? null))) { - case LevelType::Debug: + case LevelType::DEBUG: case 'debug': case '6': case 'dbg': - return LevelType::Debug; + return LevelType::DEBUG; - case LevelType::Verbose: + case LevelType::VERBOSE: case 'verbose': case '5': case 'vrb': - return LevelType::Verbose; + return LevelType::VERBOSE; default: - case LevelType::Info: + case LevelType::INFO: case 'info': case '4': case 'inf': - return LevelType::Info; + return LevelType::INFO; - case LevelType::Warning: + case LevelType::WARNING: case 'warning': case '3': case 'wrn': - return LevelType::Warning; + return LevelType::WARNING; - case LevelType::Error: + case LevelType::ERROR: case 'error': case '2': case 'err': - return LevelType::Error; + return LevelType::ERROR; - case LevelType::Fatal: + case LevelType::FATAL: case 'fatal': case '1': case 'crt': - return LevelType::Fatal; + return LevelType::FATAL; - case LevelType::Silent: + case LevelType::SILENT: case 'silent': case '0': case 'sil': - return LevelType::Silent; + return LevelType::SILENT; } } /** - * @return bool + * Checks if ANSI escape sequences should be displayed in the output. + * + * @return bool Returns true if ANSI escape sequences should be displayed, false otherwise. */ public static function getDisplayAnsi(): bool { @@ -145,51 +156,30 @@ $display_ansi = ($args['display-ansi'] ?? $args['ansi'] ?? null); if($display_ansi === null) + { return true; + } // Strict boolean response return strtolower($display_ansi) === 'true' || $display_ansi === '1'; } /** - * Returns the current active log file name, the current value can - * change depending on the date/time, if it has changed; close the - * old file and open a new one. + * Returns a string representation of the backtrace for the given event. * - * @return string - */ - public static function getLogFilename(): string - { - return date('Y-m-d') . '.log'; - } - - /** - * Returns a random string of characters - * - * @param int $length - * @return string - */ - public static function randomString(int $length = 32): string - { - $characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; - $charactersLength = strlen($characters); - $randomString = ''; - for ($i = 0; $i < $length; $i++) - { - $randomString .= $characters[rand(0, $charactersLength - 1)]; - } - return $randomString; - } - - /** - * @param Event $event - * @param bool $ansi - * @return string|null + * @param Event $event The event object for which to generate the backtrace string. + * @param bool $ansi Determines whether the output should include ANSI escape codes for colored output. Default is false. + * @return string|null A string representation of the backtrace for the event, or null if the event has no backtrace. + * The output format is: ClassName::methodName() or functionName() depending on the type of call. + * If $ansi is true, the output will be colored using ANSI escape codes. + * If the event has no backtrace, the constant CallType::LAMBDA_CALL will be returned. */ public static function getTraceString(Event $event, bool $ansi=false): ?string { - if($event->getBacktrace() == null) - return 'λ'; + if($event->getBacktrace() === null) + { + return CallType::LAMBDA_CALL; + } $backtrace = $event->getBacktrace()[0]; $function = $backtrace->getFunction(); @@ -201,18 +191,22 @@ $class = "\033[1;37m$class\033[0m"; } - if($class == null) - return "{$function}()"; + if($class === null) + { + return $function . CallType::FUNCTION_CALL; + } - $type = ($backtrace->getType() == '->' ? '->' : '::'); - return "{$class}{$type}{$function}()"; + $type = ($backtrace->getType() === CallType::METHOD_CALL ? CallType::METHOD_CALL : CallType::STATIC_CALL); + return "{$class}{$type}{$function}" . CallType::FUNCTION_CALL; } /** - * Returns an array representation of a throwable exception + * Converts an exception object to an array representation. * - * @param Throwable $e - * @return array + * @param Throwable $e The exception object to convert. + * @return array An array containing the details of the exception. + * The array includes the exception message, code, file, line, and a formatted trace. + * The trace is formatted as a string containing the file, line, class, type, and function for each call in the traceback. */ public static function exceptionToArray(Throwable $e): array { diff --git a/src/LogLib/Classes/Validate.php b/src/LogLib/Classes/Validate.php index 9e1c134..07f2490 100644 --- a/src/LogLib/Classes/Validate.php +++ b/src/LogLib/Classes/Validate.php @@ -7,102 +7,94 @@ class Validate { /** - * Validates that the level is valid + * Checks if the given level is a valid level type. * - * @param string $level - * @return bool + * @param string $level The level to check. + * @return bool Returns true if the level is valid */ public static function LevelType(string $level): bool { - return in_array($level, LevelType::All); + return in_array($level, LevelType::ALL); } /** - * Checks if the input level matches the current level + * Checks if the given input level is valid for the current level. * - * @param string $input - * @param string $current_level - * @return bool + * @param string $input The input level to check. + * @param string $current_level The current level to compare against. + * @return bool Returns true if the input level is valid for the current level, false otherwise. */ public static function checkLevelType(string $input, string $current_level): bool { - if($input == null) - return false; - if($current_level == null) - return false; - $input = strtolower($input); - if(!Validate::LevelType($input)) + if(!self::LevelType($input)) + { return false; + } $current_level = strtolower($current_level); - if(!Validate::LevelType($current_level)) + if(!self::LevelType($current_level)) + { return false; + } switch($current_level) { - case LevelType::Debug: + case LevelType::DEBUG: $levels = [ - LevelType::Debug, - LevelType::Verbose, - LevelType::Info, - LevelType::Warning, - LevelType::Fatal, - LevelType::Error + LevelType::DEBUG, + LevelType::VERBOSE, + LevelType::INFO, + LevelType::WARNING, + LevelType::FATAL, + LevelType::ERROR ]; - if(in_array($input, $levels)) - return true; - return false; - case LevelType::Verbose: + return in_array($input, $levels, true); + + case LevelType::VERBOSE: $levels = [ - LevelType::Verbose, - LevelType::Info, - LevelType::Warning, - LevelType::Fatal, - LevelType::Error + LevelType::VERBOSE, + LevelType::INFO, + LevelType::WARNING, + LevelType::FATAL, + LevelType::ERROR ]; - if(in_array($input, $levels)) - return true; - return false; - case LevelType::Info: + return in_array($input, $levels, true); + + case LevelType::INFO: $levels = [ - LevelType::Info, - LevelType::Warning, - LevelType::Fatal, - LevelType::Error + LevelType::INFO, + LevelType::WARNING, + LevelType::FATAL, + LevelType::ERROR ]; - if(in_array($input, $levels)) - return true; - return false; - case LevelType::Warning: + return in_array($input, $levels, true); + + case LevelType::WARNING: $levels = [ - LevelType::Warning, - LevelType::Fatal, - LevelType::Error + LevelType::WARNING, + LevelType::FATAL, + LevelType::ERROR ]; - if(in_array($input, $levels)) - return true; - return false; - case LevelType::Error: + return in_array($input, $levels, true); + + case LevelType::ERROR: $levels = [ - LevelType::Fatal, - LevelType::Error + LevelType::FATAL, + LevelType::ERROR ]; - if(in_array($input, $levels)) - return true; - return false; - case LevelType::Fatal: - if($input == LevelType::Fatal) - return true; - return false; + return in_array($input, $levels, true); + + case LevelType::FATAL: + return $input === LevelType::FATAL; default: - case LevelType::Silent: + case LevelType::SILENT: return false; } } diff --git a/src/LogLib/Exceptions/ConfigurationException.php b/src/LogLib/Exceptions/ConfigurationException.php deleted file mode 100644 index 7a829fc..0000000 --- a/src/LogLib/Exceptions/ConfigurationException.php +++ /dev/null @@ -1,21 +0,0 @@ -message = $message; - $this->code = $code; - } - } \ No newline at end of file diff --git a/src/LogLib/Log.php b/src/LogLib/Log.php index 0da1569..f54e4f8 100644 --- a/src/LogLib/Log.php +++ b/src/LogLib/Log.php @@ -17,14 +17,14 @@ class Log { /** - * @var Options[] + * @var Options[]|null */ - private static $Applications; + private static $applications; /** - * @var RuntimeOptions + * @var RuntimeOptions|null */ - private static $RuntimeOptions; + private static $runtime_options; /** * Registers a new application logger @@ -35,9 +35,16 @@ public static function register(Options $options): bool { if(self::isRegistered($options->getApplicationName())) + { return false; + } - self::$Applications[$options->getApplicationName()] = $options; + if(self::$applications === null) + { + self::$applications = []; + } + + self::$applications[$options->getApplicationName()] = $options; return true; } @@ -49,8 +56,15 @@ */ public static function unregister(string $application): void { - if(isset(self::$Applications[$application])) - unset(self::$Applications[$application]); + if(self::$applications === null) + { + return; + } + + if(isset(self::$applications[$application])) + { + unset(self::$applications[$application]); + } } /** @@ -61,7 +75,7 @@ */ private static function isRegistered(string $application): bool { - return isset(self::$Applications[$application]); + return isset(self::$applications[$application]); } /** @@ -71,9 +85,11 @@ public static function getApplication(string $application): Options { if(!self::isRegistered($application)) + { throw new InvalidArgumentException("The application '$application' is not registered"); + } - return self::$Applications[$application]; + return self::$applications[$application]; } /** @@ -87,38 +103,49 @@ self::register(new Options($application_name)); } - return self::$Applications[$application_name]; + return self::$applications[$application_name]; } /** + * 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 of the event - * @param string|null $message The message of the event + * @param string $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, string $level=LevelType::INFO, ?string $message=null, ?Throwable $throwable=null): void { $application = self::getOptions($application_name); - if(!Validate::checkLevelType($level, self::getRuntimeOptions()->getLogLevel())) + if(!Validate::levelType($level)) + { + throw new InvalidArgumentException(sprintf('Invalid level type: %s', $level)); + } + + if(!Validate::checkLevelType($level, self::getRuntimeOptions()->getLoglevel())) + { return; + } - if($message == null) + if($message === null) + { throw new InvalidArgumentException('Message cannot be null'); - if($level == null || !Validate::levelType($level)) - throw new InvalidArgumentException('Invalid logging level'); + } - $event = new Event(); - $event->Level = $level; - $event->Message = $message; - $event->Exception = $throwable; + $event = new Event($message, $level, $throwable); - if($event->getBacktrace() == null) + if($event->getBacktrace() === null) + { $event->setBacktrace(Utilities::getBacktrace()); + } if(self::getRuntimeOptions()->isConsoleOutput()) + { Console::out($application, $event); + } } /** @@ -128,7 +155,7 @@ */ public static function info(string $application_name, string $message): void { - self::log($application_name, LevelType::Info, $message); + self::log($application_name, LevelType::INFO, $message); } /** @@ -138,7 +165,7 @@ */ public static function verbose(string $application_name, string $message): void { - self::log($application_name, LevelType::Verbose, $message); + self::log($application_name, LevelType::VERBOSE, $message); } /** @@ -148,56 +175,62 @@ */ public static function debug(string $application_name, string $message): void { - self::log($application_name, LevelType::Debug, $message); + self::log($application_name, LevelType::DEBUG, $message); } /** - * @param string $application_name The name of the application - * @param string $message The message of the event - * @param Throwable|null $throwable The exception that was thrown, if any + * Logs a warning message. + * + * @param string $application_name The name of the application. + * @param string $message The warning message to log. + * @param Throwable|null $throwable (Optional) The throwable object associated with the warning. * @return void */ public static function warning(string $application_name, string $message, ?Throwable $throwable=null): void { - self::log($application_name, LevelType::Warning, $message, $throwable); + self::log($application_name, LevelType::WARNING, $message, $throwable); } /** - * @param string $application_name The name of the application - * @param string $message The message of the event - * @param Throwable|null $throwable The exception that was thrown, if any + * Logs an error message. + * + * @param string $application_name The name of the application. + * @param string $message The error message. + * @param Throwable|null $throwable The optional throwable object associated with the error. * @return void - */ + **/ public static function error(string $application_name, string $message, ?Throwable $throwable=null): void { - self::log($application_name, LevelType::Error, $message, $throwable); + self::log($application_name, LevelType::ERROR, $message, $throwable); } /** - * @param string $application_name The name of the application - * @param string $message The message of the event - * @param Throwable|null $throwable The exception that was thrown, if any + * Logs a fatal message. + * + * @param string $application_name The name of the application. + * @param string $message The fatal message to log. + * @param Throwable|null $throwable (Optional) The throwable object associated with the fatal message. * @return void */ public static function fatal(string $application_name, string $message, ?Throwable $throwable=null): void { - self::log($application_name, LevelType::Fatal, $message, $throwable); + self::log($application_name, LevelType::FATAL, $message, $throwable); } /** - * Registers LogLib as a exception handler + * Registers an exception handler that logs any uncaught exceptions as errors. * * @return void */ public static function registerExceptionHandler(): void { - set_exception_handler(function(Throwable $throwable) { + set_exception_handler(static function(Throwable $throwable) { self::error('Runtime', $throwable->getMessage(), $throwable); }); } /** - * Unregisters all applications + * Unregisters the currently registered exception handler. * * @return void */ @@ -207,15 +240,18 @@ } /** - * @return RuntimeOptions + * Gets the runtime options. + * + * @return RuntimeOptions The runtime options. */ public static function getRuntimeOptions(): RuntimeOptions { - if(self::$RuntimeOptions == null) + if(self::$runtime_options === null) { - self::$RuntimeOptions = new RuntimeOptions(); + self::$runtime_options = new RuntimeOptions(); } - return self::$RuntimeOptions; + + return self::$runtime_options; } } \ No newline at end of file diff --git a/src/LogLib/Objects/Backtrace.php b/src/LogLib/Objects/Backtrace.php index bc9f38b..cf03a73 100644 --- a/src/LogLib/Objects/Backtrace.php +++ b/src/LogLib/Objects/Backtrace.php @@ -7,56 +7,35 @@ class Backtrace { /** - * The function name of the backtrace - * * @var string|null - * @property_name function */ - private $Function; + private $function; /** - * The line number of the backtrace - * * @var int|null - * @property_name line */ - private $Line; + private $line; /** - * The file name of the backtrace - * * @var string|null - * @property_name file */ - private $File; + private $file; /** - * The class name, if any, of the backtrace - * * @var string|null - * @property_name class */ - private $Class; + private $class; /** - * The current call type. If a method call, "->" is returned. - * If a static method call, "::" is returned. If a function call, - * nothing is returned. - * * @see CallType * @var string|null - * @property_name type */ - private $Type; + private $type; /** - * If inside a function, this lists the functions arguments. If inside - * an included file, this lists the included file name(s). - * * @var array|null - * @property_name args */ - private $Args; + private $args; /** * Public Constructor @@ -66,109 +45,135 @@ public function __construct(?array $backtrace=null) { if($backtrace === null) + { return; + } - $this->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; + $this->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; + return $this->function; } /** - * @param string|null $Function + * Sets the function name of the backtrace + * + * @param string|null $function */ - public function setFunction(?string $Function): void + public function setFunction(?string $function): void { - $this->Function = $Function; + $this->function = $function; } /** + * Optional. Returns the line number of the backtrace + * * @return int|null */ public function getLine(): ?int { - return $this->Line; + return $this->line; } /** - * @param int|null $Line + * Sets the line number of the backtrace + * + * @param int|null $line */ - public function setLine(?int $Line): void + public function setLine(?int $line): void { - $this->Line = $Line; + $this->line = $line; } /** + * Optional. Returns the file name of the backtrace + * * @return string|null */ public function getFile(): ?string { - return $this->File; + return $this->file; } /** - * @param string|null $File + * Sets the file name of the backtrace + * + * @param string|null $file */ - public function setFile(?string $File): void + public function setFile(?string $file): void { - $this->File = $File; + $this->file = $file; } /** + * Optional. Returns the class name, if any, of the backtrace + * * @return string|null */ public function getClass(): ?string { - return $this->Class; + return $this->class; } /** - * @param string|null $Class + * Sets the class name, if any, of the backtrace + * + * @param string|null $class */ - public function setClass(?string $Class): void + public function setClass(?string $class): void { - $this->Class = $Class; + $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; + return $this->type; } /** - * @param string|null $Type + * Sets the current call type. If a method call, "->" is returned. + * + * @param string|null $type */ - public function setType(?string $Type): void + public function setType(?string $type): void { - $this->Type = $Type; + $this->type = $type; } /** + * Optional. Return the functions arguments or included file name(s) + * * @return array|null */ public function getArgs(): ?array { - return $this->Args; + return $this->args; } /** - * @param array|null $Args + * Sets the function arguments or included file name(s) + * + * @param array|null $args */ - public function setArgs(?array $Args): void + public function setArgs(?array $args): void { - $this->Args = $Args; + $this->args = $args; } } \ No newline at end of file diff --git a/src/LogLib/Objects/Event.php b/src/LogLib/Objects/Event.php index 12530e6..5ca960b 100644 --- a/src/LogLib/Objects/Event.php +++ b/src/LogLib/Objects/Event.php @@ -7,37 +7,76 @@ use LogLib\Abstracts\LevelType; use LogLib\Classes\Utilities; use Throwable; + class Event { /** - * The level of the event - * * @see LevelType * @var string - * @property_name level */ - public $Level; + private $level; /** - * An array of backtraces, if any, that were created when the event was created - * * @var Backtrace[]|null */ - private $Backtrace; + private $backtrace; /** - * The exception that was thrown, if any - * * @var Throwable|null */ - public $Exception; + private $exception; /** - * The message of the event - * * @var string */ - public $Message; + private $message; + + /** + * Event constructor. + * + * @param string $message + * @param int $level + * @param Throwable|null $exception + * @param array|null $backtrace + */ + public function __construct(string $message, int $level, ?Throwable $exception=null, ?array $backtrace=null) + { + $this->message = $message; + $this->level = $level; + $this->exception = $exception; + $this->backtrace = $backtrace; + } + + /** + * Returns the level of the event + * + * @see LevelType + * @return int + */ + public function getLevel(): int + { + return $this->level; + } + + /** + * Returns the message of the event + * + * @return string + */ + public function getMessage(): string + { + return $this->message; + } + + /** + * Optional. Returns the exception to the event + * + * @return Throwable|null + */ + public function getException(): ?Throwable + { + return $this->exception; + } /** * Sets an exception to the event @@ -47,23 +86,27 @@ */ public function setException(Throwable $e): void { - $this->Exception = Utilities::exceptionToArray($e); + $this->exception = Utilities::exceptionToArray($e); } /** + * Returns the backtrace of the event + * * @return array|null */ public function getBacktrace(): ?array { - return $this->Backtrace; + return $this->backtrace; } /** - * @param array|null $Backtrace + * Sets the backtrace of the event + * + * @param array|null $backtrace */ - public function setBacktrace(?array $Backtrace): void + public function setBacktrace(?array $backtrace): void { - $this->Backtrace = $Backtrace; + $this->backtrace = $backtrace; } } \ No newline at end of file diff --git a/src/LogLib/Objects/Options.php b/src/LogLib/Objects/Options.php index 3e20eae..7774c29 100644 --- a/src/LogLib/Objects/Options.php +++ b/src/LogLib/Objects/Options.php @@ -8,19 +8,16 @@ class Options { /** - * The name of the application - * * @var string - * @property_name application_name */ - private $ApplicationName; + private $application_name; /** * Options constructor. */ public function __construct(string $application_name) { - $this->ApplicationName = $application_name; + $this->application_name = $application_name; } /** @@ -30,7 +27,7 @@ */ public function getApplicationName(): string { - return $this->ApplicationName; + return $this->application_name; } } \ No newline at end of file diff --git a/src/LogLib/Objects/RuntimeOptions.php b/src/LogLib/Objects/RuntimeOptions.php index 7f6fe4a..c1051b8 100644 --- a/src/LogLib/Objects/RuntimeOptions.php +++ b/src/LogLib/Objects/RuntimeOptions.php @@ -4,7 +4,6 @@ namespace LogLib\Objects; - use InvalidArgumentException; use LogLib\Abstracts\LevelType; use LogLib\Classes\Utilities; @@ -16,7 +15,7 @@ * @var bool * @property_name console_output */ - private $ConsoleOutput; + private $console_output; /** * Indicates if ANSI colors should be used in the console output @@ -24,7 +23,7 @@ * @var bool * @property_name display_ansi */ - private $DisplayAnsi; + private $display_ansi; /** * Indicates if LogLib should handle uncaught exceptions @@ -32,7 +31,7 @@ * @var bool * @property_name handle_exceptions */ - private $HandleExceptions; + private $handle_exceptions; /** * The current log level @@ -40,17 +39,17 @@ * @var int * @see LevelType */ - private $LogLevel; + private $log_level; /** * Public Constructor */ public function __construct() { - $this->ConsoleOutput = Utilities::runningInCli(); - $this->DisplayAnsi = Utilities::getDisplayAnsi(); - $this->HandleExceptions = true; - $this->LogLevel = Utilities::getLogLevel(); + $this->console_output = Utilities::runningInCli(); + $this->display_ansi = Utilities::getDisplayAnsi(); + $this->log_level = Utilities::getLogLevel(); + $this->handle_exceptions = true; } /** @@ -58,62 +57,62 @@ */ public function isConsoleOutput(): bool { - return $this->ConsoleOutput; + return $this->console_output; } /** - * @param bool $ConsoleOutput + * @param bool $console_output */ - public function setConsoleOutput(bool $ConsoleOutput): void + public function setConsoleOutput(bool $console_output): void { - $this->ConsoleOutput = $ConsoleOutput; + $this->console_output = $console_output; } /** * @return bool */ - public function isDisplayAnsi(): bool + public function displayAnsi(): bool { - return $this->DisplayAnsi; + return $this->display_ansi; } /** - * @param bool $DisplayAnsi + * @param bool $display_ansi */ - public function setDisplayAnsi(bool $DisplayAnsi): void + public function setDisplayAnsi(bool $display_ansi): void { - $this->DisplayAnsi = $DisplayAnsi; + $this->display_ansi = $display_ansi; } /** * @return bool */ - public function isHandleExceptions(): bool + public function handleExceptions(): bool { - return $this->HandleExceptions; + return $this->handle_exceptions; } /** - * @param bool $HandleExceptions + * @param bool $handle_exceptions */ - public function setHandleExceptions(bool $HandleExceptions): void + public function setHandleExceptions(bool $handle_exceptions): void { - $this->HandleExceptions = $HandleExceptions; + $this->handle_exceptions = $handle_exceptions; } /** * @return int */ - public function getLogLevel(): int + public function getLoglevel(): int { - return $this->LogLevel; + return $this->log_level; } /** - * @param int $LogLevel + * @param int $log_level */ - public function setLogLevel(int $LogLevel): void + public function setLoglevel(int $log_level): void { - $this->LogLevel = $LogLevel; + $this->log_level = $log_level; } } \ No newline at end of file