-
-
Notifications
You must be signed in to change notification settings - Fork 1
PSR 3 Compliance
The package targets PSR-3 v3, the
current version of the PHP-FIG logging interface. It declares the
implementation through Composer's provide mechanism:
"provide": {
"psr/log-implementation": "3.0"
}This page documents how each rule of the specification maps to the package's behaviour.
PSR-3 defines a single interface, Psr\Log\LoggerInterface, with nine
methods:
namespace Psr\Log;
interface LoggerInterface
{
public function emergency(string|\Stringable $message, array $context = []): void;
public function alert (string|\Stringable $message, array $context = []): void;
public function critical (string|\Stringable $message, array $context = []): void;
public function error (string|\Stringable $message, array $context = []): void;
public function warning (string|\Stringable $message, array $context = []): void;
public function notice (string|\Stringable $message, array $context = []): void;
public function info (string|\Stringable $message, array $context = []): void;
public function debug (string|\Stringable $message, array $context = []): void;
public function log ($level, string|\Stringable $message, array $context = []): void;
}All three handlers shipped in this package implement that interface:
-
Logger— extends\Psr\Log\AbstractLogger. -
FileLogger— extends\Psr\Log\AbstractLogger. -
PDOLogger— extends\Psr\Log\AbstractLogger.
Extending AbstractLogger means each handler implements just log(); the
eight severity helpers are inherited and forward to that single method.
PSR-3 §1.1 enumerates exactly eight severity levels, in this order (highest first):
| Level |
Psr\Log\LogLevel constant |
Severity |
|---|---|---|
| Emergency |
LogLevel::EMERGENCY ("emergency") |
system is unusable |
| Alert |
LogLevel::ALERT ("alert") |
action must be taken immediately |
| Critical |
LogLevel::CRITICAL ("critical") |
critical conditions |
| Error |
LogLevel::ERROR ("error") |
runtime errors that do not require immediate action |
| Warning |
LogLevel::WARNING ("warning") |
exceptional occurrences that are not errors |
| Notice |
LogLevel::NOTICE ("notice") |
normal but significant events |
| Info |
LogLevel::INFO ("info") |
informational messages |
| Debug |
LogLevel::DEBUG ("debug") |
debug-level messages |
The package matches level inputs case-insensitively against these eight
constants. So 'error', 'ERROR', 'Error' all work. Output is uppercased
for grep-friendliness ([ERROR] in file logs, 'ERROR' in the database
level column).
Any other string raises Psr\Log\InvalidArgumentException, as permitted by
PSR-3 §1.1.
PSR-3 §1.2 defines the placeholder syntax: a placeholder is {name}, where
name matches the regex [A-Za-z0-9_\.]+. Each handler in the package
implements that syntax through HelperTrait::interpolate(). The full rules
are documented in Context Interpolation.
$logger->info('User {user} hit a {kind} error', [
'user' => 'jane',
'kind' => 'transient',
]);
// → "User jane hit a transient error"PSR-3 §1.3 says:
If an Exception object is passed in the context data, it MUST be in the
'exception'key. Logging exceptions is a common pattern and this allows implementors to extract a stack trace from the exception when the log backend supports it.Implementors MUST still ensure that the
'exception'key is not interfered with should they get one from the user.
The package honours both clauses:
- It does not apply special parsing to the
'exception'key beyond the generic\Throwablerendering. - Any
\Throwablein the context — under any key — is rendered as"<Class>(<code>): <message> in <file>:<line>"when its corresponding placeholder appears in the message.
If you want the stack trace too, format it yourself:
$logger->error("payment failed: {exception}\n{trace}", [
'exception' => $e,
'trace' => $e->getTraceAsString(),
]);PSR-3 v3 widened the message type from string to string|\Stringable. The
package accepts both:
$logger->info('plain string');
$logger->info(new class implements \Stringable {
public function __toString(): string { return 'a Stringable'; }
});Placeholders work on the rendered string of a Stringable message,
so combining the two is fully supported.
PSR-3 explicitly permits (but does not require) implementers to:
- raise
Psr\Log\InvalidArgumentExceptionfromlog()when the level is unknown — the package does; - interpret context keys with special meaning to the storage backend, as
long as the
'exception'key is preserved — the package only renders\Throwablein context; it does not assign extra meaning to any key.
The specification mandates that:
-
log()MUST NOT throw for ordinary backend failures (network down, disk full, …). The package's handlers honour this — see Error Handling. - A logger MUST NOT modify the contents of the
$contextarray. The package reads it but never writes back; even shared-context wrappers like the one in Multi-Logger create a new merged array per call.
The single most important rule for PSR-3 consumers: depend on the interface.
use Psr\Log\LoggerInterface;
final class PaymentService
{
public function __construct(private LoggerInterface $logger) {}
}Production code can be wired with InitPHP\Logger\Logger, tests with
Psr\Log\NullLogger, an integration test with an ArrayLogger-style helper
(Custom Handlers) — none of
the consumer code changes.
- Context Interpolation — the per-value rendering rules in detail.
- Error Handling — when the package throws and when it silently degrades.
- Custom Handlers › Guidelines — checklist for writing your own PSR-3-compliant handler.
- The official spec: https://www.php-fig.org/psr/psr-3/.
initphp/logger · MIT License · part of the InitPHP family
Source · Issues · Discussions · Packagist · Contributing · Security Policy
Getting Started
Handlers
PSR-3 Behaviour
Practical Guides
Reference