Refactor logging methods and utility functions

This commit is contained in:
netkas 2024-10-28 15:29:57 -04:00
parent dec96d85e1
commit 81ee234540
2 changed files with 143 additions and 85 deletions

View file

@ -80,11 +80,9 @@
* - SILENT (0) * - SILENT (0)
* If no log level is configured or the configured level is not recognized, the INFO level (4) will be returned by default. * 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(): LogLevel private static function parseLogLevel(string $logLevel): LogLevel
{ {
$args = Parse::getArguments(); switch(strtolower($logLevel))
switch(strtolower(($args['log'] ?? $args['log-level'] ?? (getenv('LOG_LEVEL') ?: 'info') ?? 'info')))
{ {
case LogLevel::DEBUG: case LogLevel::DEBUG:
case 'debug': case 'debug':
@ -154,13 +152,12 @@
* Returns a string representation of the backtrace for the given event. * Returns a string representation of the backtrace for the given event.
* *
* @param Event $event The event object for which to generate the backtrace string. * @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. * @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. * 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 $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. * If the event has no backtrace, the constant CallType::LAMBDA_CALL will be returned.
*/ */
public static function getTraceString(Event $event, bool $ansi=false): ?string public static function getTraceString(Event $event): ?string
{ {
if($event->getBacktrace() === null || count($event->getBacktrace()) === 0) if($event->getBacktrace() === null || count($event->getBacktrace()) === 0)
{ {
@ -174,7 +171,7 @@
{ {
if(isset($backtrace['file'])) if(isset($backtrace['file']))
{ {
return ($ansi ? "\033[1;37m" : '') . basename($backtrace['file']) . ($ansi ? "\033[0m" : ''); return "\033[1;37m" . basename($backtrace['file']) . "\033[0m";
} }
return basename($backtrace['file']); return basename($backtrace['file']);
@ -184,7 +181,7 @@
{ {
if(isset($backtrace['file'])) if(isset($backtrace['file']))
{ {
return ($ansi ? "\033[1;37m" : '') . basename($backtrace['file']) . ($ansi ? "\033[0m" : '') . CallType::STATIC_CALL->value . CallType::LAMBDA_CALL->value; return "\033[1;37m" . basename($backtrace['file']) . "\033[0m" . CallType::STATIC_CALL->value . CallType::LAMBDA_CALL->value;
} }
return basename($backtrace['file']) . CallType::STATIC_CALL->value . CallType::LAMBDA_CALL->value; return basename($backtrace['file']) . CallType::STATIC_CALL->value . CallType::LAMBDA_CALL->value;
@ -194,14 +191,12 @@
{ {
if(isset($backtrace['file'])) if(isset($backtrace['file']))
{ {
return ($ansi ? "\033[1;37m" : '') . basename($backtrace['file']) . ($ansi ? "\033[0m" : '') . CallType::STATIC_CALL->value . CallType::EVAL_CALL->value; return "\033[1;37m" . basename($backtrace['file']) . "\033[0m" . CallType::STATIC_CALL->value . CallType::EVAL_CALL->value;
} }
return basename($backtrace['file']) . CallType::STATIC_CALL->value . CallType::EVAL_CALL->value; return basename($backtrace['file']) . CallType::STATIC_CALL->value . CallType::EVAL_CALL->value;
} }
if($ansi)
{
$function = sprintf("\033[1;37m%s\033[0m", $backtrace['function']); $function = sprintf("\033[1;37m%s\033[0m", $backtrace['function']);
$class = null; $class = null;
@ -209,12 +204,6 @@
{ {
$class = sprintf("\033[1;37m%s\033[0m", $backtrace['class']); $class = sprintf("\033[1;37m%s\033[0m", $backtrace['class']);
} }
}
else
{
$function = $backtrace['function'];
$class = $backtrace['class'] ?? null;
}
if($class === null) if($class === null)
{ {
@ -253,4 +242,94 @@
]; ];
} }
public static function getLogDirectory(): string
{
$args = Parse::getArguments();
$log_directory = ($args['log-directory'] ?? getenv('LOG_DIRECTORY') ?? null);
if($log_directory === null)
{
return sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'logs';
}
return $log_directory;
}
public static function getConsoleLoggingEnabled(): bool
{
if(isset(Parse::getArguments()['log-level']))
{
return true;
}
if(self::runningInCli())
{
return true;
}
if(getenv('CLI_LOGGING') === 'true' || getenv('CLI_LOGGING') === '1')
{
return true;
}
return false;
}
public static function getConsoleLoggingLevel(): LogLevel
{
return self::parseLogLevel(($args['log'] ?? $args['log-level'] ?? (getenv('LOG_LEVEL') ?: 'info') ?? 'info'));
}
public static function getFileLoggingEnabled(): bool
{
if(isset(Parse::getArguments()['log-directory']))
{
return true;
}
if(getenv('LOG_DIRECTORY') !== null)
{
return true;
}
if(!is_writable(self::getLogDirectory()))
{
return false;
}
return false;
}
public static function getFileLoggingLevel(): LogLevel
{
if(getenv('FILE_LOG_LEVEL') !== null || isset(Parse::getArguments()['file-log-level']))
{
return self::parseLogLevel(getenv('FILE_LOG_LEVEL'));
}
return LogLevel::WARNING;
}
public static function getFileLoggingDirectory(): string
{
$args = Parse::getArguments();
$log_directory = ($args['log-directory'] ?? getenv('LOG_DIRECTORY') ?? null);
if($log_directory === null)
{
return sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'logs';
}
return $log_directory;
}
public static function sanitizeFileName(string $name): string
{
// Replace spaces with hyphens
$name = str_replace(' ', '-', $name);
// Remove illegal characters and replace escapable characters with underscores
return preg_replace('/[\/:*?"<>|.]/', '_', $name);
}
} }

View file

@ -5,36 +5,29 @@
namespace LogLib; namespace LogLib;
use InvalidArgumentException; use InvalidArgumentException;
use LogLib\Classes\Console;
use LogLib\Classes\Utilities; use LogLib\Classes\Utilities;
use LogLib\Classes\Validate;
use LogLib\Enums\LogLevel; use LogLib\Enums\LogLevel;
use LogLib\Exceptions\LoggingException;
use LogLib\Objects\Application;
use LogLib\Objects\Event; use LogLib\Objects\Event;
use LogLib\Objects\Options;
use LogLib\Objects\RuntimeOptions;
use Throwable; use Throwable;
class Log class Log
{ {
/** /**
* @var Options[]|null * @var Application[]|null
*/ */
private static $applications; private static $applications;
/**
* @var RuntimeOptions|null
*/
private static $runtime_options;
/** /**
* Registers a new application logger * Registers a new application logger
* *
* @param Options $options The options for the application * @param Application $application The options for the application
* @return bool * @return bool
*/ */
public static function register(Options $options): bool public static function register(Application $application): bool
{ {
if(self::isRegistered($options->getApplicationName())) if(self::isRegistered($application->getApplicationName()))
{ {
return false; return false;
} }
@ -44,7 +37,7 @@
self::$applications = []; self::$applications = [];
} }
self::$applications[$options->getApplicationName()] = $options; self::$applications[$application->getApplicationName()] = $application;
return true; return true;
} }
@ -79,33 +72,27 @@
} }
/** /**
* @param string $application * Retrieves the application options. If the application is not registered, it optionally creates and registers a new one.
* @return Options *
* @param string $application The name of the application.
* @param bool $create (Optional) Whether to create the application if it is not registered. Default is true.
* @return Application The options for the specified application.
*/ */
public static function getApplication(string $application): Options public static function getApplication(string $application, bool $create=true): Application
{ {
if(!self::isRegistered($application)) if(!self::isRegistered($application))
{
if(!$create)
{ {
throw new InvalidArgumentException("The application '$application' is not registered"); throw new InvalidArgumentException("The application '$application' is not registered");
} }
self::register(new Application($application));
}
return self::$applications[$application]; return self::$applications[$application];
} }
/**
* @param string $application_name The name of the application
* @return Options The options for the application
*/
public static function getOptions(string $application_name): Options
{
if(!self::isRegistered($application_name))
{
self::register(new Options($application_name));
}
return self::$applications[$application_name];
}
/** /**
* Logs a message with a specified application name, level, optional message, and optional throwable. * Logs a message with a specified application name, level, optional message, and optional throwable.
* *
@ -114,22 +101,11 @@
* @param string|null $message The message of the log event * @param string|null $message The message of the log event
* @param Throwable|null $throwable The exception that was thrown, if any * @param Throwable|null $throwable The exception that was thrown, if any
* @return void * @return void
* @throws LoggingException
*/ */
private static function log(?string $application_name, LogLevel $level=LogLevel::INFO, ?string $message=null, ?Throwable $throwable=null): void private static function log(?string $application_name, LogLevel $level=LogLevel::INFO, ?string $message=null, ?Throwable $throwable=null): void
{ {
if($application_name === null) $application = self::getApplication($application_name);
{
$options = self::getRuntimeOptions();
}
else
{
$options = self::getOptions($application_name);
}
if(!Validate::checkLevelType($level, $options->getLoglevel()))
{
return;
}
if($message === null) if($message === null)
{ {
@ -143,9 +119,14 @@
$event->setBacktrace(Utilities::getBacktrace()); $event->setBacktrace(Utilities::getBacktrace());
} }
if($options->isConsoleOutput()) if($application->isConsoleLoggingEnabled())
{ {
Console::out($options, $event); $application->getConsoleLoggingHandler()::handle($application, $event);
}
if($application->isFileLoggingEnabled())
{
$application->getFileLoggingHandler()::handle($application, $event);
} }
} }
@ -153,6 +134,7 @@
* @param string $application_name The name of the application * @param string $application_name The name of the application
* @param string $message The message of the event * @param string $message The message of the event
* @return void * @return void
* @throws LoggingException
*/ */
public static function info(string $application_name, string $message): void public static function info(string $application_name, string $message): void
{ {
@ -163,6 +145,7 @@
* @param string $application_name The name of the application * @param string $application_name The name of the application
* @param string $message The message of the event * @param string $message The message of the event
* @return void * @return void
* @throws LoggingException
*/ */
public static function verbose(string $application_name, string $message): void public static function verbose(string $application_name, string $message): void
{ {
@ -173,6 +156,7 @@
* @param string $application_name The name of the application * @param string $application_name The name of the application
* @param string $message The message of the event * @param string $message The message of the event
* @return void * @return void
* @throws LoggingException
*/ */
public static function debug(string $application_name, string $message): void public static function debug(string $application_name, string $message): void
{ {
@ -186,6 +170,7 @@
* @param string $message The warning message to log. * @param string $message The warning message to log.
* @param Throwable|null $throwable (Optional) The throwable object associated with the warning. * @param Throwable|null $throwable (Optional) The throwable object associated with the warning.
* @return void * @return void
* @throws LoggingException
*/ */
public static function warning(string $application_name, string $message, ?Throwable $throwable=null): void public static function warning(string $application_name, string $message, ?Throwable $throwable=null): void
{ {
@ -199,7 +184,8 @@
* @param string $message The error message. * @param string $message The error message.
* @param Throwable|null $throwable The optional throwable object associated with the error. * @param Throwable|null $throwable The optional throwable object associated with the error.
* @return void * @return void
**/ * @throws LoggingException
*/
public static function error(string $application_name, string $message, ?Throwable $throwable=null): void public static function error(string $application_name, string $message, ?Throwable $throwable=null): void
{ {
self::log($application_name, LogLevel::ERROR, $message, $throwable); self::log($application_name, LogLevel::ERROR, $message, $throwable);
@ -212,6 +198,7 @@
* @param string $message The fatal message to log. * @param string $message The fatal message to log.
* @param Throwable|null $throwable (Optional) The throwable object associated with the fatal message. * @param Throwable|null $throwable (Optional) The throwable object associated with the fatal message.
* @return void * @return void
* @throws LoggingException
*/ */
public static function fatal(string $application_name, string $message, ?Throwable $throwable=null): void public static function fatal(string $application_name, string $message, ?Throwable $throwable=null): void
{ {
@ -226,8 +213,15 @@
public static function registerExceptionHandler(): void public static function registerExceptionHandler(): void
{ {
set_exception_handler(static function(Throwable $throwable) set_exception_handler(static function(Throwable $throwable)
{
try
{ {
self::error('Runtime', $throwable->getMessage(), $throwable); self::error('Runtime', $throwable->getMessage(), $throwable);
}
catch(LoggingException)
{
return;
}
}); });
} }
@ -241,19 +235,4 @@
set_exception_handler(null); set_exception_handler(null);
} }
/**
* Gets the runtime options.
*
* @return RuntimeOptions The runtime options.
*/
public static function getRuntimeOptions(): RuntimeOptions
{
if(self::$runtime_options === null)
{
self::$runtime_options = new RuntimeOptions();
}
return self::$runtime_options;
}
} }