Package · logger

Channel config

A channel is a named Monolog instance with its own level, format, and output. Each entry in a LoggerManager’s channels array is a config of the shape below.

Config shape

php
'http' => [
  'level'        => \Monolog\Level::Info,
  'format'       => 'line',
  'output'       => 'stderr',
  'file_path'    => null,
  'file_max'     => 30,
  'syslog_ident' => 'winter',
],
Key Type Required Default Description
level Monolog\Level yes Minimum level; records below it are discarded.
format 'line' | 'json' yes Output format. See below.
output see targets yes Where records are written.
file_path string|null when output=file null Absolute path to the log file.
file_max int no 30 Max rotated files to keep.
syslog_ident string no 'winter' Syslog process identifier.

Config is passed in, never derived

The library never resolves these values from the environment. The framework builds the config and passes it to LoggerManager. See Framework integration.

Output targets

The output value selects the Monolog handler (built by HandlerFactory):

output Handler Notes
stdout SafeStreamHandler('php://stdout') Swoole, CLI.
stderr SafeStreamHandler('php://stderr') FPM — safe from broken pipe.
syslog SyslogHandler Docker / Kubernetes centralized logging. LOG_USER facility.
file RotatingFileHandler Requires file_path; rotates daily (Y-m-d), keeps file_max files, uses locking.
null NullHandler Discards everything — useful in tests.

An unknown output, or output=file without file_path, throws InvalidArgumentException.

FPM + stdout = broken-pipe risk

Under PHP-FPM, php://stdout is the FastCGI response stream to nginx/Apache. If the client disconnects, writing to it can SIGPIPE the worker. Use stderr for FPM — it goes to FPM’s error_log, independent of the client. Full explanation: Output & broken pipe.

Formats

Selected by format (built by FormatterFactory):

format Formatter Use
line SpringLineFormatter Human-readable single line — terminals, dev, tailing logs.
json Monolog JsonFormatter Newline-delimited JSON — Loki, Elasticsearch, Datadog.

The exact line anatomy and level labels are in Log format.

Syslog and trailing newlines

When output is syslog, the manager builds the formatter with appendNewline = false — syslog frames each message itself, so an extra trailing newline would emit a spurious empty record. For every other output the formatter appends \n. This is handled automatically; you don’t configure it.

Example — multiple channels

php
use Monolog\Level;

$channels = [
  'sys'  => ['level' => Level::Warning, 'format' => 'line', 'output' => 'stderr',
             'file_path' => null, 'file_max' => 30, 'syslog_ident' => 'winter'],
  'http' => ['level' => Level::Info,    'format' => 'json', 'output' => 'syslog',
             'file_path' => null, 'file_max' => 30, 'syslog_ident' => 'winter'],
  'job'  => ['level' => Level::Debug,   'format' => 'line', 'output' => 'file',
             'file_path' => '/var/log/app/job.log', 'file_max' => 7, 'syslog_ident' => 'winter'],
];