Compare commits
No commits in common. "master" and "1.1.1" have entirely different histories.
31 changed files with 765 additions and 1722 deletions
12
.github/workflows/ncc_workflow.yml
vendored
12
.github/workflows/ncc_workflow.yml
vendored
|
@ -51,7 +51,7 @@ jobs:
|
|||
|
||||
- name: Build project
|
||||
run: |
|
||||
ncc build --config release --build-source --log-level debug
|
||||
ncc build --config release --log-level debug
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -100,7 +100,7 @@ jobs:
|
|||
|
||||
- name: Build project
|
||||
run: |
|
||||
ncc build --config release-compressed --build-source --log-level debug
|
||||
ncc build --config release-compressed --log-level debug
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -149,7 +149,7 @@ jobs:
|
|||
|
||||
- name: Build project
|
||||
run: |
|
||||
ncc build --config debug-compressed --build-source --log-level debug
|
||||
ncc build --config debug-compressed --log-level debug
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -198,7 +198,7 @@ jobs:
|
|||
|
||||
- name: Build project
|
||||
run: |
|
||||
ncc build --config release-executable --build-source --log-level debug
|
||||
ncc build --config release-executable --log-level debug
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -247,7 +247,7 @@ jobs:
|
|||
|
||||
- name: Build project
|
||||
run: |
|
||||
ncc build --config release-compressed-executable --build-source --log-level debug
|
||||
ncc build --config release-compressed-executable --log-level debug
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
@ -296,7 +296,7 @@ jobs:
|
|||
|
||||
- name: Build project
|
||||
run: |
|
||||
ncc build --config debug-compressed-executable --build-source --log-level debug
|
||||
ncc build --config debug-compressed-executable --log-level debug
|
||||
|
||||
- name: Upload build artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -1,3 +1 @@
|
|||
build/
|
||||
/.idea/phpunit.xml
|
||||
/.phpunit.result.cache
|
||||
build/
|
1
.idea/inspectionProfiles/Project_Default.xml
generated
1
.idea/inspectionProfiles/Project_Default.xml
generated
|
@ -25,6 +25,5 @@
|
|||
</set>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
<inspection_tool class="PhpDocRedundantThrowsInspection" enabled="true" level="INFORMATION" enabled_by_default="true" />
|
||||
</profile>
|
||||
</component>
|
2
.idea/php-test-framework.xml
generated
2
.idea/php-test-framework.xml
generated
|
@ -5,7 +5,7 @@
|
|||
<tool tool_name="PHPUnit">
|
||||
<cache>
|
||||
<versions>
|
||||
<info id="Local/home/netkas/phar/phpunit.phar" version="11.3.5" />
|
||||
<info id="Local" version="PHPUnit version can't be detected. Default PHP interpreter is not local" />
|
||||
</versions>
|
||||
</cache>
|
||||
</tool>
|
||||
|
|
4
.idea/php.xml
generated
4
.idea/php.xml
generated
|
@ -11,8 +11,8 @@
|
|||
</component>
|
||||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="/var/ncc/packages/net.nosial.optslib=1.1.2" />
|
||||
<path value="/usr/share/php" />
|
||||
<path value="/var/ncc/packages/net.nosial.optslib=1.1.0" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
||||
|
@ -124,7 +124,7 @@
|
|||
</component>
|
||||
<component name="PhpUnit">
|
||||
<phpunit_settings>
|
||||
<PhpUnitSettings load_method="PHPUNIT_PHAR" custom_loader_path="$USER_HOME$/phpunit-9.5.phar" phpunit_phar_path="$USER_HOME$/phar/phpunit.phar" />
|
||||
<PhpUnitSettings load_method="PHPUNIT_PHAR" custom_loader_path="$USER_HOME$/phpunit-9.5.phar" phpunit_phar_path="$USER_HOME$/phpunit-9.5.phar" />
|
||||
</phpunit_settings>
|
||||
</component>
|
||||
<component name="PsalmOptionsConfiguration">
|
||||
|
|
74
CHANGELOG.md
74
CHANGELOG.md
|
@ -5,80 +5,6 @@ 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).
|
||||
|
||||
## [2.0.7] - 2025-01-13
|
||||
|
||||
This update introduces a minor fix
|
||||
|
||||
### Fixed
|
||||
- Fixed FileLogging issue by setting the write permission to 0666 for the log file if it doesn't exist.
|
||||
|
||||
|
||||
|
||||
## [2.0.6] - 2025-01-10
|
||||
|
||||
This update introduces a minor change
|
||||
|
||||
### Changed
|
||||
- File logging is disabled for web environments due to instability in file locking, until a better solution is found.
|
||||
|
||||
|
||||
## [2.0.5] - 2025-01-09
|
||||
|
||||
This update introduces a minor bug fix
|
||||
|
||||
### Fixed
|
||||
- Refactor file locking to return status and handle failure.
|
||||
|
||||
|
||||
## [2.0.4] - 2024-12-04
|
||||
|
||||
This update introduces a minor bug fix
|
||||
|
||||
|
||||
## [2.0.3] - 2024-11-05
|
||||
|
||||
This update introduces a minor bug fix
|
||||
|
||||
|
||||
## [2.0.2] - 2024-10-30
|
||||
|
||||
This update introduces minor improvements
|
||||
|
||||
### Changed
|
||||
- Refactored exception handling in FileLogging where it will always attempt to print the exception no matter
|
||||
the log level for as long as the log level isn't silent
|
||||
- Implement enhanced error and exception handling
|
||||
|
||||
|
||||
## [2.0.1] - 2024-10-29
|
||||
|
||||
This update introduces a critical bug fix where Console logging was enabled in web environments
|
||||
|
||||
|
||||
## [2.0.0] - 2024-10-29
|
||||
|
||||
This update introduces some additional features & bug fixes
|
||||
|
||||
### Added
|
||||
- Added File Logging support
|
||||
- Added LogHandlerInterface & refactored Application settings to allow for use of custom logging handlers
|
||||
- Added Logging type for logging type handling
|
||||
- Added a Logger object for creating a logging instance for Applications
|
||||
|
||||
### Changed
|
||||
- All abstract classes are now enum classes
|
||||
- Refactored Console Logging to use the new LogHandlerInterface
|
||||
|
||||
### Fixed
|
||||
- Set default log level to 'info' in Utilities. instead of using `null` due to deprecation error
|
||||
|
||||
### Removed
|
||||
- Removed Unused BRIGHT_COLORS constant from ConsoleColors
|
||||
- Removed Unused Options object
|
||||
- Removed Unused RuntimeOptions object
|
||||
- Removed unused Console class
|
||||
|
||||
|
||||
## [1.1.1] - 2024-10-13
|
||||
|
||||
Update build system
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
<?php
|
||||
require 'ncc';
|
||||
import('net.nosial.loglib');
|
11
phpunit.xml
11
phpunit.xml
|
@ -1,11 +0,0 @@
|
|||
<phpunit bootstrap="bootstrap.php">
|
||||
<testsuites>
|
||||
<testsuite name="LogLib Test Suite">
|
||||
<directory>tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<php>
|
||||
<ini name="error_reporting" value="-1"/>
|
||||
<server name="KERNEL_DIR" value="app/"/>
|
||||
</php>
|
||||
</phpunit>
|
|
@ -20,7 +20,7 @@
|
|||
"package": "net.nosial.loglib",
|
||||
"company": "Nosial",
|
||||
"copyright": "Copyright (c) 2022-2023 Nosial",
|
||||
"version": "2.0.7",
|
||||
"version": "1.1.1",
|
||||
"uuid": "de1deca6-7b65-11ed-a8b0-a172264634d8"
|
||||
},
|
||||
"build": {
|
||||
|
|
41
src/LogLib/Abstracts/CallType.php
Normal file
41
src/LogLib/Abstracts/CallType.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Abstracts;
|
||||
|
||||
final class CallType
|
||||
{
|
||||
/**
|
||||
* 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 = 'λ';
|
||||
|
||||
/**
|
||||
* Represents an eval() call.
|
||||
*
|
||||
* @var string EVAL_CALL
|
||||
*/
|
||||
public const EVAL_CALL = 'eval()';
|
||||
}
|
75
src/LogLib/Abstracts/ConsoleColors.php
Normal file
75
src/LogLib/Abstracts/ConsoleColors.php
Normal file
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Abstracts;
|
||||
|
||||
final class ConsoleColors
|
||||
{
|
||||
public const BLACK = "0;30";
|
||||
|
||||
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
|
||||
*/
|
||||
public const BRIGHT_COLORS = [
|
||||
self::LIGHT_BLUE,
|
||||
self::LIGHT_GREEN,
|
||||
self::LIGHT_CYAN,
|
||||
self::LIGHT_RED,
|
||||
self::LIGHT_PURPLE,
|
||||
];
|
||||
}
|
|
@ -1,43 +1,43 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Enums;
|
||||
namespace LogLib\Abstracts;
|
||||
|
||||
enum LogLevel : int
|
||||
final class LevelType
|
||||
{
|
||||
/**
|
||||
* Silent type.
|
||||
*/
|
||||
case SILENT = 0;
|
||||
public const SILENT = 0;
|
||||
|
||||
/**
|
||||
* Fatal type.
|
||||
*/
|
||||
case FATAL = 1;
|
||||
public const FATAL = 1;
|
||||
|
||||
/**
|
||||
* Error type.
|
||||
*/
|
||||
case ERROR = 2;
|
||||
public const ERROR = 2;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
case WARNING = 3;
|
||||
public const WARNING = 3;
|
||||
|
||||
/**
|
||||
* Information type.
|
||||
*/
|
||||
case INFO = 4;
|
||||
public const INFO = 4;
|
||||
|
||||
/**
|
||||
* Verbose type.
|
||||
*/
|
||||
case VERBOSE = 5;
|
||||
public const VERBOSE = 5;
|
||||
|
||||
/**
|
||||
* Debug type.
|
||||
*/
|
||||
case DEBUG = 6;
|
||||
public const DEBUG = 6;
|
||||
|
||||
/**
|
||||
* All types.
|
|
@ -1,87 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Classes;
|
||||
|
||||
class BacktraceParser
|
||||
{
|
||||
/**
|
||||
* Determines if the given backtrace originates from the exception handler.
|
||||
*
|
||||
* @param array $backtrace The backtrace array to inspect.
|
||||
* @return bool Returns true if the backtrace originates from the exception handler within LogLib\Runtime class, false otherwise.
|
||||
*/
|
||||
public static function fromExceptionHandler(array $backtrace): bool
|
||||
{
|
||||
/** @var array $trace */
|
||||
foreach($backtrace as $trace)
|
||||
{
|
||||
if(!isset($trace['function']) || $trace['function'] != 'exceptionHandler')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!isset($trace['class']) || $trace['class'] != 'LogLib\Runtime')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the given backtrace originates from the error handler.
|
||||
*
|
||||
* @param array $backtrace The backtrace array to inspect.
|
||||
* @return bool Returns true if the backtrace originates from the error handler within LogLib\Runtime class, false otherwise.
|
||||
*/
|
||||
public static function fromErrorHandler(array $backtrace): bool
|
||||
{
|
||||
/** @var array $trace */
|
||||
foreach($backtrace as $trace)
|
||||
{
|
||||
if(!isset($trace['function']) || $trace['function'] != 'errorHandler')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!isset($trace['class']) || $trace['class'] != 'LogLib\Runtime')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if a given backtrace contains a call to the shutdownHandler method in the LogLib\Runtime class.
|
||||
*
|
||||
* @param array $backtrace The backtrace to be analyzed.
|
||||
* @return bool True if the shutdownHandler method in the LogLib\Runtime class is found in the backtrace; otherwise, false.
|
||||
*/
|
||||
public static function fromShutdownHandler(array $backtrace): bool
|
||||
{
|
||||
/** @var array $trace */
|
||||
foreach($backtrace as $trace)
|
||||
{
|
||||
if(!isset($trace['function']) || $trace['function'] != 'shutdownHandler')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!isset($trace['class']) || $trace['class'] != 'LogLib\Runtime')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
249
src/LogLib/Classes/Console.php
Normal file
249
src/LogLib/Classes/Console.php
Normal file
|
@ -0,0 +1,249 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
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
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private static $application_colors = [];
|
||||
|
||||
|
||||
/**
|
||||
* @var float|int|null
|
||||
*/
|
||||
private static $last_tick_time;
|
||||
|
||||
/**
|
||||
* @var int|null
|
||||
*/
|
||||
private static $largest_tick_length;
|
||||
|
||||
/**
|
||||
* Formats the application name with a color for the console
|
||||
*
|
||||
* @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()->displayAnsi())
|
||||
{
|
||||
return $application;
|
||||
}
|
||||
|
||||
if(!isset(self::$application_colors[$application]))
|
||||
{
|
||||
$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;
|
||||
}
|
||||
|
||||
return self::color($application, self::$application_colors[$application]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies a specified color to the given text, using ANSI escape sequences.
|
||||
*
|
||||
* @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()->displayAnsi())
|
||||
{
|
||||
return $text;
|
||||
}
|
||||
|
||||
return "\033[" . $color . "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
|
||||
{
|
||||
if(!Log::getRuntimeOptions()->displayAnsi())
|
||||
{
|
||||
return Utilities::levelToString($event->getLevel());
|
||||
}
|
||||
|
||||
$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($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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a log event to the console.
|
||||
*
|
||||
* @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::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),
|
||||
$backtrace_output, $event->getMessage()
|
||||
));
|
||||
|
||||
if($event->getException() !== null)
|
||||
{
|
||||
self::outException($event->getException());
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
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->getMessage()
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,122 +0,0 @@
|
|||
<?php
|
||||
namespace LogLib\Classes;
|
||||
use RuntimeException;
|
||||
|
||||
/**
|
||||
* Class FileLock
|
||||
*
|
||||
* This class provides functionalities to safely work with file locks and ensures
|
||||
* that concurrent write operations do not overwrite each other.
|
||||
* It offers methods to lock, unlock, and append data to a file.
|
||||
*/
|
||||
class FileLock
|
||||
{
|
||||
private $fileHandle;
|
||||
private string $filePath;
|
||||
private int $retryInterval; // in microseconds
|
||||
private int $confirmationInterval; // in microseconds
|
||||
|
||||
/**
|
||||
* Constructor for FileLock.
|
||||
*
|
||||
* @param string $filePath Path to the file.
|
||||
* @param int $retryInterval Time to wait between retries (in microseconds).
|
||||
* @param int $confirmationInterval Time to wait before double confirmation (in microseconds).
|
||||
*/
|
||||
public function __construct(string $filePath, int $retryInterval=100000, int $confirmationInterval=50000)
|
||||
{
|
||||
$this->filePath = $filePath;
|
||||
$this->retryInterval = $retryInterval;
|
||||
$this->confirmationInterval = $confirmationInterval;
|
||||
|
||||
// Create the file if it doesn't exist
|
||||
if (!file_exists($filePath))
|
||||
{
|
||||
// Create the file
|
||||
touch($filePath);
|
||||
|
||||
// Set the file permissions to 0666
|
||||
chmod($filePath, 0666);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Locks the file.
|
||||
*
|
||||
* @throws RuntimeException if unable to open or lock the file.
|
||||
*/
|
||||
private function lock(): bool
|
||||
{
|
||||
$this->fileHandle = @fopen($this->filePath, 'a');
|
||||
if ($this->fileHandle === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Keep trying to acquire the lock until it succeeds
|
||||
while (!flock($this->fileHandle, LOCK_EX))
|
||||
{
|
||||
usleep($this->retryInterval); // Wait for the specified interval before trying again
|
||||
}
|
||||
|
||||
// Double confirmation
|
||||
usleep($this->confirmationInterval); // Wait for the specified confirmation interval
|
||||
if (!flock($this->fileHandle, LOCK_EX | LOCK_NB))
|
||||
{
|
||||
// If the lock cannot be re-acquired, release the current lock and retry
|
||||
flock($this->fileHandle, LOCK_UN);
|
||||
$this->lock();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlocks the file after performing write operations.
|
||||
*/
|
||||
private function unlock(): void
|
||||
{
|
||||
if ($this->fileHandle !== null)
|
||||
{
|
||||
flock($this->fileHandle, LOCK_UN); // Release the lock
|
||||
fclose($this->fileHandle); // Close the file handle
|
||||
$this->fileHandle = null; // Reset the file handle
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends data to the file.
|
||||
*
|
||||
* @param string $data Data to append.
|
||||
* @throws RuntimeException if unable to write to the file.
|
||||
*/
|
||||
public function append(string $data): void
|
||||
{
|
||||
if(!$this->lock())
|
||||
{
|
||||
// Do not proceed if the file cannot be locked
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->fileHandle !== false)
|
||||
{
|
||||
if (fwrite($this->fileHandle, $data) === false)
|
||||
{
|
||||
throw new RuntimeException("Unable to write to the file: " . $this->filePath);
|
||||
}
|
||||
}
|
||||
|
||||
$this->unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor to ensure the file handle is closed.
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->fileHandle)
|
||||
{
|
||||
fclose($this->fileHandle);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
namespace LogLib\Classes;
|
||||
|
||||
use LogLib\Enums\CallType;
|
||||
use LogLib\Enums\LogLevel;
|
||||
use LogLib\Abstracts\CallType;
|
||||
use LogLib\Abstracts\LevelType;
|
||||
use LogLib\Objects\Event;
|
||||
use OptsLib\Parse;
|
||||
use Throwable;
|
||||
|
@ -28,19 +28,19 @@
|
|||
/**
|
||||
* Converts a log level to its corresponding string representation.
|
||||
*
|
||||
* @param LogLevel $level The log level to convert.
|
||||
* @param int $level The log level to convert.
|
||||
* @return string The string representation of the log level.
|
||||
*/
|
||||
public static function levelToString(LogLevel $level): string
|
||||
public static function levelToString(int $level): string
|
||||
{
|
||||
return match ($level)
|
||||
{
|
||||
LogLevel::DEBUG => 'DBG',
|
||||
LogLevel::VERBOSE => 'VRB',
|
||||
LogLevel::INFO => 'INF',
|
||||
LogLevel::WARNING => 'WRN',
|
||||
LogLevel::FATAL => 'CRT',
|
||||
LogLevel::ERROR => 'ERR',
|
||||
LevelType::DEBUG => 'DBG',
|
||||
LevelType::VERBOSE => 'VRB',
|
||||
LevelType::INFO => 'INF',
|
||||
LevelType::WARNING => 'WRN',
|
||||
LevelType::FATAL => 'CRT',
|
||||
LevelType::ERROR => 'ERR',
|
||||
default => 'UNK',
|
||||
};
|
||||
}
|
||||
|
@ -69,7 +69,7 @@
|
|||
/**
|
||||
* Returns the log level based on the configuration.
|
||||
*
|
||||
* @return LogLevel The log level. This value represents the severity or importance of the log messages.
|
||||
* @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)
|
||||
|
@ -80,52 +80,54 @@
|
|||
* - SILENT (0)
|
||||
* If no log level is configured or the configured level is not recognized, the INFO level (4) will be returned by default.
|
||||
*/
|
||||
private static function parseLogLevel(string $logLevel): LogLevel
|
||||
public static function getLogLevel(): int
|
||||
{
|
||||
switch(strtolower($logLevel))
|
||||
$args = Parse::getArguments();
|
||||
|
||||
switch(strtolower(($args['log'] ?? $args['log-level'] ?? (getenv('LOG_LEVEL') ?: null) ?? null)))
|
||||
{
|
||||
case LogLevel::DEBUG:
|
||||
case LevelType::DEBUG:
|
||||
case 'debug':
|
||||
case '6':
|
||||
case 'dbg':
|
||||
return LogLevel::DEBUG;
|
||||
return LevelType::DEBUG;
|
||||
|
||||
case LogLevel::VERBOSE:
|
||||
case LevelType::VERBOSE:
|
||||
case 'verbose':
|
||||
case '5':
|
||||
case 'vrb':
|
||||
return LogLevel::VERBOSE;
|
||||
return LevelType::VERBOSE;
|
||||
|
||||
default:
|
||||
case LogLevel::INFO:
|
||||
case LevelType::INFO:
|
||||
case 'info':
|
||||
case '4':
|
||||
case 'inf':
|
||||
return LogLevel::INFO;
|
||||
return LevelType::INFO;
|
||||
|
||||
case LogLevel::WARNING:
|
||||
case LevelType::WARNING:
|
||||
case 'warning':
|
||||
case '3':
|
||||
case 'wrn':
|
||||
return LogLevel::WARNING;
|
||||
return LevelType::WARNING;
|
||||
|
||||
case LogLevel::ERROR:
|
||||
case LevelType::ERROR:
|
||||
case 'error':
|
||||
case '2':
|
||||
case 'err':
|
||||
return LogLevel::ERROR;
|
||||
return LevelType::ERROR;
|
||||
|
||||
case LogLevel::FATAL:
|
||||
case LevelType::FATAL:
|
||||
case 'fatal':
|
||||
case '1':
|
||||
case 'crt':
|
||||
return LogLevel::FATAL;
|
||||
return LevelType::FATAL;
|
||||
|
||||
case LogLevel::SILENT:
|
||||
case LevelType::SILENT:
|
||||
case 'silent':
|
||||
case '0':
|
||||
case 'sil':
|
||||
return LogLevel::SILENT;
|
||||
return LevelType::SILENT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,120 +154,77 @@
|
|||
* 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 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 = true): ?string
|
||||
public static function getTraceString(Event $event, bool $ansi=false): ?string
|
||||
{
|
||||
if ($event->getBacktrace() === null || count($event->getBacktrace()) === 0)
|
||||
if($event->getBacktrace() === null || count($event->getBacktrace()) === 0)
|
||||
{
|
||||
return CallType::LAMBDA_CALL->value;
|
||||
return CallType::LAMBDA_CALL;
|
||||
}
|
||||
|
||||
$backtrace = $event->getBacktrace()[count($event->getBacktrace()) - 1];
|
||||
|
||||
// Ignore \LogLib namespace
|
||||
if (isset($backtrace['class']) && str_starts_with($backtrace['class'], 'LogLib'))
|
||||
if(isset($backtrace['class']) && str_starts_with($backtrace['class'], 'LogLib'))
|
||||
{
|
||||
if (isset($backtrace['file']))
|
||||
if(isset($backtrace['file']))
|
||||
{
|
||||
if ($ansi)
|
||||
{
|
||||
return "\033[1;37m" . basename($backtrace['file']) . "\033[0m";
|
||||
}
|
||||
return basename($backtrace['file']);
|
||||
return ($ansi ? "\033[1;37m" : '') . basename($backtrace['file']) . ($ansi ? "\033[0m" : '');
|
||||
}
|
||||
|
||||
return self::determineCallType($event->getBacktrace())->value; // Return a placeholder value
|
||||
return basename($backtrace['file']);
|
||||
}
|
||||
|
||||
if ($backtrace['function'] === '{closure}')
|
||||
if($backtrace['function'] === '{closure}')
|
||||
{
|
||||
if (isset($backtrace['file']))
|
||||
if(isset($backtrace['file']))
|
||||
{
|
||||
if ($ansi)
|
||||
{
|
||||
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 ($ansi ? "\033[1;37m" : '') . basename($backtrace['file']) . ($ansi ? "\033[0m" : '') . CallType::STATIC_CALL . CallType::LAMBDA_CALL;
|
||||
}
|
||||
|
||||
return self::determineCallType($event->getBacktrace())->value . CallType::STATIC_CALL->value . CallType::LAMBDA_CALL->value; // Adjusted to handle missing 'file'
|
||||
return basename($backtrace['file']) . CallType::STATIC_CALL . CallType::LAMBDA_CALL;
|
||||
}
|
||||
|
||||
if ($backtrace['function'] === 'eval')
|
||||
if($backtrace['function'] === 'eval')
|
||||
{
|
||||
if (isset($backtrace['file']))
|
||||
if(isset($backtrace['file']))
|
||||
{
|
||||
if ($ansi)
|
||||
{
|
||||
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 ($ansi ? "\033[1;37m" : '') . basename($backtrace['file']) . ($ansi ? "\033[0m" : '') . CallType::STATIC_CALL . CallType::EVAL_CALL;
|
||||
}
|
||||
return self::determineCallType($event->getBacktrace())->value . CallType::STATIC_CALL->value . CallType::EVAL_CALL->value; // Adjusted to handle missing 'file'
|
||||
|
||||
return basename($backtrace['file']) . CallType::STATIC_CALL . CallType::EVAL_CALL;
|
||||
}
|
||||
|
||||
if ($ansi)
|
||||
if($ansi)
|
||||
{
|
||||
$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;
|
||||
}
|
||||
|
||||
$class = null;
|
||||
|
||||
if (isset($backtrace["class"]))
|
||||
if($class === null)
|
||||
{
|
||||
if ($ansi)
|
||||
{
|
||||
$class = sprintf("\033[1;37m%s\033[0m", $backtrace['class']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$class = $backtrace['class'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($class === null)
|
||||
{
|
||||
return $function . CallType::FUNCTION_CALL->value;
|
||||
return $function . CallType::FUNCTION_CALL;
|
||||
}
|
||||
|
||||
$type = ($backtrace['type'] === CallType::METHOD_CALL ? CallType::METHOD_CALL : CallType::STATIC_CALL);
|
||||
return "{$class}{$type->value}{$function}" . CallType::FUNCTION_CALL->value;
|
||||
return "{$class}{$type}{$function}" . CallType::FUNCTION_CALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the type of call based on the provided backtrace.
|
||||
*
|
||||
* @param array $backtrace The backtrace information of the calling code.
|
||||
* @return CallType The type of call detected.
|
||||
*/
|
||||
private static function determineCallType(array $backtrace): CallType
|
||||
{
|
||||
if(BacktraceParser::fromErrorHandler($backtrace))
|
||||
{
|
||||
return CallType::ERROR_HANDLER;
|
||||
}
|
||||
|
||||
if(BacktraceParser::fromExceptionHandler($backtrace))
|
||||
{
|
||||
return CallType::EXCEPTION_HANDLER;
|
||||
}
|
||||
|
||||
if(BacktraceParser::fromShutdownHandler($backtrace))
|
||||
{
|
||||
return CallType::SHUTDOWN_HANDLER;
|
||||
}
|
||||
|
||||
return CallType::UNKNOWN_FILE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an exception object to an array representation.
|
||||
|
@ -294,135 +253,4 @@
|
|||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the directory path for logging purposes.
|
||||
*
|
||||
* @return string The path to the log directory, or a temporary directory if not set.
|
||||
*/
|
||||
public static function getLogDirectory(): string
|
||||
{
|
||||
$args = Parse::getArguments();
|
||||
$LOGGING_DIRECTORY = ($args['logging-directory'] ?? getenv('LOGGING_DIRECTORY') ?? null);
|
||||
|
||||
if($LOGGING_DIRECTORY === null)
|
||||
{
|
||||
return sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'logs';
|
||||
}
|
||||
|
||||
return $LOGGING_DIRECTORY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if console logging is enabled based on command-line arguments,
|
||||
* execution environment, or environment variables.
|
||||
*
|
||||
* @return bool True if console logging is enabled, false otherwise.
|
||||
*/
|
||||
public static function getConsoleLoggingEnabled(): bool
|
||||
{
|
||||
if(isset(Parse::getArguments()['log-level']))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(self::runningInCli())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(getenv('LOGGING_CONSOLE') === 'true' || getenv('LOGGING_CONSOLE') === '1')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current logging level for console output.
|
||||
*
|
||||
* @return LogLevel The determined logging level.
|
||||
*/
|
||||
public static function getConsoleLoggingLevel(): LogLevel
|
||||
{
|
||||
return self::parseLogLevel(($args['log'] ?? $args['log-level'] ?? (getenv('LOG_LEVEL') ?: 'info') ?? 'info'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if file logging is enabled based on various conditions.
|
||||
*
|
||||
* @return bool True if file logging is enabled, false otherwise.
|
||||
*/
|
||||
public static function getFileLoggingEnabled(): bool
|
||||
{
|
||||
if(isset(Parse::getArguments()['logging-directory']))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(getenv('LOGGING_DIRECTORY') !== null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if(!is_writable(self::getLogDirectory()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the logging level for file outputs based on environment variables or command line arguments.
|
||||
*
|
||||
* @return LogLevel The logging level to be used for file logging.
|
||||
*/
|
||||
public static function getFileLoggingLevel(): LogLevel
|
||||
{
|
||||
if(getenv('LOGGING_FILE_LEVEL') !== null)
|
||||
{
|
||||
return self::parseLogLevel(getenv('LOGGING_FILE_LEVEL'));
|
||||
}
|
||||
|
||||
if(isset(Parse::getArguments()['logging-file-level']))
|
||||
{
|
||||
return self::parseLogLevel(Parse::getArguments()['logging-file-level']);
|
||||
}
|
||||
|
||||
return LogLevel::WARNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the directory path for file logging.
|
||||
*
|
||||
* @return string The logging directory path.
|
||||
*/
|
||||
public static function getFileLoggingDirectory(): string
|
||||
{
|
||||
$args = Parse::getArguments();
|
||||
$LOGGING_DIRECTORY = ($args['logging-directory'] ?? getenv('LOGGING_DIRECTORY') ?? null);
|
||||
|
||||
if($LOGGING_DIRECTORY === null || $LOGGING_DIRECTORY === false || strlen($LOGGING_DIRECTORY) === 0)
|
||||
{
|
||||
return sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'logs';
|
||||
}
|
||||
|
||||
return $LOGGING_DIRECTORY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sanitizes a file name by replacing spaces with hyphens and removing illegal characters.
|
||||
*
|
||||
* @param string $name The file name to sanitize.
|
||||
* @return string The sanitized file name.
|
||||
*/
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -2,78 +2,98 @@
|
|||
|
||||
namespace LogLib\Classes;
|
||||
|
||||
use LogLib\Enums\LogLevel;
|
||||
use LogLib\Abstracts\LevelType;
|
||||
|
||||
class Validate
|
||||
{
|
||||
/**
|
||||
* Checks if the given level is a valid level type.
|
||||
*
|
||||
* @param int $level The level to check.
|
||||
* @return bool Returns true if the level is valid
|
||||
*/
|
||||
public static function LevelType(int $level): bool
|
||||
{
|
||||
return in_array($level, LevelType::ALL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given input level is valid for the current level.
|
||||
*
|
||||
* @param LogLevel $input The input level to check.
|
||||
* @param LogLevel $current_level The current level to compare against.
|
||||
* @param int $input The input level to check.
|
||||
* @param int $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(LogLevel $input, LogLevel $current_level): bool
|
||||
public static function checkLevelType(int $input, int $current_level): bool
|
||||
{
|
||||
switch($current_level)
|
||||
if(!self::LevelType($input))
|
||||
{
|
||||
case LogLevel::DEBUG:
|
||||
$levels = [
|
||||
LogLevel::DEBUG,
|
||||
LogLevel::VERBOSE,
|
||||
LogLevel::INFO,
|
||||
LogLevel::WARNING,
|
||||
LogLevel::FATAL,
|
||||
LogLevel::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LogLevel::VERBOSE:
|
||||
$levels = [
|
||||
LogLevel::VERBOSE,
|
||||
LogLevel::INFO,
|
||||
LogLevel::WARNING,
|
||||
LogLevel::FATAL,
|
||||
LogLevel::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LogLevel::INFO:
|
||||
$levels = [
|
||||
LogLevel::INFO,
|
||||
LogLevel::WARNING,
|
||||
LogLevel::FATAL,
|
||||
LogLevel::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LogLevel::WARNING:
|
||||
$levels = [
|
||||
LogLevel::WARNING,
|
||||
LogLevel::FATAL,
|
||||
LogLevel::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LogLevel::ERROR:
|
||||
$levels = [
|
||||
LogLevel::FATAL,
|
||||
LogLevel::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LogLevel::FATAL:
|
||||
return $input == LogLevel::FATAL;
|
||||
|
||||
case LogLevel::SILENT:
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
if(!self::LevelType($current_level))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch($current_level)
|
||||
{
|
||||
case LevelType::DEBUG:
|
||||
$levels = [
|
||||
LevelType::DEBUG,
|
||||
LevelType::VERBOSE,
|
||||
LevelType::INFO,
|
||||
LevelType::WARNING,
|
||||
LevelType::FATAL,
|
||||
LevelType::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LevelType::VERBOSE:
|
||||
$levels = [
|
||||
LevelType::VERBOSE,
|
||||
LevelType::INFO,
|
||||
LevelType::WARNING,
|
||||
LevelType::FATAL,
|
||||
LevelType::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LevelType::INFO:
|
||||
$levels = [
|
||||
LevelType::INFO,
|
||||
LevelType::WARNING,
|
||||
LevelType::FATAL,
|
||||
LevelType::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LevelType::WARNING:
|
||||
$levels = [
|
||||
LevelType::WARNING,
|
||||
LevelType::FATAL,
|
||||
LevelType::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LevelType::ERROR:
|
||||
$levels = [
|
||||
LevelType::FATAL,
|
||||
LevelType::ERROR
|
||||
];
|
||||
|
||||
return in_array($input, $levels, true);
|
||||
|
||||
case LevelType::FATAL:
|
||||
return $input === LevelType::FATAL;
|
||||
|
||||
default:
|
||||
case LevelType::SILENT:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Enums;
|
||||
|
||||
enum CallType : string
|
||||
{
|
||||
/**
|
||||
* Represents a method call.
|
||||
*
|
||||
* @var string METHOD_CALL
|
||||
*/
|
||||
case METHOD_CALL = '->';
|
||||
|
||||
/**
|
||||
* Represents a static method call.
|
||||
*
|
||||
* @var string STATIC_CALL
|
||||
*/
|
||||
case STATIC_CALL = '::';
|
||||
|
||||
/**
|
||||
* Represents a function call.
|
||||
*
|
||||
* @var string FUNCTION_CALL
|
||||
*/
|
||||
case FUNCTION_CALL = '()';
|
||||
|
||||
/**
|
||||
* Represents a lambda function call.
|
||||
*
|
||||
* @var string LAMBDA_CALL
|
||||
*/
|
||||
case LAMBDA_CALL = 'λ';
|
||||
|
||||
/**
|
||||
* Represents an eval() call.
|
||||
*
|
||||
* @var string EVAL_CALL
|
||||
*/
|
||||
case EVAL_CALL = 'eval()';
|
||||
|
||||
/**
|
||||
* Represents an unknown file.
|
||||
*
|
||||
* @var string UNKNOWN_FILE
|
||||
*/
|
||||
case UNKNOWN_FILE = '?';
|
||||
|
||||
/**
|
||||
* Represents a runtime error handler.
|
||||
*
|
||||
* @var string ERROR_HANDLER
|
||||
*/
|
||||
case ERROR_HANDLER = 'RUNTIME_ERROR';
|
||||
|
||||
/**
|
||||
* Represents a shutdown handler event.
|
||||
*
|
||||
* @var string SHUTDOWN_HANDLER
|
||||
*/
|
||||
case SHUTDOWN_HANDLER = 'SHUTDOWN_ERROR';
|
||||
|
||||
/**
|
||||
* Represents an exception handler for runtime exceptions.
|
||||
*
|
||||
* @var string EXCEPTION_HANDLER
|
||||
*/
|
||||
case EXCEPTION_HANDLER = 'RUNTIME_EXCEPTION';
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Enums;
|
||||
|
||||
enum ConsoleColors : string
|
||||
{
|
||||
case BLUE = "0;34";
|
||||
|
||||
case LIGHT_BLUE = "1;34";
|
||||
|
||||
case GREEN = "0;32";
|
||||
|
||||
case LIGHT_GREEN = "1;32";
|
||||
|
||||
case CYAN = "0;36";
|
||||
|
||||
case LIGHT_CYAN = "1;36";
|
||||
|
||||
case RED = "0;31";
|
||||
|
||||
case LIGHT_RED = "1;31";
|
||||
|
||||
case PURPLE = "0;35";
|
||||
|
||||
case LIGHT_PURPLE = "1;35";
|
||||
|
||||
case BROWN = "0;33";
|
||||
|
||||
case YELLOW = "1;33";
|
||||
|
||||
case LIGHT_GRAY = "0;37";
|
||||
|
||||
case WHITE = "1;37";
|
||||
|
||||
case RESET = "0";
|
||||
|
||||
/**
|
||||
* Represents an array of all possible supported color values.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public const ALL = [
|
||||
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
|
||||
];
|
||||
}
|
|
@ -1,223 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Handlers;
|
||||
|
||||
use Exception;
|
||||
use LogLib\Classes\Utilities;
|
||||
use LogLib\Classes\Validate;
|
||||
use LogLib\Enums\ConsoleColors;
|
||||
use LogLib\Enums\LogLevel;
|
||||
use LogLib\Interfaces\LogHandlerInterface;
|
||||
use LogLib\Objects\Application;
|
||||
use LogLib\Objects\Event;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
class ConsoleLogging implements LogHandlerInterface
|
||||
{
|
||||
private static array $application_colors = [];
|
||||
private static float|int|null $last_tick_time = null;
|
||||
private static ?int $largest_tick_length = null;
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function handle(Application $application, Event $event): void
|
||||
{
|
||||
if(!Utilities::runningInCli())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 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()
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats the application name with a color for the console
|
||||
*
|
||||
* @param string $application_name The application name
|
||||
* @return string The formatted application name
|
||||
*/
|
||||
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 RuntimeException(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)
|
||||
{
|
||||
if(isset($item['file']) && isset($item['line']))
|
||||
{
|
||||
print( ' - ' . self::color($item['file'], ConsoleColors::RED) . ':' . $item['line'] . PHP_EOL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($exception->getPrevious() !== null)
|
||||
{
|
||||
print('Previous Exception:' . PHP_EOL);
|
||||
self::outException($exception->getPrevious());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Handlers;
|
||||
|
||||
use LogLib\Classes\FileLock;
|
||||
use LogLib\Classes\Utilities;
|
||||
use LogLib\Classes\Validate;
|
||||
use LogLib\Enums\LogLevel;
|
||||
use LogLib\Interfaces\LogHandlerInterface;
|
||||
use LogLib\Objects\Application;
|
||||
use LogLib\Objects\Event;
|
||||
use RuntimeException;
|
||||
use Throwable;
|
||||
|
||||
class FileLogging implements LogHandlerInterface
|
||||
{
|
||||
private static array $application_logs = [];
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public static function handle(Application $application, Event $event): void
|
||||
{
|
||||
if(!Validate::checkLevelType($event->getLevel(), $application->getFileLoggingLevel()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(Validate::checkLevelType(LogLevel::DEBUG, $application->getConsoleLoggingLevel()))
|
||||
{
|
||||
$backtrace_output = Utilities::getTraceString($event, false);
|
||||
$output = sprintf("[%s] [%s] [%s] %s %s" . PHP_EOL,
|
||||
self::getTimestamp(), $application->getApplicationName(), $event->getLevel()->name, $backtrace_output, $event->getMessage()
|
||||
);
|
||||
}
|
||||
else if(Validate::checkLevelType(LogLevel::VERBOSE, $application->getConsoleLoggingLevel()))
|
||||
{
|
||||
$backtrace_output = Utilities::getTraceString($event, false);
|
||||
$output = sprintf("[%s] [%s] [%s] %s %s" . PHP_EOL, self::getTimestamp(), $application->getApplicationName(), $event->getLevel()->name, $backtrace_output, $event->getMessage());
|
||||
}
|
||||
else
|
||||
{
|
||||
$output = sprintf("[%s] [%s] [%s] %s" . PHP_EOL, self::getTimestamp(), $application->getApplicationName(), $event->getLevel()->name, $event->getMessage());
|
||||
}
|
||||
|
||||
if($event->getException() !== null)
|
||||
{
|
||||
$output .= self::outException($event->getException());
|
||||
}
|
||||
|
||||
self::getLogger($application)->append($output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the logger instance associated with the given application.
|
||||
* If the logger does not exist, it initializes a new one and stores it.
|
||||
*
|
||||
* @param Application $application The application for which the logger is to be retrieved.
|
||||
* @return FileLock The logger instance associated with the specified application.
|
||||
*/
|
||||
private static function getLogger(Application $application): FileLock
|
||||
{
|
||||
if(!isset(self::$application_logs[$application->getApplicationName()]))
|
||||
{
|
||||
self::$application_logs[$application->getApplicationName()] = new FileLock(self::getLogFile($application));
|
||||
}
|
||||
|
||||
return self::$application_logs[$application->getApplicationName()];
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the log file path for the specified application.
|
||||
*
|
||||
* @param Application $application The application instance for which the log file is to be retrieved.
|
||||
* @return string The full path of the log file.
|
||||
*/
|
||||
private static function getLogFile(Application $application): string
|
||||
{
|
||||
$logging_directory = $application->getFileLoggingDirectory();
|
||||
|
||||
if(!file_exists($logging_directory))
|
||||
{
|
||||
if(!mkdir($logging_directory))
|
||||
{
|
||||
throw new RuntimeException(sprintf("Cannot write to %s due to insufficient permissions", $logging_directory));
|
||||
}
|
||||
}
|
||||
|
||||
$logging_file = $logging_directory . DIRECTORY_SEPARATOR . Utilities::sanitizeFileName($application->getApplicationName()) . '-' . date('Y-m-d') . '.log';
|
||||
|
||||
if(!file_exists($logging_file) && !@touch($logging_file))
|
||||
{
|
||||
throw new RuntimeException(sprintf("Cannot write to %s due to insufficient permissions", $logging_file));
|
||||
}
|
||||
|
||||
return $logging_file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current timestamp formatted as "yd/m/y H:i".
|
||||
*
|
||||
* @return string The formatted current timestamp.
|
||||
*/
|
||||
private static function getTimestamp(): string
|
||||
{
|
||||
return date('yd/m/y H:i');
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a detailed string representation of a given Throwable object, including its message, code,
|
||||
* file, line of occurrence, stack trace, and any previous exceptions.
|
||||
*
|
||||
* @param Throwable|null $exception The throwable object to process. If null, an empty string is returned.
|
||||
* @return string A detailed string representation of the throwable object.
|
||||
*/
|
||||
private static function outException(?Throwable $exception=null): string
|
||||
{
|
||||
if($exception === null)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
$output = '';
|
||||
$trace_header = $exception->getFile() . ':' . $exception->getLine();
|
||||
$trace_error = 'error: ';
|
||||
|
||||
$output .= $trace_header . ' ' . $trace_error . $exception->getMessage() . PHP_EOL;
|
||||
$output .= sprintf('Error code: %s', $exception->getCode() . PHP_EOL);
|
||||
$trace = $exception->getTrace();
|
||||
|
||||
if(count($trace) > 1)
|
||||
{
|
||||
$output .= 'Stack Trace:' . PHP_EOL;
|
||||
foreach($trace as $item)
|
||||
{
|
||||
if(isset($item['file']) && isset($item['line']))
|
||||
{
|
||||
$output .= ' - ' . $item['file'] . ':' . $item['line'] . PHP_EOL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($exception->getPrevious() !== null)
|
||||
{
|
||||
$output .= 'Previous Exception:' . PHP_EOL;
|
||||
$output .= self::outException($exception->getPrevious());
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Interfaces;
|
||||
|
||||
use LogLib\Exceptions\LoggingException;
|
||||
use LogLib\Objects\Application;
|
||||
use LogLib\Objects\Event;
|
||||
|
||||
interface LogHandlerInterface
|
||||
{
|
||||
/**
|
||||
* Outputs the event details based on the given options.
|
||||
*
|
||||
* @param Application $application The options used to configure the output
|
||||
* @param Event $event The event to be output
|
||||
* @return void
|
||||
* @throws LoggingException If an error occurs while handling the event
|
||||
*/
|
||||
public static function handle(Application $application, Event $event): void;
|
||||
}
|
|
@ -4,39 +4,38 @@
|
|||
|
||||
namespace LogLib;
|
||||
|
||||
use ErrorException;
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use LogLib\Abstracts\LevelType;
|
||||
use LogLib\Classes\Console;
|
||||
use LogLib\Classes\Utilities;
|
||||
use LogLib\Enums\LogLevel;
|
||||
use LogLib\Objects\Application;
|
||||
use LogLib\Classes\Validate;
|
||||
use LogLib\Objects\Event;
|
||||
use LogLib\Objects\Options;
|
||||
use LogLib\Objects\RuntimeOptions;
|
||||
use Throwable;
|
||||
|
||||
class Log
|
||||
{
|
||||
/**
|
||||
* @var Application[]|null
|
||||
* @var Options[]|null
|
||||
*/
|
||||
private static $applications;
|
||||
|
||||
/**
|
||||
* @var RuntimeOptions|null
|
||||
*/
|
||||
private static $runtime_options;
|
||||
|
||||
/**
|
||||
* Registers a new application logger
|
||||
*
|
||||
* @param Application $application The options for the application
|
||||
* @param bool $overwrite
|
||||
* @param Options $options The options for the application
|
||||
* @return bool
|
||||
*/
|
||||
public static function register(Application $application, bool $overwrite=false): bool
|
||||
public static function register(Options $options): bool
|
||||
{
|
||||
if(self::isRegistered($application->getApplicationName()))
|
||||
if(self::isRegistered($options->getApplicationName()))
|
||||
{
|
||||
if($overwrite)
|
||||
{
|
||||
self::$applications[$application->getApplicationName()] = $application;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -45,7 +44,7 @@
|
|||
self::$applications = [];
|
||||
}
|
||||
|
||||
self::$applications[$application->getApplicationName()] = $application;
|
||||
self::$applications[$options->getApplicationName()] = $options;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -80,39 +79,56 @@
|
|||
}
|
||||
|
||||
/**
|
||||
* Retrieves the application options. If the application is not registered, it optionally creates and registers a new one.
|
||||
*
|
||||
* @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.
|
||||
* @param string $application
|
||||
* @return Options
|
||||
*/
|
||||
public static function getApplication(string $application, bool $create=true): Application
|
||||
public static function getApplication(string $application): Options
|
||||
{
|
||||
if(!self::isRegistered($application))
|
||||
{
|
||||
if(!$create)
|
||||
{
|
||||
throw new InvalidArgumentException("The application '$application' is not registered");
|
||||
}
|
||||
|
||||
self::register(new Application($application));
|
||||
throw new InvalidArgumentException("The application '$application' is not registered");
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* @param string|null $application_name The name of the application
|
||||
* @param LogLevel $level The level type of the log (default is LevelType::INFO)
|
||||
* @param string $application_name The name of the application
|
||||
* @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, LogLevel $level=LogLevel::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::getApplication($application_name);
|
||||
$application = self::getOptions($application_name);
|
||||
|
||||
if(!Validate::levelType($level))
|
||||
{
|
||||
throw new InvalidArgumentException(sprintf('Invalid level type: %s', $level));
|
||||
}
|
||||
|
||||
if(!Validate::checkLevelType($level, self::getRuntimeOptions()->getLoglevel()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if($message === null)
|
||||
{
|
||||
|
@ -126,14 +142,9 @@
|
|||
$event->setBacktrace(Utilities::getBacktrace());
|
||||
}
|
||||
|
||||
if($application->isConsoleLoggingEnabled())
|
||||
if(self::getRuntimeOptions()->isConsoleOutput())
|
||||
{
|
||||
$application->getConsoleLoggingHandler()::handle($application, $event);
|
||||
}
|
||||
|
||||
if($application->isFileLoggingEnabled())
|
||||
{
|
||||
$application->getFileLoggingHandler()::handle($application, $event);
|
||||
Console::out($application, $event);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -144,7 +155,7 @@
|
|||
*/
|
||||
public static function info(string $application_name, string $message): void
|
||||
{
|
||||
self::log($application_name, LogLevel::INFO, $message);
|
||||
self::log($application_name, LevelType::INFO, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -154,7 +165,7 @@
|
|||
*/
|
||||
public static function verbose(string $application_name, string $message): void
|
||||
{
|
||||
self::log($application_name, LogLevel::VERBOSE, $message);
|
||||
self::log($application_name, LevelType::VERBOSE, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,7 +175,7 @@
|
|||
*/
|
||||
public static function debug(string $application_name, string $message): void
|
||||
{
|
||||
self::log($application_name, LogLevel::DEBUG, $message);
|
||||
self::log($application_name, LevelType::DEBUG, $message);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -177,7 +188,7 @@
|
|||
*/
|
||||
public static function warning(string $application_name, string $message, ?Throwable $throwable=null): void
|
||||
{
|
||||
self::log($application_name, LogLevel::WARNING, $message, $throwable);
|
||||
self::log($application_name, LevelType::WARNING, $message, $throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -187,10 +198,10 @@
|
|||
* @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, LogLevel::ERROR, $message, $throwable);
|
||||
self::log($application_name, LevelType::ERROR, $message, $throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -203,7 +214,7 @@
|
|||
*/
|
||||
public static function fatal(string $application_name, string $message, ?Throwable $throwable=null): void
|
||||
{
|
||||
self::log($application_name, LogLevel::FATAL, $message, $throwable);
|
||||
self::log($application_name, LevelType::FATAL, $message, $throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -213,7 +224,9 @@
|
|||
*/
|
||||
public static function registerExceptionHandler(): void
|
||||
{
|
||||
Runtime::registerExceptionHandler();
|
||||
set_exception_handler(static function(Throwable $throwable) {
|
||||
self::error('Runtime', $throwable->getMessage(), $throwable);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -223,6 +236,22 @@
|
|||
*/
|
||||
public static function unregisterExceptionHandler(): void
|
||||
{
|
||||
Runtime::unregisterExceptionHandler();
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib;
|
||||
|
||||
use LogLib\Objects\Application;
|
||||
use Throwable;
|
||||
|
||||
class Logger extends Application
|
||||
{
|
||||
/**
|
||||
* @inheritDoc
|
||||
*/
|
||||
public function __construct(string $applicationName)
|
||||
{
|
||||
parent::__construct($applicationName);
|
||||
Log::register($this, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an informational message.
|
||||
*
|
||||
* @param string $message The message to log.
|
||||
* @return void
|
||||
*/
|
||||
public function info(string $message): void
|
||||
{
|
||||
Log::info($this->getApplicationName(), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a verbose message with the application name.
|
||||
*
|
||||
* @param string $message The message to be logged.
|
||||
* @return void
|
||||
*/
|
||||
public function verbose(string $message): void
|
||||
{
|
||||
Log::verbose($this->getApplicationName(), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a debug message.
|
||||
*
|
||||
* @param string $message The debug message to log.
|
||||
* @return void
|
||||
*/
|
||||
public function debug(string $message): void
|
||||
{
|
||||
Log::debug($this->getApplicationName(), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a warning message with the application name.
|
||||
*
|
||||
* @param string $message The warning message to log.
|
||||
* @return void
|
||||
*/
|
||||
public function warning(string $message): void
|
||||
{
|
||||
Log::warning($this->getApplicationName(), $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs an error message with an optional throwable instance.
|
||||
*
|
||||
* @param string $message The error message to be logged.
|
||||
* @param Throwable|null $throwable An optional throwable instance to be logged along with the error message.
|
||||
* @return void
|
||||
*/
|
||||
public function error(string $message, ?Throwable $throwable=null): void
|
||||
{
|
||||
Log::error($this->getApplicationName(), $message, $throwable);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logs a fatal error message along with an optional throwable.
|
||||
*
|
||||
* @param string $message The fatal error message to log.
|
||||
* @param Throwable|null $throwable Optional throwable associated with the fatal error.
|
||||
* @return void
|
||||
*/
|
||||
public function fatal(string $message, ?Throwable $throwable=null): void
|
||||
{
|
||||
Log::fatal($this->getApplicationName(), $message, $throwable);
|
||||
}
|
||||
}
|
|
@ -1,248 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Objects;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use LogLib\Classes\Utilities;
|
||||
use LogLib\Enums\LogLevel;
|
||||
use LogLib\Handlers\ConsoleLogging;
|
||||
use LogLib\Handlers\FileLogging;
|
||||
use LogLib\Interfaces\LogHandlerInterface;
|
||||
|
||||
class Application
|
||||
{
|
||||
private string $applicationName;
|
||||
private bool $handleExceptions;
|
||||
private bool $consoleLoggingEnabled;
|
||||
private string $consoleLoggingHandler;
|
||||
private LogLevel $consoleLoggingLevel;
|
||||
private bool $fileLoggingEnabled;
|
||||
private string $fileLoggingHandler;
|
||||
private LogLevel $fileLoggingLevel;
|
||||
private string $fileLoggingDirectory;
|
||||
|
||||
/**
|
||||
* Constructor for initializing the application logging and exception handling.
|
||||
*
|
||||
* @param string $applicationName The name of the application.
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(string $applicationName)
|
||||
{
|
||||
$this->applicationName = $applicationName;
|
||||
$this->handleExceptions = true;
|
||||
$this->consoleLoggingEnabled = Utilities::getConsoleLoggingEnabled();
|
||||
$this->consoleLoggingHandler = ConsoleLogging::class;
|
||||
$this->consoleLoggingLevel = Utilities::getConsoleLoggingLevel();
|
||||
$this->fileLoggingEnabled = Utilities::getFileLoggingEnabled();
|
||||
$this->fileLoggingHandler = FileLogging::class;
|
||||
$this->fileLoggingLevel = Utilities::getFileLoggingLevel();
|
||||
$this->fileLoggingDirectory = Utilities::getFileLoggingDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApplicationName(): string
|
||||
{
|
||||
return $this->applicationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if exceptions are being handled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isHandleExceptions(): bool
|
||||
{
|
||||
return $this->handleExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag to handle exceptions.
|
||||
*
|
||||
* @param bool $handleExceptions Flag indicating whether to handle exceptions.
|
||||
* @return void
|
||||
*/
|
||||
public function setHandleExceptions(bool $handleExceptions): void
|
||||
{
|
||||
$this->handleExceptions = $handleExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if console logging is enabled.
|
||||
*
|
||||
* @return bool True if console logging is enabled, false otherwise.
|
||||
*/
|
||||
public function isConsoleLoggingEnabled(): bool
|
||||
{
|
||||
return $this->consoleLoggingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param bool $consoleLoggingEnabled Indicates whether console logging is enabled.
|
||||
* @return void
|
||||
*/
|
||||
public function setConsoleLoggingEnabled(bool $consoleLoggingEnabled): void
|
||||
{
|
||||
$this->consoleLoggingEnabled = $consoleLoggingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current console logging handler.
|
||||
*
|
||||
* @return LogHandlerInterface|string The console logging handler currently set.
|
||||
*/
|
||||
public function getConsoleLoggingHandler(): LogHandlerInterface|string
|
||||
{
|
||||
return new $this->consoleLoggingHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the console logging handler.
|
||||
*
|
||||
* @param LogHandlerInterface|string $consoleLoggingHandler The console logging handler to set.
|
||||
* @return void
|
||||
*/
|
||||
public function setConsoleLoggingHandler(LogHandlerInterface|string $consoleLoggingHandler): void
|
||||
{
|
||||
if($consoleLoggingHandler instanceof LogHandlerInterface)
|
||||
{
|
||||
$this->consoleLoggingHandler = get_class($consoleLoggingHandler);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!class_exists($consoleLoggingHandler))
|
||||
{
|
||||
throw new InvalidArgumentException("The class $consoleLoggingHandler does not exist.");
|
||||
}
|
||||
|
||||
if(!in_array(LogHandlerInterface::class, class_implements($consoleLoggingHandler)))
|
||||
{
|
||||
throw new InvalidArgumentException("The class $consoleLoggingHandler does not implement LogHandlerInterface.");
|
||||
}
|
||||
|
||||
$this->consoleLoggingHandler = $consoleLoggingHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current console logging level.
|
||||
*
|
||||
* @return LogLevel The current logging level for the console.
|
||||
*/
|
||||
public function getConsoleLoggingLevel(): LogLevel
|
||||
{
|
||||
return $this->consoleLoggingLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logging level for console output.
|
||||
*
|
||||
* @param LogLevel $consoleLoggingLevel The logging level to set for console output.
|
||||
* @return void
|
||||
*/
|
||||
public function setConsoleLoggingLevel(LogLevel $consoleLoggingLevel): void
|
||||
{
|
||||
$this->consoleLoggingLevel = $consoleLoggingLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if file logging is enabled.
|
||||
*
|
||||
* @return bool Returns true if file logging is enabled, false otherwise.
|
||||
*/
|
||||
public function isFileLoggingEnabled(): bool
|
||||
{
|
||||
return $this->fileLoggingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables or disables file logging.
|
||||
*
|
||||
* @param bool $fileLoggingEnabled True to enable file logging, false to disable.
|
||||
* @return void
|
||||
*/
|
||||
public function setFileLoggingEnabled(bool $fileLoggingEnabled): void
|
||||
{
|
||||
$this->fileLoggingEnabled = $fileLoggingEnabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return LogHandlerInterface|string
|
||||
*/
|
||||
public function getFileLoggingHandler(): LogHandlerInterface|string
|
||||
{
|
||||
return $this->fileLoggingHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the file logging handler.
|
||||
*
|
||||
* @param string $fileLoggingHandler The file logging handler to be set.
|
||||
* @return void
|
||||
*/
|
||||
public function setFileLoggingHandler(string $fileLoggingHandler): void
|
||||
{
|
||||
if($fileLoggingHandler instanceof LogHandlerInterface)
|
||||
{
|
||||
$this->consoleLoggingHandler = get_class($fileLoggingHandler);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!class_exists($fileLoggingHandler))
|
||||
{
|
||||
throw new InvalidArgumentException("The class $fileLoggingHandler does not exist.");
|
||||
}
|
||||
|
||||
if(!in_array(LogHandlerInterface::class, class_implements($fileLoggingHandler)))
|
||||
{
|
||||
throw new InvalidArgumentException("The class $fileLoggingHandler does not implement LogHandlerInterface.");
|
||||
}
|
||||
|
||||
$this->consoleLoggingHandler = $fileLoggingHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the logging level for file outputs.
|
||||
*
|
||||
* @return LogLevel The current file logging level.
|
||||
*/
|
||||
public function getFileLoggingLevel(): LogLevel
|
||||
{
|
||||
return $this->fileLoggingLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the logging level for file-based logging.
|
||||
*
|
||||
* @param LogLevel $fileLoggingLevel The logging level to set for file logging.
|
||||
* @return void
|
||||
*/
|
||||
public function setFileLoggingLevel(LogLevel $fileLoggingLevel): void
|
||||
{
|
||||
$this->fileLoggingLevel = $fileLoggingLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the directory path for file logging.
|
||||
*
|
||||
* @return string The directory path where log files are stored.
|
||||
*/
|
||||
public function getFileLoggingDirectory(): string
|
||||
{
|
||||
return $this->fileLoggingDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the directory for file logging.
|
||||
*
|
||||
* @param string $fileLoggingDirectory The path to the directory where log files will be stored.
|
||||
* @return void
|
||||
*/
|
||||
public function setFileLoggingDirectory(string $fileLoggingDirectory): void
|
||||
{
|
||||
$this->fileLoggingDirectory = $fileLoggingDirectory;
|
||||
}
|
||||
}
|
|
@ -4,14 +4,15 @@
|
|||
|
||||
namespace LogLib\Objects;
|
||||
|
||||
use LogLib\Abstracts\LevelType;
|
||||
use LogLib\Classes\Utilities;
|
||||
use LogLib\Enums\LogLevel;
|
||||
use Throwable;
|
||||
|
||||
class Event
|
||||
{
|
||||
/**
|
||||
* @var LogLevel
|
||||
* @see LevelType
|
||||
* @var int
|
||||
*/
|
||||
private $level;
|
||||
|
||||
|
@ -34,11 +35,11 @@
|
|||
* Event constructor.
|
||||
*
|
||||
* @param string $message
|
||||
* @param LogLevel $level
|
||||
* @param int $level
|
||||
* @param Throwable|null $exception
|
||||
* @param array|null $backtrace
|
||||
*/
|
||||
public function __construct(string $message, LogLevel $level, ?Throwable $exception=null, ?array $backtrace=null)
|
||||
public function __construct(string $message, int $level, ?Throwable $exception=null, ?array $backtrace=null)
|
||||
{
|
||||
$this->message = $message;
|
||||
$this->level = $level;
|
||||
|
@ -49,10 +50,10 @@
|
|||
/**
|
||||
* Returns the level of the event
|
||||
*
|
||||
* @return LogLevel
|
||||
* @see LogLevel
|
||||
* @see LevelType
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel(): LogLevel
|
||||
public function getLevel(): int
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
@ -107,4 +108,5 @@
|
|||
{
|
||||
$this->backtrace = $backtrace;
|
||||
}
|
||||
|
||||
}
|
33
src/LogLib/Objects/Options.php
Normal file
33
src/LogLib/Objects/Options.php
Normal file
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace LogLib\Objects;
|
||||
|
||||
|
||||
class Options
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $application_name;
|
||||
|
||||
/**
|
||||
* Options constructor.
|
||||
*/
|
||||
public function __construct(string $application_name)
|
||||
{
|
||||
$this->application_name = $application_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the Application
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getApplicationName(): string
|
||||
{
|
||||
return $this->application_name;
|
||||
}
|
||||
|
||||
}
|
118
src/LogLib/Objects/RuntimeOptions.php
Normal file
118
src/LogLib/Objects/RuntimeOptions.php
Normal file
|
@ -0,0 +1,118 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace LogLib\Objects;
|
||||
|
||||
use LogLib\Abstracts\LevelType;
|
||||
use LogLib\Classes\Utilities;
|
||||
|
||||
class RuntimeOptions
|
||||
{
|
||||
/**
|
||||
* Indicates if the console output is enabled
|
||||
*
|
||||
* @var bool
|
||||
* @property_name console_output
|
||||
*/
|
||||
private $console_output;
|
||||
|
||||
/**
|
||||
* Indicates if ANSI colors should be used in the console output
|
||||
*
|
||||
* @var bool
|
||||
* @property_name display_ansi
|
||||
*/
|
||||
private $display_ansi;
|
||||
|
||||
/**
|
||||
* Indicates if LogLib should handle uncaught exceptions
|
||||
*
|
||||
* @var bool
|
||||
* @property_name handle_exceptions
|
||||
*/
|
||||
private $handle_exceptions;
|
||||
|
||||
/**
|
||||
* The current log level
|
||||
*
|
||||
* @var int
|
||||
* @see LevelType
|
||||
*/
|
||||
private $log_level;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->console_output = Utilities::runningInCli();
|
||||
$this->display_ansi = Utilities::getDisplayAnsi();
|
||||
$this->log_level = Utilities::getLogLevel();
|
||||
$this->handle_exceptions = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isConsoleOutput(): bool
|
||||
{
|
||||
return $this->console_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $console_output
|
||||
*/
|
||||
public function setConsoleOutput(bool $console_output): void
|
||||
{
|
||||
$this->console_output = $console_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function displayAnsi(): bool
|
||||
{
|
||||
return $this->display_ansi;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $display_ansi
|
||||
*/
|
||||
public function setDisplayAnsi(bool $display_ansi): void
|
||||
{
|
||||
$this->display_ansi = $display_ansi;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function handleExceptions(): bool
|
||||
{
|
||||
return $this->handle_exceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $handle_exceptions
|
||||
*/
|
||||
public function setHandleExceptions(bool $handle_exceptions): void
|
||||
{
|
||||
$this->handle_exceptions = $handle_exceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getLoglevel(): int
|
||||
{
|
||||
return $this->log_level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $log_level
|
||||
*/
|
||||
public function setLoglevel(int $log_level): void
|
||||
{
|
||||
$this->log_level = $log_level;
|
||||
}
|
||||
}
|
|
@ -1,124 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib;
|
||||
|
||||
use ErrorException;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
|
||||
class Runtime
|
||||
{
|
||||
/**
|
||||
* Registers an exception handler that logs any uncaught exceptions as errors.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function registerExceptionHandler(): void
|
||||
{
|
||||
set_exception_handler([__CLASS__, 'exceptionHandler']);
|
||||
set_error_handler([__CLASS__, 'errorHandler']);
|
||||
register_shutdown_function([__CLASS__, 'shutdownHandler']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles uncaught exceptions by logging them with a fatal error level.
|
||||
*
|
||||
* @param Throwable $throwable The exception or error that was thrown.
|
||||
* @return void
|
||||
*/
|
||||
public static function exceptionHandler(Throwable $throwable): void
|
||||
{
|
||||
try
|
||||
{
|
||||
Log::Fatal('Runtime', $throwable->getMessage(), $throwable);
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles PHP errors by converting them to exceptions and logging appropriately.
|
||||
*
|
||||
* @param int $errno The level of the error raised.
|
||||
* @param string $errstr The error message.
|
||||
* @param string $errfile The filename that the error was raised in.
|
||||
* @param int $errline The line number the error was raised at.
|
||||
* @return bool True to prevent PHP's internal error handler from being invoked.
|
||||
*/
|
||||
public static function errorHandler(int $errno, string $errstr, string $errfile = '', int $errline = 0): bool
|
||||
{
|
||||
try
|
||||
{
|
||||
// Convert error to exception for consistent handling
|
||||
$exception = new ErrorException($errstr, 0, $errno, $errfile, $errline);
|
||||
|
||||
// Handle different error types
|
||||
switch ($errno)
|
||||
{
|
||||
case E_ERROR:
|
||||
case E_PARSE:
|
||||
case E_CORE_ERROR:
|
||||
case E_COMPILE_ERROR:
|
||||
case E_USER_ERROR:
|
||||
Log::error('Runtime', $errstr, $exception);
|
||||
break;
|
||||
|
||||
case E_USER_DEPRECATED:
|
||||
case E_DEPRECATED:
|
||||
case E_USER_NOTICE:
|
||||
case E_NOTICE:
|
||||
case E_USER_WARNING:
|
||||
case E_WARNING:
|
||||
default:
|
||||
Log::warning('Runtime', $errstr, $exception);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Return true to prevent PHP's internal error handler
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles script shutdown by checking for any fatal errors and logging them.
|
||||
*
|
||||
* This method is designed to be registered with the `register_shutdown_function`,
|
||||
* and it inspects the last error that occurred using `error_get_last`. If a fatal
|
||||
* error is detected, it logs the error details.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function shutdownHandler(): void
|
||||
{
|
||||
$error = error_get_last();
|
||||
|
||||
if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR]))
|
||||
{
|
||||
try
|
||||
{
|
||||
$exception = new ErrorException($error['message'], 0, $error['type'], $error['file'], $error['line']);
|
||||
Log::error('Fatal Error', $error['message'], $exception);
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the currently registered exception handler.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function unregisterExceptionHandler(): void
|
||||
{
|
||||
set_exception_handler(null);
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class LogTest extends TestCase
|
||||
{
|
||||
|
||||
public function testDebug()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testInfo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testGetRuntimeOptions()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testGetOptions()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testGetApplication()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testUnregisterExceptionHandler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testUnregister()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testWarning()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testError()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testFatal()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testRegisterExceptionHandler()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testVerbose()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testRegister()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -1,9 +1,10 @@
|
|||
<?php
|
||||
|
||||
use LogLib\Log;
|
||||
use LogLib\Objects\Options;
|
||||
use LogLib\Abstracts\LevelType;
|
||||
use LogLib\Log;
|
||||
use LogLib\Objects\Options;
|
||||
|
||||
require('ncc');
|
||||
require('ncc');
|
||||
import('net.nosial.loglib', 'latest');
|
||||
|
||||
$options = new Options('net.nosial.optslib');
|
||||
|
|
Loading…
Add table
Reference in a new issue