thinkphp 8.0 日志需按业务通道(如 pay、access、energy)结构化分流,sql 与 error 日志独立落地并启用 apart_level,cli 命令末尾强制 log::save(),错误日志对接 filebeat 或 mqtt 实时告警。

ThinkPHP 8.0 的日志拆分不是简单“按天切文件”,而是要让不同业务、不同风险级别的日志可隔离、可监控、可告警。关键不在数量,而在结构化和可响应性。
按通道精准分流,避免混杂
不要把所有日志塞进一个 file 通道。应为关键模块单独建通道,比如支付、门禁、能耗各一个:
- 在
config/log.php的channels中显式声明'pay'、'access'、'energy'等通道,type首字母大写('File'),path以/结尾(如runtime_path('log/pay/')) - 每个通道配独立
level,例如'pay' => ['info', 'error']记交易流水,'access' => ['warning', 'error']只收异常通行事件 - 调用时用
Log::channel('pay')->info(...),不声明通道则走默认,避免日志归属模糊
SQL 与错误日志必须独立落地
SQL 日志和错误日志是排障第一线索,不能依赖全局 level 控制:
- 启用
apart_level:在 file 通道配置里加'apart_level' => ['sql', 'error'] - 注意
sql级别只在APP_DEBUG = true时生效,开发环境开启,生产环境关闭——但error仍需同时列入全局level才会写入主日志 - 确保
runtime/log/error/目录存在且 PHP 进程可写,否则error.log不会生成
CLI 命令日志必须手动落盘
定时任务、自定义命令(如能耗采集脚本)的日志容易丢失,因为没有请求生命周期触发自动保存:
- 所有 CLI 命令逻辑末尾必须加
Log::save() - 更稳妥写法是
try { ... } finally { Log::save(); },确保异常退出也能刷出已记录内容 - 调试时先验证路径可写:
is_writable(runtime_path('log/')),再执行Log::info('test')->save()看是否生成文件
对接运维告警链路
日志只是原始数据,告警才是闭环动作。重点不是“有日志”,而是“有人看到”:
- 对
error和critical级别日志,用 Filebeat 或自研脚本监听runtime/log/error/*.log,提取含[db_connect_fail]、[mqtt_timeout]等标记的行 - 结构化字段(如
host=10.0.1.5 code=1040 msg="Too many connections")便于 ELK 提取指标或 Prometheus 抓取 - 门禁连续失败 5 次、能耗突增超基线 2σ 等事件,应在 MQTT 订阅服务内判断后直接推告警队列,不依赖日志轮询
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











