Refactored Project, various changes and bug fixes. Implemented file logging
This commit is contained in:
parent
55ec27903f
commit
09141f3d10
16 changed files with 1007 additions and 316 deletions
4
.idea/php.xml
generated
4
.idea/php.xml
generated
|
@ -11,8 +11,10 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpIncludePathManager">
|
<component name="PhpIncludePathManager">
|
||||||
<include_path>
|
<include_path>
|
||||||
|
<path value="/usr/share/php" />
|
||||||
<path value="/etc/ncc" />
|
<path value="/etc/ncc" />
|
||||||
<path value="/var/ncc/packages/net.nosial.optslib=1.0.0" />
|
<path value="/var/ncc/packages/net.nosial.optslib=1.0.1" />
|
||||||
|
<path value="/var/ncc/packages/net.nosial.properties=1.0.1" />
|
||||||
</include_path>
|
</include_path>
|
||||||
</component>
|
</component>
|
||||||
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
<component name="PhpProjectSharedConfiguration" php_language_level="8.2" />
|
||||||
|
|
4
Makefile
4
Makefile
|
@ -5,10 +5,10 @@ release:
|
||||||
ncc build --config="release"
|
ncc build --config="release"
|
||||||
|
|
||||||
install:
|
install:
|
||||||
ncc package install --package="build/release/net.nosial.loglib.ncc"
|
ncc package install --package="build/release/net.nosial.loglib.ncc" --skip-dependencies --reinstall -y
|
||||||
|
|
||||||
install-debug:
|
install-debug:
|
||||||
ncc package install --package="build/debug/net.nosial.loglib.ncc"
|
ncc package install --package="build/debug/net.nosial.loglib.ncc" --skip-dependencies --reinstall -y
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
ncc package uninstall -y --package="net.nosial.loglib"
|
ncc package uninstall -y --package="net.nosial.loglib"
|
28
README.md
28
README.md
|
@ -1,3 +1,29 @@
|
||||||
# LogLib
|
# LogLib
|
||||||
|
|
||||||
A logging library for PHP.
|
A logging library for PHP/ncc, this was quickly thrown together
|
||||||
|
to provide a simple logging interface and to test out
|
||||||
|
NCC's capabilities for PHP.
|
||||||
|
|
||||||
|
## Getting started
|
||||||
|
|
||||||
|
First
|
||||||
|
|
||||||
|
|
||||||
|
### building
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ git clone https://git.n64.cc/nosial/libs/loglib.git
|
||||||
|
$ cd loglib
|
||||||
|
|
||||||
|
$ ncc build --config release
|
||||||
|
# or
|
||||||
|
$ make release
|
||||||
|
```
|
||||||
|
|
||||||
|
### installing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
$ sudo ncc install -p="build/release/net.nosial.loglib.ncc"
|
||||||
|
# or
|
||||||
|
$ sudo make install
|
||||||
|
```
|
23
project.json
23
project.json
|
@ -5,6 +5,15 @@
|
||||||
"minimum_version": "8.0",
|
"minimum_version": "8.0",
|
||||||
"maximum_version": "8.2"
|
"maximum_version": "8.2"
|
||||||
},
|
},
|
||||||
|
"update_source": {
|
||||||
|
"source": "nosial/libs.log@n64",
|
||||||
|
"repository": {
|
||||||
|
"name": "n64",
|
||||||
|
"type": "gitlab",
|
||||||
|
"host": "git.n64.cc",
|
||||||
|
"ssl": true
|
||||||
|
}
|
||||||
|
},
|
||||||
"options": []
|
"options": []
|
||||||
},
|
},
|
||||||
"assembly": {
|
"assembly": {
|
||||||
|
@ -24,6 +33,20 @@
|
||||||
"ASSEMBLY_VERSION": "%ASSEMBLY.VERSION%",
|
"ASSEMBLY_VERSION": "%ASSEMBLY.VERSION%",
|
||||||
"ASSEMBLY_UID": "%ASSEMBLY.UID%"
|
"ASSEMBLY_UID": "%ASSEMBLY.UID%"
|
||||||
},
|
},
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"name": "net.nosial.optslib",
|
||||||
|
"version": "latest",
|
||||||
|
"source_type": "remote",
|
||||||
|
"source": "nosial/libs.opts=latest@n64"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "net.nosial.properties",
|
||||||
|
"version": "latest",
|
||||||
|
"source_type": "remote",
|
||||||
|
"source": "nosial/libs.properties=latest@n64"
|
||||||
|
}
|
||||||
|
],
|
||||||
"configurations": [
|
"configurations": [
|
||||||
{
|
{
|
||||||
"name": "debug",
|
"name": "debug",
|
||||||
|
|
|
@ -40,4 +40,15 @@
|
||||||
self::LightGray,
|
self::LightGray,
|
||||||
self::White
|
self::White
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A list of random usable bright colors
|
||||||
|
*/
|
||||||
|
const BrightColors = [
|
||||||
|
self::LightBlue,
|
||||||
|
self::LightGreen,
|
||||||
|
self::LightCyan,
|
||||||
|
self::LightRed,
|
||||||
|
self::LightPurple,
|
||||||
|
];
|
||||||
}
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
use LogLib\Abstracts\ConsoleColors;
|
use LogLib\Abstracts\ConsoleColors;
|
||||||
use LogLib\Abstracts\LevelType;
|
use LogLib\Abstracts\LevelType;
|
||||||
|
use LogLib\Log;
|
||||||
use LogLib\Objects\Event;
|
use LogLib\Objects\Event;
|
||||||
use LogLib\Objects\Options;
|
use LogLib\Objects\Options;
|
||||||
|
|
||||||
|
@ -24,13 +25,17 @@
|
||||||
*/
|
*/
|
||||||
private static function formatAppColor(string $application): string
|
private static function formatAppColor(string $application): string
|
||||||
{
|
{
|
||||||
|
if(!Log::getRuntimeOptions()->isDisplayAnsi())
|
||||||
|
return $application;
|
||||||
|
|
||||||
if(!isset(self::$ApplicationColors[$application]))
|
if(!isset(self::$ApplicationColors[$application]))
|
||||||
{
|
{
|
||||||
$colors = ConsoleColors::All;
|
$colors = ConsoleColors::BrightColors;
|
||||||
$color = $colors[array_rand($colors)];
|
$color = $colors[array_rand($colors)];
|
||||||
self::$ApplicationColors[$application] = $color;
|
self::$ApplicationColors[$application] = $color;
|
||||||
}
|
}
|
||||||
return self::$ApplicationColors[$application];
|
|
||||||
|
return self::color($application, self::$ApplicationColors[$application]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,7 +47,10 @@
|
||||||
*/
|
*/
|
||||||
private static function color(string $text, string $color): string
|
private static function color(string $text, string $color): string
|
||||||
{
|
{
|
||||||
return "\033[{$color}m$text\033[0m";
|
if(!Log::getRuntimeOptions()->isDisplayAnsi())
|
||||||
|
return $text;
|
||||||
|
|
||||||
|
return "\033[" . $color . "m" . $text . "\033[0m";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,6 +62,9 @@
|
||||||
*/
|
*/
|
||||||
private static function colorize(Event $event, string $text): string
|
private static function colorize(Event $event, string $text): string
|
||||||
{
|
{
|
||||||
|
if(!Log::getRuntimeOptions()->isDisplayAnsi())
|
||||||
|
return Utilities::levelToString($text);
|
||||||
|
|
||||||
$color = null;
|
$color = null;
|
||||||
switch($event->Level)
|
switch($event->Level)
|
||||||
{
|
{
|
||||||
|
@ -83,46 +94,6 @@
|
||||||
return self::color(Utilities::levelToString($text), $color);
|
return self::color(Utilities::levelToString($text), $color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the formatted backtrace
|
|
||||||
*
|
|
||||||
* @param Event $event
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
private static function parseBacktrace(Event $event): ?string
|
|
||||||
{
|
|
||||||
$backtrace = null;
|
|
||||||
if($event->Backtrace !== null && count($event->Backtrace) > 0)
|
|
||||||
{
|
|
||||||
foreach($event->Backtrace as $item)
|
|
||||||
{
|
|
||||||
if($item->Class !== 'LogLib\\Log')
|
|
||||||
{
|
|
||||||
$backtrace = $item;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$backtrace_output = null;
|
|
||||||
if($backtrace !== null)
|
|
||||||
{
|
|
||||||
if($backtrace->Class !== null)
|
|
||||||
{
|
|
||||||
$backtrace_output = $backtrace->Class . $backtrace->Type . $backtrace->Function . '()';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$backtrace_output = $backtrace->Function . '()';
|
|
||||||
}
|
|
||||||
|
|
||||||
if($backtrace->Line !== null)
|
|
||||||
$backtrace_output .= ':' . $backtrace->Line;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $backtrace_output;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regular console output for the event object
|
* Regular console output for the event object
|
||||||
*
|
*
|
||||||
|
@ -132,61 +103,35 @@
|
||||||
*/
|
*/
|
||||||
public static function out(Options $options, Event $event): void
|
public static function out(Options $options, Event $event): void
|
||||||
{
|
{
|
||||||
// If the current level is verbose or higher, then we need to output the backtrace
|
if(!Utilities::runningInCli())
|
||||||
if(Validate::checkLevelType(LevelType::Verbose, $options->getOutputLevel()))
|
return;
|
||||||
{
|
|
||||||
$backtrace_output = self::parseBacktrace($event);
|
|
||||||
|
|
||||||
if($options->isConsoleAnsiColors())
|
if(Validate::checkLevelType(LevelType::Verbose, Log::getRuntimeOptions()->getLogLevel()))
|
||||||
{
|
{
|
||||||
print(sprintf(
|
$backtrace_output = Utilities::parseBacktrace($event);
|
||||||
"%s [%s] [%s] (%s) - %s" . PHP_EOL,
|
|
||||||
$event->getTimestamp(),
|
print(sprintf(
|
||||||
self::formatAppColor($options->getApplicationName()),
|
"%s [%s] [%s] (%s) - %s" . PHP_EOL,
|
||||||
self::colorize($event, $event->Level),
|
$event->getTimestamp(),
|
||||||
$backtrace_output !== null ? $backtrace_output : 'λ',
|
self::formatAppColor($options->getApplicationName()),
|
||||||
$event->Message
|
self::colorize($event, $event->Level),
|
||||||
));
|
$backtrace_output !== null ? $backtrace_output : 'λ',
|
||||||
}
|
$event->Message
|
||||||
else
|
));
|
||||||
{
|
|
||||||
print(sprintf(
|
|
||||||
"%s [%s] [%s] - %s - %s" . PHP_EOL,
|
|
||||||
$event->getTimestamp(), $options->getApplicationName(), $event->Level,
|
|
||||||
$backtrace_output !== null ? $backtrace_output : 'lambda',
|
|
||||||
$event->Message
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if($event->Exception !== null)
|
if($event->Exception !== null)
|
||||||
self::outException($event->Exception);
|
self::outException($event->Exception);
|
||||||
}
|
|
||||||
elseif(!Validate::checkLevelType(LevelType::Fatal, $options->getOutputLevel()))
|
|
||||||
{
|
|
||||||
if($options->isConsoleAnsiColors())
|
|
||||||
{
|
|
||||||
print(sprintf(
|
|
||||||
"%s [%s] [%s] - %s" . PHP_EOL,
|
|
||||||
$event->getTimestamp(),
|
|
||||||
self::formatAppColor($options->getApplicationName()),
|
|
||||||
self::colorize($event, $event->Level),
|
|
||||||
$event->Message
|
|
||||||
));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
print(sprintf(
|
|
||||||
"%s [%s] [%s] - %s" . PHP_EOL,
|
|
||||||
$event->getTimestamp(), $options->getApplicationName(), $event->Level,
|
|
||||||
$event->Message
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
if($event->Exception !== null)
|
return;
|
||||||
self::outException($event->Exception);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print(sprintf(
|
||||||
|
"%s [%s] [%s] - %s" . PHP_EOL,
|
||||||
|
$event->getTimestamp(),
|
||||||
|
self::formatAppColor($options->getApplicationName()),
|
||||||
|
self::colorize($event, $event->Level),
|
||||||
|
$event->Message
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
84
src/LogLib/Classes/FileLogging.php
Normal file
84
src/LogLib/Classes/FileLogging.php
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
<?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::parseBacktrace($event);
|
||||||
|
$handle = $fileHandle ?? $options->getFileHandle();
|
||||||
|
|
||||||
|
switch($event->Level)
|
||||||
|
{
|
||||||
|
// Only process Debug/Verbose events if the log level is set to Debug/Verbose
|
||||||
|
// otherwise omit it because it could be a performance hit if there are a lot of
|
||||||
|
// debug/verbose events being logged.
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
use LogLib\Abstracts\LevelType;
|
use LogLib\Abstracts\LevelType;
|
||||||
use LogLib\Objects\Backtrace;
|
use LogLib\Objects\Backtrace;
|
||||||
|
use LogLib\Objects\Event;
|
||||||
|
use OptsLib\Parse;
|
||||||
|
use Properties\Prop;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
||||||
class Utilities
|
class Utilities
|
||||||
|
@ -23,7 +26,7 @@
|
||||||
|
|
||||||
foreach($backtrace as $trace)
|
foreach($backtrace as $trace)
|
||||||
{
|
{
|
||||||
$results[] = Backtrace::fromArray($trace);
|
$results[] = Prop::fromArray($trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $results;
|
return $results;
|
||||||
|
@ -36,6 +39,8 @@
|
||||||
public static function exceptionToArray(Throwable $e): array
|
public static function exceptionToArray(Throwable $e): array
|
||||||
{
|
{
|
||||||
$results = [
|
$results = [
|
||||||
|
'hash' => spl_object_hash($e),
|
||||||
|
'type' => get_class($e),
|
||||||
'message' => $e->getMessage(),
|
'message' => $e->getMessage(),
|
||||||
'code' => $e->getCode(),
|
'code' => $e->getCode(),
|
||||||
'file' => $e->getFile(),
|
'file' => $e->getFile(),
|
||||||
|
@ -71,4 +76,188 @@
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple method to determine if the current environment is a CLI environment
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function runningInCli(): bool
|
||||||
|
{
|
||||||
|
if(function_exists('php_sapi_name'))
|
||||||
|
{
|
||||||
|
return strtolower(php_sapi_name()) === 'cli';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(defined('PHP_SAPI'))
|
||||||
|
{
|
||||||
|
return strtolower(PHP_SAPI) === 'cli';
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempts to determine the current log level from the command line arguments
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public static function getLogLevel(): int
|
||||||
|
{
|
||||||
|
$args = Parse::getArguments();
|
||||||
|
|
||||||
|
$selected_level = ($args['log'] ?? $args['log-level'] ?? null);
|
||||||
|
|
||||||
|
if($selected_level === null)
|
||||||
|
return LevelType::Info;
|
||||||
|
|
||||||
|
switch(strtolower($selected_level))
|
||||||
|
{
|
||||||
|
case LevelType::Debug:
|
||||||
|
case 'debug':
|
||||||
|
case '6':
|
||||||
|
case 'dbg':
|
||||||
|
return LevelType::Debug;
|
||||||
|
|
||||||
|
case LevelType::Verbose:
|
||||||
|
case 'verbose':
|
||||||
|
case '5':
|
||||||
|
case 'vrb':
|
||||||
|
return LevelType::Verbose;
|
||||||
|
|
||||||
|
case LevelType::Info:
|
||||||
|
case 'info':
|
||||||
|
case '4':
|
||||||
|
case 'inf':
|
||||||
|
return LevelType::Info;
|
||||||
|
|
||||||
|
case LevelType::Warning:
|
||||||
|
case 'warning':
|
||||||
|
case '3':
|
||||||
|
case 'wrn':
|
||||||
|
return LevelType::Warning;
|
||||||
|
|
||||||
|
case LevelType::Error:
|
||||||
|
case 'error':
|
||||||
|
case '2':
|
||||||
|
case 'err':
|
||||||
|
return LevelType::Error;
|
||||||
|
|
||||||
|
case LevelType::Fatal:
|
||||||
|
case 'fatal':
|
||||||
|
case '1':
|
||||||
|
case 'crt':
|
||||||
|
return LevelType::Fatal;
|
||||||
|
|
||||||
|
case LevelType::Silent:
|
||||||
|
case 'silent':
|
||||||
|
case '0':
|
||||||
|
case 'sil':
|
||||||
|
return LevelType::Silent;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return LevelType::Info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
public static function getDisplayAnsi(): bool
|
||||||
|
{
|
||||||
|
$args = Parse::getArguments();
|
||||||
|
$display_ansi = ($args['display-ansi'] ?? $args['ansi'] ?? null);
|
||||||
|
|
||||||
|
if($display_ansi === null)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
// Strict boolean response
|
||||||
|
return strtolower($display_ansi) === 'true' || $display_ansi === '1';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current active log file name, the current value can
|
||||||
|
* change depending on the date/time, if it has changed; close the
|
||||||
|
* old file and open a new one.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getLogFilename()
|
||||||
|
{
|
||||||
|
return date('Y-m-d') . '.log';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the formatted backtrace
|
||||||
|
*
|
||||||
|
* @param Event $event
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public static function parseBacktrace(Event $event): ?string
|
||||||
|
{
|
||||||
|
$backtrace = null;
|
||||||
|
if ($event->Backtrace !== null && count($event->Backtrace) > 0)
|
||||||
|
{
|
||||||
|
foreach ($event->Backtrace as $item)
|
||||||
|
{
|
||||||
|
if ($item->Class !== 'LogLib\\Log')
|
||||||
|
{
|
||||||
|
$backtrace = $item;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$backtrace_output = null;
|
||||||
|
if ($backtrace !== null)
|
||||||
|
{
|
||||||
|
if ($backtrace->Class !== null)
|
||||||
|
{
|
||||||
|
$backtrace_output = $backtrace->Class . $backtrace->Type . $backtrace->Function . '()';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$backtrace_output = $backtrace->Function . '()';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($backtrace->Line !== null)
|
||||||
|
$backtrace_output .= ':' . $backtrace->Line;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $backtrace_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a random string of characters
|
||||||
|
*
|
||||||
|
* @param int $length
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function randomString(int $length = 32): string
|
||||||
|
{
|
||||||
|
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
$charactersLength = strlen($characters);
|
||||||
|
$randomString = '';
|
||||||
|
for ($i = 0; $i < $length; $i++)
|
||||||
|
{
|
||||||
|
$randomString .= $characters[rand(0, $charactersLength - 1)];
|
||||||
|
}
|
||||||
|
return $randomString;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
21
src/LogLib/Exceptions/ConfigurationException.php
Normal file
21
src/LogLib/Exceptions/ConfigurationException.php
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace LogLib\Exceptions;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class ConfigurationException extends Exception
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param string $message
|
||||||
|
* @param int $code
|
||||||
|
* @param Throwable|null $previous
|
||||||
|
*/
|
||||||
|
public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null)
|
||||||
|
{
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
$this->message = $message;
|
||||||
|
$this->code = $code;
|
||||||
|
}
|
||||||
|
}
|
231
src/LogLib/Log.php
Normal file
231
src/LogLib/Log.php
Normal file
|
@ -0,0 +1,231 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
|
namespace LogLib;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use LogLib\Abstracts\LevelType;
|
||||||
|
use LogLib\Classes\Console;
|
||||||
|
use LogLib\Classes\FileLogging;
|
||||||
|
use LogLib\Classes\Validate;
|
||||||
|
use LogLib\Objects\Event;
|
||||||
|
use LogLib\Objects\Options;
|
||||||
|
use LogLib\Objects\RuntimeOptions;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
class Log
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var Options[]
|
||||||
|
*/
|
||||||
|
private static $Applications;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var RuntimeOptions
|
||||||
|
*/
|
||||||
|
private static $RuntimeOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new application logger
|
||||||
|
*
|
||||||
|
* @param Options $options The options for the application
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function register(Options $options): bool
|
||||||
|
{
|
||||||
|
if(self::isRegistered($options->getApplicationName()))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
self::$Applications[$options->getApplicationName()] = $options;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a registered application logger
|
||||||
|
*
|
||||||
|
* @param string $application The name of the application
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function unregister(string $application): void
|
||||||
|
{
|
||||||
|
if(isset(self::$Applications[$application]))
|
||||||
|
unset(self::$Applications[$application]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the given application is registered
|
||||||
|
*
|
||||||
|
* @param string $application
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
private static function isRegistered(string $application): bool
|
||||||
|
{
|
||||||
|
return isset(self::$Applications[$application]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $application
|
||||||
|
* @return Options
|
||||||
|
*/
|
||||||
|
public static function getApplication(string $application): Options
|
||||||
|
{
|
||||||
|
if(!self::isRegistered($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];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $application_name The name of the application
|
||||||
|
* @param string $level The level of the event
|
||||||
|
* @param string|null $message The message of the event
|
||||||
|
* @param Throwable|null $throwable The exception that was thrown, if any
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
private static function log(string $application_name, string $level=LevelType::Info, ?string $message=null, ?Throwable $throwable=null): void
|
||||||
|
{
|
||||||
|
$application = self::getOptions($application_name);
|
||||||
|
|
||||||
|
if(!Validate::checkLevelType($level, self::getRuntimeOptions()->getLogLevel()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if($message == null)
|
||||||
|
throw new InvalidArgumentException('Message cannot be null');
|
||||||
|
if($level == null || !Validate::levelType($level))
|
||||||
|
throw new InvalidArgumentException('Invalid logging level');
|
||||||
|
|
||||||
|
$event = new Event();
|
||||||
|
$event->Level = $level;
|
||||||
|
$event->Message = $message;
|
||||||
|
$event->Exception = $throwable;
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $application_name The name of the application
|
||||||
|
* @param string $message The message of the event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function info(string $application_name, string $message): void
|
||||||
|
{
|
||||||
|
self::log($application_name, LevelType::Info, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $application_name The name of the application
|
||||||
|
* @param string $message The message of the event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function verbose(string $application_name, string $message): void
|
||||||
|
{
|
||||||
|
self::log($application_name, LevelType::Verbose, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $application_name The name of the application
|
||||||
|
* @param string $message The message of the event
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function debug(string $application_name, string $message): void
|
||||||
|
{
|
||||||
|
self::log($application_name, LevelType::Debug, $message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $application_name The name of the application
|
||||||
|
* @param string $message The message of the event
|
||||||
|
* @param Throwable|null $throwable The exception that was thrown, if any
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function warning(string $application_name, string $message, ?Throwable $throwable=null): void
|
||||||
|
{
|
||||||
|
self::log($application_name, LevelType::Warning, $message, $throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $application_name The name of the application
|
||||||
|
* @param string $message The message of the event
|
||||||
|
* @param Throwable|null $throwable The exception that was thrown, if any
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function error(string $application_name, string $message, ?Throwable $throwable=null): void
|
||||||
|
{
|
||||||
|
self::log($application_name, LevelType::Error, $message, $throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $application_name The name of the application
|
||||||
|
* @param string $message The message of the event
|
||||||
|
* @param Throwable|null $throwable The exception that was thrown, if any
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function fatal(string $application_name, string $message, ?Throwable $throwable=null): void
|
||||||
|
{
|
||||||
|
self::log($application_name, LevelType::Fatal, $message, $throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers LogLib as a exception handler
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function registerExceptionHandler(): void
|
||||||
|
{
|
||||||
|
set_exception_handler(function(Throwable $throwable) {
|
||||||
|
self::error('Exception', $throwable->getMessage(), $throwable);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unregisters all applications
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function unregisterExceptionHandler(): void
|
||||||
|
{
|
||||||
|
set_exception_handler(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return RuntimeOptions
|
||||||
|
*/
|
||||||
|
public static function getRuntimeOptions(): RuntimeOptions
|
||||||
|
{
|
||||||
|
if(self::$RuntimeOptions == null)
|
||||||
|
{
|
||||||
|
self::$RuntimeOptions = new RuntimeOptions();
|
||||||
|
}
|
||||||
|
return self::$RuntimeOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -10,6 +10,7 @@
|
||||||
* The function name of the backtrace
|
* The function name of the backtrace
|
||||||
*
|
*
|
||||||
* @var string|null
|
* @var string|null
|
||||||
|
* @property_name function
|
||||||
*/
|
*/
|
||||||
public $Function;
|
public $Function;
|
||||||
|
|
||||||
|
@ -17,6 +18,7 @@
|
||||||
* The line number of the backtrace
|
* The line number of the backtrace
|
||||||
*
|
*
|
||||||
* @var int|null
|
* @var int|null
|
||||||
|
* @property_name line
|
||||||
*/
|
*/
|
||||||
public $Line;
|
public $Line;
|
||||||
|
|
||||||
|
@ -24,6 +26,7 @@
|
||||||
* The file name of the backtrace
|
* The file name of the backtrace
|
||||||
*
|
*
|
||||||
* @var string|null
|
* @var string|null
|
||||||
|
* @property_name file
|
||||||
*/
|
*/
|
||||||
public $File;
|
public $File;
|
||||||
|
|
||||||
|
@ -31,6 +34,7 @@
|
||||||
* The class name, if any, of the backtrace
|
* The class name, if any, of the backtrace
|
||||||
*
|
*
|
||||||
* @var string|null
|
* @var string|null
|
||||||
|
* @property_name class
|
||||||
*/
|
*/
|
||||||
public $Class;
|
public $Class;
|
||||||
|
|
||||||
|
@ -41,6 +45,7 @@
|
||||||
*
|
*
|
||||||
* @see CallType
|
* @see CallType
|
||||||
* @var string|null
|
* @var string|null
|
||||||
|
* @property_name type
|
||||||
*/
|
*/
|
||||||
public $Type;
|
public $Type;
|
||||||
|
|
||||||
|
@ -49,41 +54,7 @@
|
||||||
* an included file, this lists the included file name(s).
|
* an included file, this lists the included file name(s).
|
||||||
*
|
*
|
||||||
* @var array|null
|
* @var array|null
|
||||||
|
* @property_name args
|
||||||
*/
|
*/
|
||||||
public $Args;
|
public $Args;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array representation of the backtrace
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function toArray(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'function' => $this->Function,
|
|
||||||
'line' => $this->Line,
|
|
||||||
'file' => $this->File,
|
|
||||||
'class' => $this->Class,
|
|
||||||
'type' => $this->Type,
|
|
||||||
'args' => $this->Args
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new DebugBacktrace object from an array representation
|
|
||||||
*
|
|
||||||
* @param array $array
|
|
||||||
* @return Backtrace
|
|
||||||
*/
|
|
||||||
public static function fromArray(array $array): Backtrace
|
|
||||||
{
|
|
||||||
$backtrace = new Backtrace();
|
|
||||||
$backtrace->Function = ($array['function'] ?? null);
|
|
||||||
$backtrace->Line = ($array['line'] ?? null);
|
|
||||||
$backtrace->File = ($array['file'] ?? null);
|
|
||||||
$backtrace->Class = ($array['class'] ?? null);
|
|
||||||
$backtrace->Type = ($array['type'] ?? null);
|
|
||||||
$backtrace->Args = ($array['args'] ?? null);
|
|
||||||
return $backtrace;
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -15,6 +15,7 @@
|
||||||
*
|
*
|
||||||
* @see LevelType
|
* @see LevelType
|
||||||
* @var string
|
* @var string
|
||||||
|
* @property_name level
|
||||||
*/
|
*/
|
||||||
public $Level;
|
public $Level;
|
||||||
|
|
||||||
|
@ -22,6 +23,7 @@
|
||||||
* The Unix Timestamp of when the event was created
|
* The Unix Timestamp of when the event was created
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
|
* @property_name timestamp
|
||||||
*/
|
*/
|
||||||
private $Timestamp;
|
private $Timestamp;
|
||||||
|
|
||||||
|
@ -29,6 +31,7 @@
|
||||||
* An array of backtraces, if any, that were created when the event was created
|
* An array of backtraces, if any, that were created when the event was created
|
||||||
*
|
*
|
||||||
* @var Backtrace[]|null
|
* @var Backtrace[]|null
|
||||||
|
* @property_name backtrace
|
||||||
*/
|
*/
|
||||||
public $Backtrace;
|
public $Backtrace;
|
||||||
|
|
||||||
|
@ -36,6 +39,7 @@
|
||||||
* The exception that was thrown, if any
|
* The exception that was thrown, if any
|
||||||
*
|
*
|
||||||
* @var array|null
|
* @var array|null
|
||||||
|
* @property_name exception
|
||||||
*/
|
*/
|
||||||
public $Exception;
|
public $Exception;
|
||||||
|
|
||||||
|
@ -43,6 +47,7 @@
|
||||||
* The message of the event
|
* The message of the event
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
|
* @property_name message
|
||||||
*/
|
*/
|
||||||
public $Message;
|
public $Message;
|
||||||
|
|
||||||
|
@ -62,39 +67,6 @@
|
||||||
$this->Exception = Utilities::exceptionToArray($e);
|
$this->Exception = Utilities::exceptionToArray($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array representation of the event
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function toArray(): array
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
'level' => ($this->Level ?? null),
|
|
||||||
'timestamp' => ($this->Timestamp ?? null),
|
|
||||||
'backtrace' => $this->Backtrace,
|
|
||||||
'exception' => $this->Exception,
|
|
||||||
'message' => ($this->Message ?? null)
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a new event from an array representation
|
|
||||||
*
|
|
||||||
* @param array $data
|
|
||||||
* @return Event
|
|
||||||
*/
|
|
||||||
public static function fromArray(array $data): Event
|
|
||||||
{
|
|
||||||
$event = new Event();
|
|
||||||
$event->Level = ($data['level'] ?? null);
|
|
||||||
$event->Timestamp = ($data['timestamp'] ?? null);
|
|
||||||
$event->Backtrace = ($data['backtrace'] ?? null);
|
|
||||||
$event->Exception = ($data['exception'] ?? null);
|
|
||||||
$event->Message = ($data['message'] ?? null);
|
|
||||||
return $event;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
|
|
99
src/LogLib/Objects/FileLogging/FileHandle.php
Normal file
99
src/LogLib/Objects/FileLogging/FileHandle.php
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
<?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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,9 +5,13 @@
|
||||||
namespace LogLib\Objects;
|
namespace LogLib\Objects;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
use LogLib\Abstracts\LevelType;
|
|
||||||
use LogLib\Classes\Validate;
|
use LogLib\Classes\Validate;
|
||||||
use LogLib\Interfaces\HandlerInterface;
|
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
|
class Options
|
||||||
{
|
{
|
||||||
|
@ -15,62 +19,19 @@
|
||||||
* The name of the application
|
* The name of the application
|
||||||
*
|
*
|
||||||
* @var string
|
* @var string
|
||||||
|
* @property_name application_name
|
||||||
*/
|
*/
|
||||||
private $ApplicationName;
|
private $ApplicationName;
|
||||||
|
|
||||||
/**
|
|
||||||
* The name of the NCC package that is using LogLib (eg; com.example.package)
|
|
||||||
*
|
|
||||||
* @var string|null
|
|
||||||
*/
|
|
||||||
private $PackageName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current output level of the logger, anything below this level will not be logged
|
|
||||||
*
|
|
||||||
* @see LevelType
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
private $OutputLevel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether the log should be written to the console or not.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private $ConsoleOutput;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether ansi colors should be used in the console output.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private $ConsoleAnsiColors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the log to a file located at the package data path provided by NCC's API
|
* Writes the log to a file located at the package data path provided by NCC's API
|
||||||
* under a "logs" directory.
|
* under a "logs" directory.
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
|
* @property_name write_to_package_data
|
||||||
*/
|
*/
|
||||||
private $WriteToPackageData;
|
private $WriteToPackageData;
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates whether the log should be split into different files based on the file size.
|
|
||||||
* Only applies if WriteToPackageData is true.
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private $SplitFiles;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The maximum size of a log file before it is split into a new file.
|
|
||||||
* Only applies if WriteToPackageData is true.
|
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
private $MaxFileSize;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of handlers that wil be used to handle the log events
|
* An array of handlers that wil be used to handle the log events
|
||||||
* if applications want to handle the log events themselves.
|
* if applications want to handle the log events themselves.
|
||||||
|
@ -79,136 +40,78 @@
|
||||||
*/
|
*/
|
||||||
private $Handlers;
|
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.
|
* Options constructor.
|
||||||
*/
|
*/
|
||||||
public function __construct(string $application_name)
|
public function __construct(string $application_name)
|
||||||
{
|
{
|
||||||
$this->ApplicationName = $application_name;
|
$this->ApplicationName = $application_name;
|
||||||
$this->WriteToPackageData = true;
|
$this->WriteToPackageData = false;
|
||||||
$this->SplitFiles = true;
|
$this->DumpExceptions = false;
|
||||||
$this->MaxFileSize = 1073741824; // 1GB
|
|
||||||
$this->OutputLevel = LevelType::Info;
|
|
||||||
$this->ConsoleOutput = true;
|
|
||||||
$this->ConsoleAnsiColors = true;
|
|
||||||
$this->Handlers = [];
|
$this->Handlers = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string|null
|
|
||||||
*/
|
|
||||||
public function getPackageName(): ?string
|
|
||||||
{
|
|
||||||
return $this->PackageName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string|null $PackageName
|
|
||||||
*/
|
|
||||||
public function setPackageName(?string $PackageName): void
|
|
||||||
{
|
|
||||||
$this->PackageName = $PackageName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getOutputLevel(): string
|
|
||||||
{
|
|
||||||
return $this->OutputLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $OutputLevel
|
|
||||||
*/
|
|
||||||
public function setOutputLevel(string $OutputLevel): void
|
|
||||||
{
|
|
||||||
if(!in_array($OutputLevel, LevelType::All))
|
|
||||||
throw new InvalidArgumentException("Invalid output level provided");
|
|
||||||
$this->OutputLevel = $OutputLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isConsoleOutput(): bool
|
public function writeToPackageData(): bool
|
||||||
{
|
|
||||||
return $this->ConsoleOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $ConsoleOutput
|
|
||||||
*/
|
|
||||||
public function setConsoleOutput(bool $ConsoleOutput): void
|
|
||||||
{
|
|
||||||
$this->ConsoleOutput = $ConsoleOutput;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isConsoleAnsiColors(): bool
|
|
||||||
{
|
|
||||||
return $this->ConsoleAnsiColors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool $ConsoleAnsiColors
|
|
||||||
*/
|
|
||||||
public function setConsoleAnsiColors(bool $ConsoleAnsiColors): void
|
|
||||||
{
|
|
||||||
$this->ConsoleAnsiColors = $ConsoleAnsiColors;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function isWriteToPackageData(): bool
|
|
||||||
{
|
{
|
||||||
return $this->WriteToPackageData;
|
return $this->WriteToPackageData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool $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 setWriteToPackageData(bool $WriteToPackageData): void
|
public function enableWriteToPackageData(): void
|
||||||
{
|
{
|
||||||
$this->WriteToPackageData = $WriteToPackageData;
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return bool
|
* Disables the writing of the log to the package data path
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function isSplitFiles(): bool
|
public function disableWriteToPackageData(): void
|
||||||
{
|
{
|
||||||
return $this->SplitFiles;
|
$this->WriteToPackageData = false;
|
||||||
}
|
$this->PackageDataPath = null;
|
||||||
|
unset($this->FileHandle);
|
||||||
/**
|
|
||||||
* @param bool $SplitFiles
|
|
||||||
*/
|
|
||||||
public function setSplitFiles(bool $SplitFiles): void
|
|
||||||
{
|
|
||||||
$this->SplitFiles = $SplitFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function getMaxFileSize(): int
|
|
||||||
{
|
|
||||||
return $this->MaxFileSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param int $MaxFileSize
|
|
||||||
*/
|
|
||||||
public function setMaxFileSize(int $MaxFileSize): void
|
|
||||||
{
|
|
||||||
if($MaxFileSize < 1)
|
|
||||||
throw new InvalidArgumentException("Max file size must be greater than 0");
|
|
||||||
|
|
||||||
$this->MaxFileSize = $MaxFileSize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -243,10 +146,52 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Returns the name of the Application
|
||||||
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getApplicationName(): string
|
public function getApplicationName(): string
|
||||||
{
|
{
|
||||||
return $this->ApplicationName;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
153
src/LogLib/Objects/RuntimeOptions.php
Normal file
153
src/LogLib/Objects/RuntimeOptions.php
Normal file
|
@ -0,0 +1,153 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/** @noinspection PhpMissingFieldTypeInspection */
|
||||||
|
|
||||||
|
namespace LogLib\Objects;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use LogLib\Abstracts\LevelType;
|
||||||
|
use LogLib\Classes\Utilities;
|
||||||
|
use LogLib\Objects\FileLogging\FileHandle;
|
||||||
|
|
||||||
|
class RuntimeOptions
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Indicates if the console output is enabled
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
* @property_name console_output
|
||||||
|
*/
|
||||||
|
private $ConsoleOutput;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if ANSI colors should be used in the console output
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
* @property_name display_ansi
|
||||||
|
*/
|
||||||
|
private $DisplayAnsi;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if LogLib should handle uncaught exceptions
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
* @property_name handle_exceptions
|
||||||
|
*/
|
||||||
|
private $HandleExceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional. The file to write the log to.
|
||||||
|
*
|
||||||
|
* @var string|null
|
||||||
|
* @property_name output_log
|
||||||
|
*/
|
||||||
|
private $OutputLog;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The current log level
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
* @see LevelType
|
||||||
|
*/
|
||||||
|
private $LogLevel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var FileHandle
|
||||||
|
*/
|
||||||
|
private $OutputLogHandle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public Constructor
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->ConsoleOutput = Utilities::runningInCli();
|
||||||
|
$this->DisplayAnsi = Utilities::getDisplayAnsi();
|
||||||
|
$this->HandleExceptions = true;
|
||||||
|
$this->OutputLog = Utilities::getOutputLogPath();
|
||||||
|
$this->LogLevel = Utilities::getLogLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isConsoleOutput(): bool
|
||||||
|
{
|
||||||
|
return $this->ConsoleOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $ConsoleOutput
|
||||||
|
*/
|
||||||
|
public function setConsoleOutput(bool $ConsoleOutput): void
|
||||||
|
{
|
||||||
|
$this->ConsoleOutput = $ConsoleOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isDisplayAnsi(): bool
|
||||||
|
{
|
||||||
|
return $this->DisplayAnsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $DisplayAnsi
|
||||||
|
*/
|
||||||
|
public function setDisplayAnsi(bool $DisplayAnsi): void
|
||||||
|
{
|
||||||
|
$this->DisplayAnsi = $DisplayAnsi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isHandleExceptions(): bool
|
||||||
|
{
|
||||||
|
return $this->HandleExceptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param bool $HandleExceptions
|
||||||
|
*/
|
||||||
|
public function setHandleExceptions(bool $HandleExceptions): void
|
||||||
|
{
|
||||||
|
$this->HandleExceptions = $HandleExceptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getLogLevel(): int
|
||||||
|
{
|
||||||
|
return $this->LogLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $LogLevel
|
||||||
|
*/
|
||||||
|
public function setLogLevel(int $LogLevel): void
|
||||||
|
{
|
||||||
|
$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;
|
||||||
|
}
|
||||||
|
}
|
19
tests/logging.php
Normal file
19
tests/logging.php
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
<?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');
|
||||||
|
$options->enableWriteToPackageData();
|
||||||
|
Log::register($options);
|
||||||
|
|
||||||
|
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');
|
Loading…
Add table
Reference in a new issue