Webman默认日志不按天分割,因Monolog原生StreamHandler仅支持固定路径,date()或%Y等时间占位符在进程启动时仅计算一次,无法动态切文件;须改用MonologExtendHandler自定义处理器,按日期自动创建新文件并轮转。

Webman 默认日志不按天分割,必须手动替换 MonologHandler 并配置自定义处理器——直接改 config/log.php 里的路径加日期占位符(如 webman_%Y-%m-%d.log)完全无效,PHP 和 Monolog 都不解析这些变量。
为什么默认配置不支持按天分割
Webman 日志底层用的是 Monolog,而标准 Monolog\Handler\StreamHandler 只接受固定文件路径,不感知时间变化。即使你在配置里写 'filename' => runtime_path() . '/logs/webman_' . date('Y-m-d') . '.log',也只会在进程启动时计算一次,之后所有请求都往同一个文件写,第二天不会自动切。
常见错误现象包括:
- 日志文件名带
%Y或date()函数,但实际生成的文件名是字面量(如webman_date('Y-m-d').log) - 日志持续追加到一个巨大文件,
runtime/logs/目录下始终只有一个webman.log - 手动 touch 新文件后,PHP 进程仍往旧句柄写,新文件空着不动
正确做法:用 MonologExtendHandler 替代原生 Handler
Webman 官方推荐方案是继承 StreamHandler,重写 write() 和 close(),在每次写入前检查当前日期是否变化,必要时关闭旧文件、打开新文件。这个类已在框架 support/log/MonologExtendHandler.php 中提供(需自行创建)。
立即学习“PHP免费学习笔记(深入)”;
关键点:
-
MonologExtendHandler构造函数第 1 个参数是 channel 名(如'api'),它会参与生成文件名:api_2026-05-22.log - 第 2 个参数是单文件最大大小(字节),超限会自动轮转,和「按天」逻辑正交,可同时启用
- 必须确保
runtime/logs/目录存在且 PHP 进程有写权限,否则静默失败 - 不要在
config/log.php中给多个 channel 复用同一个MonologExtendHandler实例,每个 channel 应独立初始化
config/log.php 配置示例与易错项
在 config/log.php 中,channel 的 handlers 必须指向你自己的类,并传入正确的构造参数:
'default' => [
'handlers' => [
[
'class' => \support\log\MonologExtendHandler::class,
'constructor' => [null, 10 * 1024 * 1024, \Monolog\Logger::DEBUG, true, 0755],
'formatter' => [
'class' => \Monolog\Formatter\LineFormatter::class,
'constructor' => [null, 'Y-m-d H:i:s', true, true],
],
],
],
],
注意:
-
constructor数组中第 1 项为null表示使用默认 channel 名(即default),生成文件名为default_2026-05-22.log - 若设为
'api',则文件名是api_2026-05-22.log,别漏掉引号,写成api会报类未找到 -
0755是创建目录的权限,不是文件权限;日志文件本身权限由系统 umask 决定,通常为0644 - 修改配置后必须重启 Webman:
php start.php restart,热更新不生效
验证是否生效及排查路径问题
最直接的验证方式是等待午夜或手动修改系统时间(仅测试环境),然后观察 runtime/logs/ 下是否出现新日期文件。但更稳妥的做法是主动触发:
- 清空
runtime/logs/目录,执行php start.php start -d启动,立刻看是否生成default_2026-05-22.log - 检查 PHP 进程用户(如
www)对runtime/logs/是否有写权限:ls -ld runtime/logs - 确认
MonologExtendHandler.php文件路径拼写准确,命名空间是support\log,且文件已加载(无 fatal error) - 如果日志仍不出现,临时把
MonologExtendHandler::write()开头加file_put_contents('/tmp/debug.log', print_r($record, 1) . "\n", FILE_APPEND)看是否被调用
真正容易被忽略的是:MonologExtendHandler 类里 $this->mustRotate 的判断逻辑依赖 filemtime(),如果服务器时间跳变(如 NTP 校准),可能导致误判;生产环境务必保证系统时间稳定。



















