Monolog日志级别是PSR-3语义级别,非PHP错误级别映射;需通过handler的level与channels组合实现分流,如emergency handler设level: emergency,error handler设level: error,并显式配置错误处理器转发PHP原生错误。

Monolog 的日志级别不是 PHP 错误级别的映射
很多人以为 error 级别会自动捕获 E_ERROR,其实不是。Monolog 的 DEBUG、ERROR、CRITICAL 等是 PSR-3 定义的语义级别,和 PHP 原生的 E_ERROR、E_WARNING 无直接转换关系。你调用 $logger->error(),它就记为 ERROR 级别;PHP 运行时抛出的 E_WARNING 不会自动变成 Monolog 日志——除非你显式配置了错误处理器(如 set_error_handler)并转发给 Logger。
如何让不同严重性错误写入不同文件
靠 level + channels 组合分流,不是靠“自动识别 PHP 错误类型”:
- 在
config/packages/prod/monolog.yaml中定义多个 handler,各自指定level -
emergencyhandler 设为level: emergency,只收最严重问题 -
errorhandler 设为level: error,收ERROR及以上(即ERROR、CRITICAL、ALERT、EMERGENCY) - 用
channels隔离来源:比如把数据库异常路由到doctrine通道,再单独配 handler - 避免把
debug级别日志写进生产环境主文件——它可能包含敏感变量值
PHP 8.5.7 下容易漏掉的错误级别陷阱
PHP 8.5.7 默认 error_reporting 可能不包含 E_DEPRECATED 或 E_USER_DEPRECATED,而 Monolog 不会自动补全这些。结果就是:弃用警告不会出现在日志里,除非你手动加:
- 确保 php.ini 中
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT(若需追踪弃用项,去掉& ~E_DEPRECATED) - 在 Symfony 中启用
php_errors通道,并配一个 handler 专门收WARNING级别(因为E_DEPRECATED在 PSR-3 中映射为WARNING) -
RotatingFileHandler的level参数必须用常量,比如\Monolog\Logger::WARNING,不能传字符串'warning' - 如果用了
FingersCrossedHandler,注意它的activation_strategy默认只对ERROR及以上触发——WARNING不会激活,也就不会写入
真正影响分级效果的是 handler 的 level 和 channel 过滤逻辑
配置写得再细,如果 handler 没 push 到对应 logger 实例上,或者 channel 名写错一个字母,日志就静默丢弃。验证方式很简单:
立即学习“PHP免费学习笔记(深入)”;
- 在控制器里临时写:
$this->logger->critical('test critical');和$this->logger->warning('test warning'); - 查对应日志文件是否出现——别只看
var/log/prod.log,确认你实际查看的是该 handler 指向的path - 用
tail -f实时观察,比翻旧文件快得多 - Symfony 的
monolog.handler.main服务默认只处理main通道;自定义通道(如payment)必须显式声明并注入对应LoggerInterface



















