chore: added documentation (#16)
All checks were successful
🧪✨ Tests Workflow / 🛡️ 🔒 Library Audit (push) Successful in 1m42s
🧪✨ Tests Workflow / 📝 ✨ Code Lint (push) Successful in 1m38s
🧪✨ Tests Workflow / 🛡️ 🔒 License Check (push) Successful in 2m5s
🧪✨ Tests Workflow / 🧪 ✨ Database Migrations (push) Successful in 2m44s
🧪✨ Tests Workflow / 🐙 🔍 Code Sniffer (push) Successful in 2m28s
🧪✨ Tests Workflow / 🧪 ✅ Unit Tests (push) Successful in 1m27s

Reviewed-on: #16
Co-authored-by: Ron Rise <ron@siteworxpro.com>
Co-committed-by: Ron Rise <ron@siteworxpro.com>
This commit was merged in pull request #16.
This commit is contained in:
2025-11-13 04:14:13 +00:00
committed by Siteworx Pro Gitea
parent e4a55af694
commit 5542ad1e75
28 changed files with 514 additions and 84 deletions

View File

@@ -11,12 +11,44 @@ use Psr\Log\LogLevel;
use RoadRunner\Logger\Logger as RRLogger;
use Spiral\Goridge\RPC\RPC;
/**
* Logger implementation that conforms to PSR-3 (`Psr\Log\LoggerInterface`).
*
* Behavior:
* - If environment indicates RoadRunner RPC (`$_SERVER['RR_RPC']`), logs are forwarded
* to a RoadRunner RPC logger (`RoadRunner\Logger\Logger`) created via Goridge RPC.
* - Otherwise, logs are written to `php://stdout` using Monolog with a JSON formatter.
* - Messages below the configured threshold are ignored (level filtering).
*
* Supported PSR-3 levels are mapped to an internal numeric ordering in `$levels`.
* When using the RPC logger, levels are translated to the respective RPC methods
* (debug, info, warning, error). When using Monolog, the numeric mapping is used
* as the numeric level passed to Monolog's `log` method.
*/
class Logger implements LoggerInterface
{
/**
* RoadRunner RPC logger instance when running under RoadRunner.
*
* @var RRLogger|null
*/
private ?RRLogger $rpcLogger = null;
/**
* Monolog logger used as a fallback to write JSON-formatted logs to stdout.
*
* @var \Monolog\Logger
*/
private \Monolog\Logger $monologLogger;
/**
* Numeric ordering for PSR-3 log levels.
*
* Lower numbers represent higher severity. This mapping is used for filtering
* messages according to the configured minimum level and for Monolog numeric level.
*
* @var array<string,int>
*/
private array $levels = [
LogLevel::EMERGENCY => 0,
LogLevel::ALERT => 1,
@@ -28,10 +60,21 @@ class Logger implements LoggerInterface
LogLevel::DEBUG => 7,
];
/**
* Create a new Logger.
*
* @param string $level Minimum level to log (PSR-3 level string). Messages with
* a higher numeric value in `$levels` will be ignored.
*
* The default is `LogLevel::DEBUG` (log everything).
*
* If `$_SERVER['RR_RPC']` is set, an RPC connection will be attempted at
* $_SERVER['RR_RPC'] and a RoadRunner RPC logger will be used.
*/
public function __construct(private readonly string $level = LogLevel::DEBUG)
{
if (isset($_SERVER['RR_RPC'])) {
$rpc = RPC::create('tcp://127.0.0.1:6001');
$rpc = RPC::create($_SERVER['RR_RPC']);
$this->rpcLogger = new RRLogger($rpc);
}
@@ -40,46 +83,113 @@ class Logger implements LoggerInterface
$this->monologLogger->pushHandler(new StreamHandler('php://stdout')->setFormatter($formatter));
}
/**
* System is unusable.
*
* @param \Stringable|string $message
* @param array $context
*/
public function emergency(\Stringable|string $message, array $context = []): void
{
$this->log(LogLevel::EMERGENCY, $message, $context);
}
/**
* Action must be taken immediately.
*
* @param \Stringable|string $message
* @param array $context
*/
public function alert(\Stringable|string $message, array $context = []): void
{
$this->log(LogLevel::ALERT, $message, $context);
}
/**
* Critical conditions.
*
* @param \Stringable|string $message
* @param array $context
*/
public function critical(\Stringable|string $message, array $context = []): void
{
$this->log(LogLevel::CRITICAL, $message, $context);
}
/**
* Runtime errors that do not require immediate action but should typically be logged and monitored.
*
* @param \Stringable|string $message
* @param array $context
*/
public function error(\Stringable|string $message, array $context = []): void
{
$this->log(LogLevel::ERROR, $message, $context);
}
/**
* Exceptional occurrences that are not errors.
*
* @param \Stringable|string $message
* @param array $context
*/
public function warning(\Stringable|string $message, array $context = []): void
{
$this->log(LogLevel::WARNING, $message, $context);
}
/**
* Normal but significant events.
*
* @param \Stringable|string $message
* @param array $context
*/
public function notice(\Stringable|string $message, array $context = []): void
{
$this->log(LogLevel::NOTICE, $message, $context);
}
/**
* Interesting events.
*
* @param \Stringable|string $message
* @param array $context
*/
public function info(\Stringable|string $message, array $context = []): void
{
$this->log(LogLevel::INFO, $message, $context);
}
/**
* Detailed debug information.
*
* @param \Stringable|string $message
* @param array $context
*/
public function debug(\Stringable|string $message, array $context = []): void
{
$this->log(LogLevel::DEBUG, $message, $context);
}
/**
* Logs with an arbitrary level.
*
* Behavior details:
* - If the provided `$level` maps to a numeric value greater than the configured
* minimum level, the message is discarded (filtered).
* - If an RPC logger is available, the message is forwarded to the RPC logger
* using a method chosen by level (debug, info, warning, error).
* - Otherwise, the message is written to Monolog using the numeric mapping.
*
* Notes:
* - `$level` should be a PSR-3 level string (values defined in `Psr\Log\LogLevel`).
* - If an unknown level string is passed, accessing `$this->levels[$level]` may
* trigger a PHP notice or undefined index. Ensure callers use valid PSR-3 levels.
*
* @param mixed $level PSR-3 log level (string)
* @param \Stringable|string $message
* @param array $context
*/
public function log($level, \Stringable|string $message, array $context = []): void
{
if ($this->levels[$level] > $this->levels[$this->level]) {