Add console logging handler
This commit is contained in:
parent
e5b0bb6012
commit
f3d0412525
1 changed files with 225 additions and 0 deletions
225
src/LogLib/Handlers/ConsoleLogging.php
Normal file
225
src/LogLib/Handlers/ConsoleLogging.php
Normal file
|
@ -0,0 +1,225 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Handlers;
|
||||
|
||||
use Exception;
|
||||
use LogLib\Classes\Utilities;
|
||||
use LogLib\Classes\Validate;
|
||||
use LogLib\Enums\ConsoleColors;
|
||||
use LogLib\Enums\LogHandlerType;
|
||||
use LogLib\Enums\LogLevel;
|
||||
use LogLib\Exceptions\LoggingException;
|
||||
use LogLib\Interfaces\LogHandlerInterface;
|
||||
use LogLib\Objects\Application;
|
||||
use LogLib\Objects\Event;
|
||||
use Throwable;
|
||||
|
||||
class ConsoleLogging implements LogHandlerInterface
|
||||
{
|
||||
private static array $application_colors = [];
|
||||
private static float|int|null $last_tick_time;
|
||||
private static ?int $largest_tick_length;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function handle(Application $application, Event $event): void
|
||||
{
|
||||
// Check if the event level is enabled for console logging
|
||||
if(!Validate::checkLevelType($event->getLevel(), $application->getConsoleLoggingLevel()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(Validate::checkLevelType(LogLevel::DEBUG, $application->getConsoleLoggingLevel()))
|
||||
{
|
||||
$backtrace_output = Utilities::getTraceString($event);
|
||||
|
||||
print(sprintf("[%s] [%s] [%s] %s %s" . PHP_EOL,
|
||||
self::getTimestamp(), self::formatAppColor($application->getApplicationName()), self::colorize($event),
|
||||
$backtrace_output, $event->getMessage()
|
||||
));
|
||||
|
||||
if($event->getException() !== null)
|
||||
{
|
||||
self::outException($event->getException());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(Validate::checkLevelType(LogLevel::VERBOSE, $application->getConsoleLoggingLevel()))
|
||||
{
|
||||
$backtrace_output = Utilities::getTraceString($event);
|
||||
|
||||
print(sprintf("[%s] [%s] %s %s" . PHP_EOL,
|
||||
self::formatAppColor($application->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($application->getApplicationName()),
|
||||
self::colorize($event),
|
||||
$event->getMessage()
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function getType(): LogHandlerType
|
||||
{
|
||||
return LogHandlerType::CONSOLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the application name with a color for the console
|
||||
*
|
||||
* @param string $application_name The application name
|
||||
* @return string The formatted application name
|
||||
* @throws LoggingException If unable to generate a random color for the application
|
||||
*/
|
||||
private static function formatAppColor(string $application_name): string
|
||||
{
|
||||
if(!isset(self::$application_colors[$application_name]))
|
||||
{
|
||||
$colors = ConsoleColors::ALL;
|
||||
|
||||
try
|
||||
{
|
||||
$color = $colors[random_int(0, count($colors) - 1)];
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new LoggingException(sprintf('Unable to generate random color for application "%s"', $application_name), $e->getCode(), $e);
|
||||
}
|
||||
|
||||
self::$application_colors[$application_name] = $color;
|
||||
}
|
||||
|
||||
return self::color($application_name, self::$application_colors[$application_name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a specified color to the given text, using ANSI escape sequences.
|
||||
*
|
||||
* @param string $text The text to apply the color to.
|
||||
* @param ConsoleColors $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, ConsoleColors $color): string
|
||||
{
|
||||
return "\033[" . $color->value . "m" . $text . "\033[0m";
|
||||
}
|
||||
|
||||
/**
|
||||
* Colorizes the log message based on the event level using ANSI escape sequences.
|
||||
*
|
||||
* @param Event $event The log event to colorize.
|
||||
* @return string The colorized log message.
|
||||
*/
|
||||
private static function colorize(Event $event): string
|
||||
{
|
||||
$color = match($event->getLevel())
|
||||
{
|
||||
LogLevel::DEBUG => ConsoleColors::LIGHT_PURPLE,
|
||||
LogLevel::VERBOSE => ConsoleColors::LIGHT_CYAN,
|
||||
LogLevel::INFO => ConsoleColors::WHITE,
|
||||
LogLevel::WARNING => ConsoleColors::YELLOW,
|
||||
LogLevel::FATAL => ConsoleColors::RED,
|
||||
LogLevel::ERROR => ConsoleColors::LIGHT_RED,
|
||||
default => null,
|
||||
};
|
||||
|
||||
if($color === null)
|
||||
{
|
||||
return Utilities::levelToString($event->getLevel());
|
||||
}
|
||||
|
||||
return self::color(Utilities::levelToString($event->getLevel()), $color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current timestamp as a formatted string.
|
||||
*
|
||||
* @return string The current timestamp.
|
||||
*/
|
||||
private static function getTimestamp(): string
|
||||
{
|
||||
$tick_time = (string)microtime(true);
|
||||
|
||||
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)
|
||||
{
|
||||
$tick_time = str_pad($tick_time, (strlen($tick_time) + (self::$largest_tick_length - strlen($tick_time))));
|
||||
}
|
||||
|
||||
$fmt_tick = $tick_time;
|
||||
if(self::$last_tick_time !== null)
|
||||
{
|
||||
$timeDiff = microtime(true) - self::$last_tick_time;
|
||||
|
||||
if ($timeDiff > 1.0)
|
||||
{
|
||||
$fmt_tick = self::color($tick_time, ConsoleColors::LIGHT_RED);
|
||||
}
|
||||
elseif ($timeDiff > 0.5)
|
||||
{
|
||||
$fmt_tick = self::color($tick_time, ConsoleColors::YELLOW);
|
||||
}
|
||||
}
|
||||
|
||||
self::$last_tick_time = $tick_time;
|
||||
return $fmt_tick;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints information about the given exception, including the error message, error code,
|
||||
* and stack trace.
|
||||
*
|
||||
* @param Throwable|null $exception The exception to print information about.
|
||||
* @return 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);
|
||||
|
||||
print($trace_header . ' ' . $trace_error . $exception->getMessage() . PHP_EOL);
|
||||
print(sprintf('Error code: %s', $exception->getCode()) . PHP_EOL);
|
||||
$trace = $exception->getTrace();
|
||||
|
||||
if(count($trace) > 1)
|
||||
{
|
||||
print('Stack Trace:' . PHP_EOL);
|
||||
foreach($trace as $item)
|
||||
{
|
||||
print( ' - ' . self::color($item['file'], ConsoleColors::RED) . ':' . $item['line'] . PHP_EOL);
|
||||
}
|
||||
}
|
||||
|
||||
if($exception->getPrevious() !== null)
|
||||
{
|
||||
print('Previous Exception:' . PHP_EOL);
|
||||
self::outException($exception->getPrevious());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue