Package · logger

Logger

Winter Logger is a PSR-3 logger built for every PHP runtime you deploy to — PHP-FPM, Swoole, and the CLI. It wraps Monolog with coroutine-safe request context, a readable Spring Boot-style line format, and a Java-style static factory, while knowing nothing about your infrastructure.

Philosophy

  • Infrastructure-agnostic — the library never reads env vars, detects Docker, inspects the SAPI, or probes for Swoole. The framework resolves all of that and hands over a finished config. That keeps the logger portable and trivial to test.
  • Monolog is optional — without monolog/monolog installed, every logger silently becomes a PSR-3 NullLogger. No exceptions, no warnings — logging just turns off.
  • Runtime-safe context — request-scoped fields (request_id, user_id, …) never leak between concurrent requests, because context storage is chosen per runtime.

Core concepts

  • LoggerManager — builds and caches one Monolog channel per config entry.
  • LoggerFactory — a static, Java-style facade: getLogger(MyClass::class) returns a per-class named logger, cached by class.
  • Log — a one-line static shortcut to the default channel.
  • ContextStorage — the abstraction that isolates request context (ProcessContext for FPM/CLI, CoroutineContext for Swoole).

Key features

  • PSR-3 compliant — drop-in wherever a Psr\Log\LoggerInterface is expected.
  • Per-class loggersgetLogger(UserService::class) renders (UserService) in the line and stores the full FQCN in context for log-aggregator queries.
  • Request-scoped context — set request_id once; it appears in every line automatically.
  • Coroutine isolationCoroutineContext binds context to the Swoole coroutine, so concurrent requests never bleed into each other.
  • Broken-pipe safeSafeStreamHandler never crashes an FPM worker when the client disconnects mid-write.
  • Sensitive-data masking — an optional processor redacts passwords, tokens, and more.
  • Two formats — a human-readable line format and newline-delimited JSON for aggregators.

Good fit for

Any Winter service that has to run the same code across FPM, a Swoole server, and CLI workers — with one logging API, request context that follows each request, and output that is readable in a terminal yet machine-parseable in production.

Requirements

  • PHP ≥ 8.3
  • psr/log ^3.0
  • monolog/monolog ^3.5suggested; without it every logger is a silent NullLogger
  • ext-swoole (or ext-openswoole) — optional; only for CoroutineContext

Install

bash
composer require flytachi/winter-logger monolog/monolog

Quick start

Build a manager, register it once, and log from anywhere:

php
use Flytachi\Winter\Logger\LoggerFactory;

LoggerFactory::getLogger(UserService::class)->info('user created', ['id' => 42]);
text
[2024-01-01 12:00:00] [INFO ] -http- [4821] (UserService): user created {"id":42,"class":"App\\Service\\UserService"}

Walk through it end to end — install to a live request-scoped log line in five minutes — in the Quickstart.

Continue with Installation & requirements, the Quickstart, and the Mental model.