php日志规范化核心是按业务模块设独立monolog通道(如error、access、payment),各通道logger绑定专属handler并配置minlevel/maxlevel精准分流,es日志必须用jsonformatter结构化上下文,文件轮转依场景选rotatingfilehandler或dailyrotatingfilehandler。

PHP项目日志规范化,核心是用好Monolog的通道(Channel)与级别(Level)机制:不同业务模块走独立通道,同一通道内按级别分流到不同目标(如error.log只存ERROR及以上,debug.log接收DEBUG级),避免日志混杂、检索困难、权限失控。
每个通道配独立Logger实例,不复用同一个对象
常见错误是创建一个$logger = new Logger('app'),再连续pushHandler()文件和ES处理器——结果所有级别日志都进ES,debug信息污染告警系统,error日志又散落在多个文件里。
- 正确做法:为关键通道分别初始化Logger,例如
$errorLogger = new Logger('error')、$accessLogger = new Logger('access')、$paymentLogger = new Logger('payment') - 每个Logger只绑定它该处理的Handler:比如
$errorLogger推RotatingFileHandler('error.log', Logger::ERROR)和ElasticsearchHandler;$accessLogger只推DailyRotatingFileHandler('access.log', Logger::INFO) - 通道名即Logger名,也是后续在代码中获取实例或注入时的标识,如Symfony中
logger.error对应error通道
日志分级必须由Handler自身控制,不是靠Logger级别
Logger的构造级别(如new Logger('app', Logger::WARNING))只影响该Logger实例是否接受某条日志;真正决定“这条日志要不要写进某个文件/ES”,得看Handler配置的minLevel和maxLevel。
-
RotatingFileHandler('app.log', Logger::INFO):只写INFO及以上,DEBUG被自动过滤 -
RotatingFileHandler('debug.log', Logger::DEBUG):接收全部调试日志,但需确保它不被其他高优先级Handler拦截 - 若用单Logger+多Handler方案,必须用
FilterHandler包裹每个目标Handler,并显式设置minLevel/maxLevel,否则级别控制失效
结构化上下文统一用JsonFormatter,尤其对接Elasticsearch
发往Elasticsearch的日志若仍是纯文本(如LineFormatter输出),trace_id、user_id、request_id等字段全塞在message里,无法做聚合、筛选、可视化。
- 所有发往ES的Handler必须使用
JsonFormatter,且确保上下文数组键名规范,如['trace_id' => 'xxx', 'user_id' => 123] - 文件类Handler可选
LineFormatter便于人工排查,但建议生产环境也统一用JsonFormatter,保持结构一致 - 搭配
UidProcessor、WebProcessor等自动注入请求ID、IP、URL等,避免每个info()手动传重复字段
轮转策略按场景选型:大小切分 or 日期切分
RotatingFileHandler适合高吞吐服务(如API网关),单文件达10MB就切;DailyRotatingFileHandler更适合审计类日志(如login、payment),每天一个文件更易归档与排查。
-
DailyRotatingFileHandler务必设setFilenameFormat('{filename}-{date}', 'Y-m-d'),避免默认命名导致新旧日志混淆 -
RotatingFileHandler第二个参数是保留归档数(如5),它会删掉最老的.1~.5,不是清空整个目录 - Linux下确认
/var/log/your-app/对PHP运行用户(如www-data)有rwx权限,否则轮转时mkdir()失败
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











