Hyperf 必须显式配置 RotatingFileHandler 并设 maxFileSize=0、filenameFormat 含 {date}、maxFiles 指定保留数量,才能实现按天切分;否则因默认按大小轮转且忽略日期占位符,导致日志混杂、假轮转。

Hyperf 默认的 StreamHandler 不切分日志,文件会无限增长,必须显式切换为 RotatingFileHandler 并禁用按大小切分,才能稳定实现「按天切分 + 保留 N 天」的目标。
为什么 RotatingFileHandler 默认不按天切分?
Monolog 的 RotatingFileHandler 默认触发条件是「单文件超过 maxFileSize」,而非日期变更。Hyperf 配置中若没显式移除或设为 0,它就会忽略 {date} 占位符,导致日志名带日期但内容仍混在旧文件里——你看到的是假轮转。
- 检查
config/autoload/logger.php中 handler 的constructor是否含'maxFileSize' => 0或直接删掉该键 - 确认
'filename' => BASE_PATH . '/runtime/logs/access.log'是基础路径,不是带{date}的完整路径(那是filenameFormat的事) -
RotatingFileHandler的filenameFormat必须显式配置,否则用默认格式,可能不含日期或格式难追溯
按天切分的关键配置项怎么填?
只改 class 不够,RotatingFileHandler 的行为由三个参数联合控制:文件名模板、保留数量、是否启用日期占位符。缺一不可。
-
'class' => Monolog\Handler\RotatingFileHandler::class—— 必须指定这个类,不能写错命名空间 -
'filenameFormat' => 'access-{date}.log'——{date}会被自动替换为Y-m-d格式,如access-2026-05-18.log -
'maxFiles' => 30—— 表示最多保留 30 个日期文件,超出的自动删除(注意:不是 30 天,是 30 个文件) - 删掉或设为
0的maxFileSize,否则它会在当天内因大小触发额外切割,破坏日期一致性
多通道切分时 channel 名和配置键必须严格匹配
Hyperf 日志工厂通过 $loggerFactory->get('access', 'access') 获取 logger,第一个参数是 channel 名(用于上下文标识),第二个参数才是 config/autoload/logger.php 中 channels 下的键名。两者不一致会导致 fallback 到 default 配置,切分失效。
- 例如定义了
'channels' => ['access' => [...]],就必须用get('access', 'access'),不能写成get('access', 'file') - 如果想复用同一套 handler 配置但输出到不同路径,应复制整个 channel 配置块,改
filename和filenameFormat,不要共用键名 - 运行时调用
setLevel()不影响切分逻辑,但会影响哪些日志被写入——若设为ERROR,则INFO级别不会落盘,自然也不会参与轮转
最易被忽略的是 maxFileSize 的残留值和 filenameFormat 的缺失——这两个点不处理,哪怕写了 RotatingFileHandler,日志也照旧越滚越大。切分不是“开了就灵”,而是三个参数咬死配合的结果。


















