ErrorLogLogger
A PSR-3 logger that writes to THE APP'S LOG — the one the host already configured. It exists because {@see \Milpa\Runtime\Http\ExceptionMiddleware} makes a promise the framework was not keeping. Measured on a fresh app (greenhouse decisions/0286): a route that throws answered a rendered 500 whose body reads «the detail is in this app's log» with a reference — and the app was built with `new ExceptionMiddleware($psr17, null, …)`, so the reference joined the response to NOTHING. The half that protects the client worked (no message, no trace, measured); the half that keeps the detail findable did not exist. A page that names a log there is no log for is worse than one that says nothing: it sends whoever reads it looking for a file. ── WHY `error_log()` AND NOT A FILE THIS PACKAGE PICKS ───────────────────────────────────────────── Every deployment ALREADY has an app log and the host already chose where it is: php-fpm has its `error_log`, Apache and nginx theirs, `php -S` prints to the console the developer is watching, and a container ships it to stdout. `error_log()` is the one destination that is correct in all of them without this package guessing a path, creating a directory, or owning rotation — and a path guessed wrong fails the same way `null` did, silently, while looking configured. An app that wants structured logs elsewhere passes its OWN PSR-3 logger to `Kernel::boot(['logger' => …])`; this is the default that makes the default honest, not a logging policy. The level rides in the line because `error_log()` has no level of its own, and the context is appended as JSON so a line stays greppable by the reference the 500 page showed — which is the whole point. ── WHY THERE IS A FLOOR, AND WHY IT IS `warning` ────────────────────────────────────────────────── A host will pass this to `Kernel::boot(['logger' => …])`, because that is the one logger the whole app then shares. Measured the moment it was: an EMPTY boot — zero plugins, zero requests — wrote SIX lines, all `debug`, because the event dispatcher narrates every dispatch to whatever logger it holds. Unfiltered, this class turns the app's error log into a firehose and the `error` line the 500 page points at becomes the hardest thing in the file to find. So the default floor is `warning`: everything that means «something is wrong» passes, and the narration of a working app does not. A host that wants the narration asks for it — `new ErrorLogLogger(LogLevel::DEBUG)` — which is the shape where the noisy choice is the explicit one.
ErrorLogLogger::__construct()
public function __construct(string $floor = Psr\Log\LogLevel::WARNING):Records at or above this severity are written; the rest are dropped.
Parameters
| Name | Type | Description |
|---|---|---|
| $floor | string |
ErrorLogLogger::log()
public function log($level, Stringable|string $message, array $context = []): voidOne line per record: `[level] message {context}`, with `{placeholders}` interpolated. PSR-3 asks that a `{key}` in the message be replaced by `$context['key']` when that value is a string or stringable, and that unmatched braces be left alone. The exception itself — which PSR-3 puts under `exception` — is deliberately NOT rendered: its trace is the thing this whole path exists to keep off the wire, and a trace in the log is fine but belongs to the host's own handler, not to a line this package composes.
Parameters
| Name | Type | Description |
|---|---|---|
| $level | mixed | |
| $message | Stringable|string | |
| $context | array<mixed, mixed> |