diff --git a/.idea/php.xml b/.idea/php.xml
index ede6265..09cee4f 100644
--- a/.idea/php.xml
+++ b/.idea/php.xml
@@ -11,8 +11,10 @@
+
-
+
+
diff --git a/Makefile b/Makefile
index b5a49de..633c80c 100644
--- a/Makefile
+++ b/Makefile
@@ -5,10 +5,10 @@ release:
ncc build --config="release"
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:
- 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:
ncc package uninstall -y --package="net.nosial.loglib"
\ No newline at end of file
diff --git a/README.md b/README.md
index f49546f..f3f0f68 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,29 @@
# LogLib
-A logging library for PHP.
\ No newline at end of file
+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
+```
\ No newline at end of file
diff --git a/project.json b/project.json
index 393e3d2..6e0d264 100644
--- a/project.json
+++ b/project.json
@@ -5,6 +5,15 @@
"minimum_version": "8.0",
"maximum_version": "8.2"
},
+ "update_source": {
+ "source": "nosial/libs.log@n64",
+ "repository": {
+ "name": "n64",
+ "type": "gitlab",
+ "host": "git.n64.cc",
+ "ssl": true
+ }
+ },
"options": []
},
"assembly": {
@@ -24,6 +33,20 @@
"ASSEMBLY_VERSION": "%ASSEMBLY.VERSION%",
"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": [
{
"name": "debug",
diff --git a/src/LogLib/Abstracts/ConsoleColors.php b/src/LogLib/Abstracts/ConsoleColors.php
index c5db91f..648c549 100644
--- a/src/LogLib/Abstracts/ConsoleColors.php
+++ b/src/LogLib/Abstracts/ConsoleColors.php
@@ -40,4 +40,15 @@
self::LightGray,
self::White
];
+
+ /**
+ * A list of random usable bright colors
+ */
+ const BrightColors = [
+ self::LightBlue,
+ self::LightGreen,
+ self::LightCyan,
+ self::LightRed,
+ self::LightPurple,
+ ];
}
\ No newline at end of file
diff --git a/src/LogLib/Classes/Console.php b/src/LogLib/Classes/Console.php
index 755c1bf..50be148 100644
--- a/src/LogLib/Classes/Console.php
+++ b/src/LogLib/Classes/Console.php
@@ -6,6 +6,7 @@
use LogLib\Abstracts\ConsoleColors;
use LogLib\Abstracts\LevelType;
+ use LogLib\Log;
use LogLib\Objects\Event;
use LogLib\Objects\Options;
@@ -24,13 +25,17 @@
*/
private static function formatAppColor(string $application): string
{
+ if(!Log::getRuntimeOptions()->isDisplayAnsi())
+ return $application;
+
if(!isset(self::$ApplicationColors[$application]))
{
- $colors = ConsoleColors::All;
+ $colors = ConsoleColors::BrightColors;
$color = $colors[array_rand($colors)];
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
{
- 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
{
+ if(!Log::getRuntimeOptions()->isDisplayAnsi())
+ return Utilities::levelToString($text);
+
$color = null;
switch($event->Level)
{
@@ -83,46 +94,6 @@
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
*
@@ -132,61 +103,35 @@
*/
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(Validate::checkLevelType(LevelType::Verbose, $options->getOutputLevel()))
- {
- $backtrace_output = self::parseBacktrace($event);
+ if(!Utilities::runningInCli())
+ return;
- if($options->isConsoleAnsiColors())
- {
- print(sprintf(
- "%s [%s] [%s] (%s) - %s" . PHP_EOL,
- $event->getTimestamp(),
- self::formatAppColor($options->getApplicationName()),
- 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(Validate::checkLevelType(LevelType::Verbose, Log::getRuntimeOptions()->getLogLevel()))
+ {
+ $backtrace_output = Utilities::parseBacktrace($event);
+
+ print(sprintf(
+ "%s [%s] [%s] (%s) - %s" . PHP_EOL,
+ $event->getTimestamp(),
+ self::formatAppColor($options->getApplicationName()),
+ self::colorize($event, $event->Level),
+ $backtrace_output !== null ? $backtrace_output : 'λ',
+ $event->Message
+ ));
if($event->Exception !== null)
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)
- self::outException($event->Exception);
+ return;
}
-
+ print(sprintf(
+ "%s [%s] [%s] - %s" . PHP_EOL,
+ $event->getTimestamp(),
+ self::formatAppColor($options->getApplicationName()),
+ self::colorize($event, $event->Level),
+ $event->Message
+ ));
}
/**
diff --git a/src/LogLib/Classes/FileLogging.php b/src/LogLib/Classes/FileLogging.php
new file mode 100644
index 0000000..a115480
--- /dev/null
+++ b/src/LogLib/Classes/FileLogging.php
@@ -0,0 +1,84 @@
+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;
+ }
+ }
\ No newline at end of file
diff --git a/src/LogLib/Classes/Utilities.php b/src/LogLib/Classes/Utilities.php
index c8f7a22..dd614f5 100644
--- a/src/LogLib/Classes/Utilities.php
+++ b/src/LogLib/Classes/Utilities.php
@@ -4,6 +4,9 @@
use LogLib\Abstracts\LevelType;
use LogLib\Objects\Backtrace;
+ use LogLib\Objects\Event;
+ use OptsLib\Parse;
+ use Properties\Prop;
use Throwable;
class Utilities
@@ -23,7 +26,7 @@
foreach($backtrace as $trace)
{
- $results[] = Backtrace::fromArray($trace);
+ $results[] = Prop::fromArray($trace);
}
return $results;
@@ -36,6 +39,8 @@
public static function exceptionToArray(Throwable $e): array
{
$results = [
+ 'hash' => spl_object_hash($e),
+ 'type' => get_class($e),
'message' => $e->getMessage(),
'code' => $e->getCode(),
'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;
+ }
+
}
\ No newline at end of file
diff --git a/src/LogLib/Exceptions/ConfigurationException.php b/src/LogLib/Exceptions/ConfigurationException.php
new file mode 100644
index 0000000..7a829fc
--- /dev/null
+++ b/src/LogLib/Exceptions/ConfigurationException.php
@@ -0,0 +1,21 @@
+message = $message;
+ $this->code = $code;
+ }
+ }
\ No newline at end of file
diff --git a/src/LogLib/Log.php b/src/LogLib/Log.php
new file mode 100644
index 0000000..058fee0
--- /dev/null
+++ b/src/LogLib/Log.php
@@ -0,0 +1,231 @@
+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;
+ }
+
+ }
\ No newline at end of file
diff --git a/src/LogLib/Objects/Backtrace.php b/src/LogLib/Objects/Backtrace.php
index cbb4dd7..fb49dac 100644
--- a/src/LogLib/Objects/Backtrace.php
+++ b/src/LogLib/Objects/Backtrace.php
@@ -10,6 +10,7 @@
* The function name of the backtrace
*
* @var string|null
+ * @property_name function
*/
public $Function;
@@ -17,6 +18,7 @@
* The line number of the backtrace
*
* @var int|null
+ * @property_name line
*/
public $Line;
@@ -24,6 +26,7 @@
* The file name of the backtrace
*
* @var string|null
+ * @property_name file
*/
public $File;
@@ -31,6 +34,7 @@
* The class name, if any, of the backtrace
*
* @var string|null
+ * @property_name class
*/
public $Class;
@@ -41,6 +45,7 @@
*
* @see CallType
* @var string|null
+ * @property_name type
*/
public $Type;
@@ -49,41 +54,7 @@
* an included file, this lists the included file name(s).
*
* @var array|null
+ * @property_name 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;
- }
}
\ No newline at end of file
diff --git a/src/LogLib/Objects/Event.php b/src/LogLib/Objects/Event.php
index ea24c1a..a8c6067 100644
--- a/src/LogLib/Objects/Event.php
+++ b/src/LogLib/Objects/Event.php
@@ -15,6 +15,7 @@
*
* @see LevelType
* @var string
+ * @property_name level
*/
public $Level;
@@ -22,6 +23,7 @@
* The Unix Timestamp of when the event was created
*
* @var string
+ * @property_name timestamp
*/
private $Timestamp;
@@ -29,6 +31,7 @@
* An array of backtraces, if any, that were created when the event was created
*
* @var Backtrace[]|null
+ * @property_name backtrace
*/
public $Backtrace;
@@ -36,6 +39,7 @@
* The exception that was thrown, if any
*
* @var array|null
+ * @property_name exception
*/
public $Exception;
@@ -43,6 +47,7 @@
* The message of the event
*
* @var string
+ * @property_name message
*/
public $Message;
@@ -62,39 +67,6 @@
$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
*/
diff --git a/src/LogLib/Objects/FileLogging/FileHandle.php b/src/LogLib/Objects/FileLogging/FileHandle.php
new file mode 100644
index 0000000..1d9f11a
--- /dev/null
+++ b/src/LogLib/Objects/FileLogging/FileHandle.php
@@ -0,0 +1,99 @@
+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;
+ }
+ }
\ No newline at end of file
diff --git a/src/LogLib/Objects/Options.php b/src/LogLib/Objects/Options.php
index a2acc05..7451f96 100644
--- a/src/LogLib/Objects/Options.php
+++ b/src/LogLib/Objects/Options.php
@@ -5,9 +5,13 @@
namespace LogLib\Objects;
use InvalidArgumentException;
- use LogLib\Abstracts\LevelType;
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
{
@@ -15,62 +19,19 @@
* The name of the application
*
* @var string
+ * @property_name application_name
*/
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
* under a "logs" directory.
*
* @var bool
+ * @property_name write_to_package_data
*/
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
* if applications want to handle the log events themselves.
@@ -79,136 +40,78 @@
*/
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 = true;
- $this->SplitFiles = true;
- $this->MaxFileSize = 1073741824; // 1GB
- $this->OutputLevel = LevelType::Info;
- $this->ConsoleOutput = true;
- $this->ConsoleAnsiColors = true;
+ $this->WriteToPackageData = false;
+ $this->DumpExceptions = false;
$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
*/
- public function isConsoleOutput(): 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
+ public function writeToPackageData(): bool
{
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;
- }
-
- /**
- * @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;
+ $this->WriteToPackageData = false;
+ $this->PackageDataPath = null;
+ unset($this->FileHandle);
}
/**
@@ -243,10 +146,52 @@
}
/**
+ * Returns the name of the Application
+ *
* @return string
*/
public function getApplicationName(): string
{
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;
+ }
+
}
\ No newline at end of file
diff --git a/src/LogLib/Objects/RuntimeOptions.php b/src/LogLib/Objects/RuntimeOptions.php
new file mode 100644
index 0000000..ced3eff
--- /dev/null
+++ b/src/LogLib/Objects/RuntimeOptions.php
@@ -0,0 +1,153 @@
+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;
+ }
+ }
\ No newline at end of file
diff --git a/tests/logging.php b/tests/logging.php
new file mode 100644
index 0000000..96df4c6
--- /dev/null
+++ b/tests/logging.php
@@ -0,0 +1,19 @@
+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');
\ No newline at end of file