Various changes
This commit is contained in:
parent
5fabf8df83
commit
1192db4bbf
14 changed files with 64 additions and 437 deletions
3
.idea/php.xml
generated
3
.idea/php.xml
generated
|
@ -13,8 +13,7 @@
|
|||
<include_path>
|
||||
<path value="/usr/share/php" />
|
||||
<path value="/etc/ncc" />
|
||||
<path value="/var/ncc/packages/net.nosial.optslib=1.0.1" />
|
||||
<path value="/var/ncc/packages/net.nosial.properties=1.0.1" />
|
||||
<path value="/var/ncc/packages/net.nosial.optslib=1.0.0" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
||||
|
|
3
Makefile
3
Makefile
|
@ -1,6 +1,3 @@
|
|||
debug:
|
||||
ncc build --config="debug"
|
||||
|
||||
release:
|
||||
ncc build --config="release"
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
abstract class CallType
|
||||
{
|
||||
const MethodCall = '->';
|
||||
|
||||
const StaticCall = '::';
|
||||
|
||||
const FunctionCall = ' ';
|
||||
}
|
|
@ -9,6 +9,7 @@
|
|||
use LogLib\Log;
|
||||
use LogLib\Objects\Event;
|
||||
use LogLib\Objects\Options;
|
||||
use Throwable;
|
||||
|
||||
class Console
|
||||
{
|
||||
|
@ -136,16 +137,18 @@
|
|||
/**
|
||||
* Prints out the exception details
|
||||
*
|
||||
* @param array $exception
|
||||
* @param Throwable $exception
|
||||
* @return void
|
||||
*/
|
||||
private static function outException(array $exception): void
|
||||
private static function outException(Throwable $exception): void
|
||||
{
|
||||
$trace_header = self::color($exception['file'] . ':' . $exception['line'], ConsoleColors::Purple);
|
||||
$trace_header = self::color($exception->getFile() . ':' . $exception->getLine(), ConsoleColors::Purple);
|
||||
$trace_error = self::color('error: ', ConsoleColors::Red);
|
||||
print($trace_header . ' ' . $trace_error . $exception['message'] . PHP_EOL);
|
||||
print(sprintf('Error code: %s', $exception['code']) . PHP_EOL);
|
||||
$trace = $exception['trace'];
|
||||
|
||||
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);
|
||||
|
@ -155,7 +158,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
if($exception['previous'] !== null)
|
||||
if($exception->getPrevious() !== null)
|
||||
{
|
||||
print('Previous Exception:' . PHP_EOL);
|
||||
self::outException($exception['previous']);
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Classes;
|
||||
|
||||
use LogLib\Abstracts\LevelType;
|
||||
use LogLib\Log;
|
||||
use LogLib\Objects\Event;
|
||||
use LogLib\Objects\FileLogging\FileHandle;
|
||||
use LogLib\Objects\Options;
|
||||
use ncc\Utilities\Functions;
|
||||
|
||||
class FileLogging
|
||||
{
|
||||
/**
|
||||
* Writes the event to the file log
|
||||
*
|
||||
* @param Options $options
|
||||
* @param Event $event
|
||||
* @param FileHandle|null $fileHandle
|
||||
* @return void
|
||||
*/
|
||||
public static function out(Options $options, Event $event, ?FileHandle $fileHandle=null): void
|
||||
{
|
||||
$backtrace_output = Utilities::getTraceString($event);
|
||||
$handle = $fileHandle ?? $options->getFileHandle();
|
||||
|
||||
switch($event->Level)
|
||||
{
|
||||
case LevelType::Debug:
|
||||
case LevelType::Verbose:
|
||||
if(!Validate::checkLevelType($event->Level, Log::getRuntimeOptions()->getLogLevel()))
|
||||
return;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$handle->fwrite(sprintf(
|
||||
"%s [%s] [%s] (%s) %s" . PHP_EOL,
|
||||
$event->getTimestamp(),
|
||||
$options->getApplicationName(),
|
||||
Utilities::levelToString($event->Level),
|
||||
$backtrace_output !== null ? $backtrace_output : 'lambda',
|
||||
$event->Message
|
||||
));
|
||||
|
||||
if($event->Exception !== null)
|
||||
self::dumpException($options, $event);
|
||||
|
||||
if($fileHandle == null && Log::getRuntimeOptions()->getOutputLogHandle() !== null)
|
||||
self::out($options, $event, Log::getRuntimeOptions()->getOutputLogHandle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps an exception to a file
|
||||
*
|
||||
* @param Options $options
|
||||
* @param Event $event
|
||||
* @return string|null
|
||||
*/
|
||||
public static function dumpException(Options $options, Event $event): ?string
|
||||
{
|
||||
if($options->dumpExceptionsEnabled() && $options->getPackageDataPath() !== null)
|
||||
return null;
|
||||
|
||||
$exceptions_path = $options->getPackageDataPath() . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . 'exceptions';
|
||||
if(!is_dir($exceptions_path))
|
||||
mkdir($exceptions_path, 0777, true);
|
||||
|
||||
|
||||
$exception_type = str_replace('\\', '_', strtolower($event->Exception['type']));
|
||||
$exception_file = sprintf('%s_%s_%s.json', date('Y-m-d'), $exception_type, Functions::randomString(12));
|
||||
|
||||
$handle = fopen($exception_file, 'w');
|
||||
fwrite($handle, json_encode($event->Exception, JSON_PRETTY_PRINT));
|
||||
fclose($handle);
|
||||
|
||||
return $exception_file;
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
use LogLib\Objects\Backtrace;
|
||||
use LogLib\Objects\Event;
|
||||
use OptsLib\Parse;
|
||||
use Throwable;
|
||||
|
||||
class Utilities
|
||||
{
|
||||
|
@ -135,22 +136,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the output log path from the command line arguments
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getOutputLogPath(): ?string
|
||||
{
|
||||
$args = Parse::getArguments();
|
||||
$path = ($args['log-path'] ?? $args['log-file'] ?? null);
|
||||
|
||||
if($path === null)
|
||||
return null;
|
||||
|
||||
return $path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
|
@ -173,7 +158,7 @@
|
|||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getLogFilename()
|
||||
public static function getLogFilename(): string
|
||||
{
|
||||
return date('Y-m-d') . '.log';
|
||||
}
|
||||
|
@ -223,4 +208,29 @@
|
|||
return "{$class}{$type}{$function}()";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array representation of a throwable exception
|
||||
*
|
||||
* @param Throwable $e
|
||||
* @return array
|
||||
*/
|
||||
public static function exceptionToArray(Throwable $e): array
|
||||
{
|
||||
$trace = $e->getTrace();
|
||||
$trace_string = '';
|
||||
|
||||
foreach($trace as $t)
|
||||
{
|
||||
$trace_string .= "\t{$t['file']}:{$t['line']} {$t['class']}{$t['type']}{$t['function']}()\n";
|
||||
}
|
||||
|
||||
return [
|
||||
'message' => $e->getMessage(),
|
||||
'code' => $e->getCode(),
|
||||
'file' => $e->getFile(),
|
||||
'line' => $e->getLine(),
|
||||
'trace' => $trace_string,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace LogLib\Interfaces;
|
||||
|
||||
use LogLib\Objects\Event;
|
||||
|
||||
interface HandlerInterface
|
||||
{
|
||||
public function handle(Event $event): void;
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
use InvalidArgumentException;
|
||||
use LogLib\Abstracts\LevelType;
|
||||
use LogLib\Classes\Console;
|
||||
use LogLib\Classes\FileLogging;
|
||||
use LogLib\Classes\Utilities;
|
||||
use LogLib\Classes\Validate;
|
||||
use LogLib\Objects\Event;
|
||||
|
@ -17,7 +16,6 @@
|
|||
|
||||
class Log
|
||||
{
|
||||
|
||||
/**
|
||||
* @var Options[]
|
||||
*/
|
||||
|
@ -121,18 +119,6 @@
|
|||
|
||||
if(self::getRuntimeOptions()->isConsoleOutput())
|
||||
Console::out($application, $event);
|
||||
|
||||
if($application->writeToPackageData())
|
||||
FileLogging::out($application, $event);
|
||||
|
||||
foreach($application->getHandlers() as $event_level => $handlers)
|
||||
{
|
||||
if(Validate::checkLevelType($event_level, $level))
|
||||
{
|
||||
foreach($handlers as $handler)
|
||||
$handler->handle($event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,7 +192,7 @@
|
|||
public static function registerExceptionHandler(): void
|
||||
{
|
||||
set_exception_handler(function(Throwable $throwable) {
|
||||
self::error('Exception', $throwable->getMessage(), $throwable);
|
||||
self::error('Runtime', $throwable->getMessage(), $throwable);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
* The Unix Timestamp of when the event was created
|
||||
*
|
||||
* @var string
|
||||
* @property_name timestamp
|
||||
*/
|
||||
private $Timestamp;
|
||||
|
||||
|
@ -30,15 +29,13 @@
|
|||
* An array of backtraces, if any, that were created when the event was created
|
||||
*
|
||||
* @var Backtrace[]|null
|
||||
* @property_name backtrace
|
||||
*/
|
||||
private $Backtrace;
|
||||
|
||||
/**
|
||||
* The exception that was thrown, if any
|
||||
*
|
||||
* @var array|null
|
||||
* @property_name exception
|
||||
* @var Throwable|null
|
||||
*/
|
||||
public $Exception;
|
||||
|
||||
|
@ -46,10 +43,12 @@
|
|||
* The message of the event
|
||||
*
|
||||
* @var string
|
||||
* @property_name message
|
||||
*/
|
||||
public $Message;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->Timestamp = date('c');
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
<?php
|
||||
|
||||
/** @noinspection PhpMissingFieldTypeInspection */
|
||||
|
||||
namespace LogLib\Objects\FileLogging;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use LogLib\Classes\Utilities;
|
||||
|
||||
class FileHandle
|
||||
{
|
||||
/**
|
||||
* The file handle of the file
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
private $resource;
|
||||
|
||||
/**
|
||||
* The current out path where all the logs are being written to
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $path;
|
||||
|
||||
/**
|
||||
* The current file path of the log file
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $current_file;
|
||||
|
||||
/**
|
||||
* Public constructor
|
||||
*
|
||||
* @param string $path
|
||||
*/
|
||||
public function __construct(string $path)
|
||||
{
|
||||
if(is_writable($path) === false)
|
||||
throw new InvalidArgumentException(sprintf('The path "%s" is not writable', $path));
|
||||
|
||||
$this->path = $path . DIRECTORY_SEPARATOR . 'logs';
|
||||
$this->current_file = Utilities::getLogFilename();
|
||||
|
||||
if(!file_exists($this->current_file))
|
||||
{
|
||||
touch($this->current_file);
|
||||
chmod($this->current_file, 0777);
|
||||
}
|
||||
|
||||
$this->resource = fopen($this->path . DIRECTORY_SEPARATOR . $this->current_file, 'a');
|
||||
|
||||
if(!is_dir($this->path))
|
||||
mkdir($this->path, 0777, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes to the file
|
||||
*
|
||||
* @param string $string
|
||||
* @return int
|
||||
*/
|
||||
public function fwrite(string $string): int
|
||||
{
|
||||
$current_file = Utilities::getLogFilename();
|
||||
|
||||
if ($current_file !== $this->current_file)
|
||||
{
|
||||
fclose($this->resource);
|
||||
$this->current_file = $current_file;
|
||||
if(!file_exists($this->current_file))
|
||||
{
|
||||
touch($this->current_file);
|
||||
chmod($this->current_file, 0777);
|
||||
}
|
||||
|
||||
$this->resource = fopen($this->current_file, 'a');
|
||||
}
|
||||
|
||||
return fwrite($this->resource, $string);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the file handle
|
||||
*/
|
||||
public function __destruct()
|
||||
{
|
||||
fclose($this->resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|resource
|
||||
*/
|
||||
public function resource()
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
}
|
|
@ -4,14 +4,6 @@
|
|||
|
||||
namespace LogLib\Objects;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use LogLib\Classes\Validate;
|
||||
use LogLib\Interfaces\HandlerInterface;
|
||||
use LogLib\Objects\FileLogging\FileHandle;
|
||||
use ncc\Exceptions\InvalidPackageNameException;
|
||||
use ncc\Exceptions\InvalidScopeException;
|
||||
use ncc\Exceptions\PackageLockException;
|
||||
use ncc\Managers\PackageLockManager;
|
||||
|
||||
class Options
|
||||
{
|
||||
|
@ -23,126 +15,12 @@
|
|||
*/
|
||||
private $ApplicationName;
|
||||
|
||||
/**
|
||||
* Writes the log to a file located at the package data path provided by NCC's API
|
||||
* under a "logs" directory.
|
||||
*
|
||||
* @var bool
|
||||
* @property_name write_to_package_data
|
||||
*/
|
||||
private $WriteToPackageData;
|
||||
|
||||
/**
|
||||
* An array of handlers that wil be used to handle the log events
|
||||
* if applications want to handle the log events themselves.
|
||||
*
|
||||
* @var HandlerInterface[]
|
||||
*/
|
||||
private $Handlers;
|
||||
|
||||
/**
|
||||
* The file handle to write the log to if WriteToPackageData is true
|
||||
*
|
||||
* @var FileHandle|null
|
||||
*/
|
||||
private $FileHandle;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
private $PackageDataPath;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $DumpExceptions;
|
||||
|
||||
/**
|
||||
* Options constructor.
|
||||
*/
|
||||
public function __construct(string $application_name)
|
||||
{
|
||||
$this->ApplicationName = $application_name;
|
||||
$this->WriteToPackageData = false;
|
||||
$this->DumpExceptions = false;
|
||||
$this->Handlers = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function writeToPackageData(): bool
|
||||
{
|
||||
return $this->WriteToPackageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables the writing of the log to a file located at the package data path provided by NCC's API
|
||||
*
|
||||
* @return void
|
||||
* @throws InvalidPackageNameException
|
||||
* @throws InvalidScopeException
|
||||
* @throws PackageLockException
|
||||
*/
|
||||
public function enableWriteToPackageData(): void
|
||||
{
|
||||
if($this->WriteToPackageData)
|
||||
return;
|
||||
|
||||
$package_lock = new PackageLockManager();
|
||||
$package = $package_lock->getPackageLock()->getPackage($this->ApplicationName);
|
||||
if($package == null)
|
||||
throw new InvalidArgumentException("The package data path could not be found for the package '{$this->ApplicationName}'");
|
||||
|
||||
$this->WriteToPackageData = true;
|
||||
$this->PackageDataPath = $package->getDataPath();
|
||||
if($this->FileHandle !== null)
|
||||
unset($this->FileHandle);
|
||||
|
||||
$this->FileHandle = new FileHandle($this->PackageDataPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables the writing of the log to the package data path
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function disableWriteToPackageData(): void
|
||||
{
|
||||
$this->WriteToPackageData = false;
|
||||
$this->PackageDataPath = null;
|
||||
unset($this->FileHandle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return HandlerInterface[]
|
||||
*/
|
||||
public function getHandlers(): array
|
||||
{
|
||||
return $this->Handlers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $level
|
||||
* @param HandlerInterface $handler
|
||||
*/
|
||||
public function setHandler(string $level, HandlerInterface $handler): void
|
||||
{
|
||||
if(!Validate::LevelType($level))
|
||||
throw new InvalidArgumentException("Invalid level provided");
|
||||
|
||||
if(!isset($this->Handlers[$level]))
|
||||
$this->Handlers[$level] = [];
|
||||
|
||||
$this->Handlers[$level][] = $handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function clearHandlers(): void
|
||||
{
|
||||
$this->Handlers = [];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -155,43 +33,4 @@
|
|||
return $this->ApplicationName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates if exceptions should be dumped to a file
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function dumpExceptionsEnabled(): bool
|
||||
{
|
||||
return $this->DumpExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables/Disables the dumping of exceptions to the /exceptions folder of the package data path
|
||||
* WriteToPackageData must be enabled for this to work properly
|
||||
*
|
||||
* @param bool $DumpExceptions
|
||||
*/
|
||||
public function setDumpExceptions(bool $DumpExceptions): void
|
||||
{
|
||||
if(!$this->WriteToPackageData)
|
||||
throw new InvalidArgumentException('Cannot dump exceptions if WriteToPackageData is disabled');
|
||||
$this->DumpExceptions = $DumpExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return FileHandle|null
|
||||
*/
|
||||
public function getFileHandle(): ?FileHandle
|
||||
{
|
||||
return $this->FileHandle;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function getPackageDataPath(): ?string
|
||||
{
|
||||
return $this->PackageDataPath;
|
||||
}
|
||||
|
||||
}
|
|
@ -7,7 +7,6 @@
|
|||
use InvalidArgumentException;
|
||||
use LogLib\Abstracts\LevelType;
|
||||
use LogLib\Classes\Utilities;
|
||||
use LogLib\Objects\FileLogging\FileHandle;
|
||||
|
||||
class RuntimeOptions
|
||||
{
|
||||
|
@ -35,14 +34,6 @@
|
|||
*/
|
||||
private $HandleExceptions;
|
||||
|
||||
/**
|
||||
* Optional. The file to write the log to.
|
||||
*
|
||||
* @var string|null
|
||||
* @property_name output_log
|
||||
*/
|
||||
private $OutputLog;
|
||||
|
||||
/**
|
||||
* The current log level
|
||||
*
|
||||
|
@ -51,11 +42,6 @@
|
|||
*/
|
||||
private $LogLevel;
|
||||
|
||||
/**
|
||||
* @var FileHandle
|
||||
*/
|
||||
private $OutputLogHandle;
|
||||
|
||||
/**
|
||||
* Public Constructor
|
||||
*/
|
||||
|
@ -64,7 +50,6 @@
|
|||
$this->ConsoleOutput = Utilities::runningInCli();
|
||||
$this->DisplayAnsi = Utilities::getDisplayAnsi();
|
||||
$this->HandleExceptions = true;
|
||||
$this->OutputLog = Utilities::getOutputLogPath();
|
||||
$this->LogLevel = Utilities::getLogLevel();
|
||||
}
|
||||
|
||||
|
@ -131,23 +116,4 @@
|
|||
{
|
||||
$this->LogLevel = $LogLevel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ?FileHandle
|
||||
*/
|
||||
public function getOutputLogHandle(): ?FileHandle
|
||||
{
|
||||
if($this->OutputLogHandle == null)
|
||||
{
|
||||
if($this->OutputLog == null)
|
||||
return null;
|
||||
|
||||
if(is_writable($this->OutputLog) === false)
|
||||
throw new InvalidArgumentException(sprintf('The path "%s" is not writable', $this->OutputLog));
|
||||
|
||||
$this->OutputLogHandle = new FileHandle($this->OutputLog);
|
||||
}
|
||||
|
||||
return $this->OutputLogHandle;
|
||||
}
|
||||
}
|
21
tests/exception_handling.php
Normal file
21
tests/exception_handling.php
Normal file
|
@ -0,0 +1,21 @@
|
|||
<?php
|
||||
|
||||
use LogLib\Abstracts\LevelType;
|
||||
use LogLib\Log;
|
||||
use LogLib\Objects\Options;
|
||||
|
||||
require('ncc');
|
||||
import('net.nosial.loglib', 'latest');
|
||||
|
||||
$options = new Options('net.nosial.optslib');
|
||||
Log::register($options);
|
||||
Log::registerExceptionHandler();
|
||||
|
||||
Log::debug('net.nosial.optslib', 'This is a debug message');
|
||||
Log::verbose('net.nosial.optslib', 'This is a verbose message');
|
||||
Log::info('net.nosial.optslib', 'This is an info message');
|
||||
Log::warning('net.nosial.optslib', 'This is a warning message');
|
||||
Log::error('net.nosial.optslib', 'This is an error message');
|
||||
Log::fatal('net.nosial.optslib', 'This is a fatal message');
|
||||
|
||||
throw new Exception('This is an exception');
|
|
@ -8,7 +8,6 @@
|
|||
import('net.nosial.loglib', 'latest');
|
||||
|
||||
$options = new Options('net.nosial.optslib');
|
||||
$options->enableWriteToPackageData();
|
||||
Log::register($options);
|
||||
|
||||
Log::debug('net.nosial.optslib', 'This is a debug message');
|
||||
|
|
Loading…
Add table
Reference in a new issue