Monolog 是独立于 Symfony 的成熟 PHP 日志库,纯项目中通过 composer require monolog/monolog 安装,用 Logger 实例配合 RotatingFileHandler(非 StreamHandler)实现按天轮转日志,并通过 LineFormatter 启用 trace 与上下文输出。

Monolog 是 PHP 里最成熟、可扩展性最强的日志库,它本身不依赖 Symfony,但 Symfony 的 symfony/debug-bundle 和 symfony/messenger 等组件默认集成了 Monolog;你不需要“实现” Monolog —— 你只需要正确配置和使用它。
怎么在纯 PHP 项目中手动引入并初始化 Monolog
别被“Symfony 组件”误导:Monolog 是独立包,symfony/logger 只是轻量接口抽象(PSR-3 兼容),实际日志逻辑仍由 Monolog 承担。直接装 Monolog 即可:
composer require monolog/monolog
初始化一个基础 logger 实例:
$logger = new \Monolog\Logger('app');
$handler = new \Monolog\Handler\StreamHandler(__DIR__.'/logs/app.log', \Monolog\Logger::DEBUG);
$logger->pushHandler($handler);
-
StreamHandler最常用,写文件;注意确保logs/目录存在且 Web 服务器有写权限 - 日志级别用常量如
\Monolog\Logger::ERROR,不是字符串'error' - 不要在循环里反复 new
Logger实例 —— 它是轻量的,但 handler 初始化有开销
为什么用 RotatingFileHandler 而不是 StreamHandler
线上环境不用 StreamHandler 直接写单个大文件,否则日志会无限增长、grep 慢、备份困难。换成按天或按大小轮转:
$handler = new \Monolog\Handler\RotatingFileHandler(
__DIR__.'/logs/app.log',
7, // 保留最近 7 天
\Monolog\Logger::WARNING
);
- 第 2 个参数是
$maxFiles,类型是int,不是字符串'7 days' - 轮转后旧日志名类似
app.log.2024-05-20,不是app.log.1(除非用MaxFilesGrowthStrategy) - 如果磁盘空间紧张,建议配合
WhatFailureGroupHandler防止 handler 失败导致静默丢日志
如何让 Monolog 输出 trace 或上下文数据
默认 $logger->error('DB timeout') 不带堆栈。加 LineFormatter 并开启 trace:
$handler->setFormatter(new \Monolog\Formatter\LineFormatter(
null, null, true, true // 第 3 个 true = include stack trace
));
- 第 4 个
true表示把上下文数组(如$logger->info('user login', ['uid' => 123]))也格式化进日志行 - trace 开销明显,只在
DEBUG或ERROR级别启用,INFO级别关掉 - 避免在上下文里传对象实例(如
$user),Monolog 会尝试__toString()或抛异常;先get_object_vars()或用array_intersect_key()过滤
Monolog 的核心复杂点不在“怎么写”,而在“怎么分发”:比如错误日志走 RotatingFileHandler,审计日志走 RedisHandler,告警日志触发 NativeMailerHandler —— 这时要靠 HandlerWrapper 或自定义 Processor 控制流向,而不是堆砌 handler。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











