ThinkPHP 6 定时任务日志必须显式配置,需重定向至带时间戳的独立文件、设置专用 cron 日志通道、按级别过滤、物理隔离 Web 与 CLI 日志、记录结构化上下文及外部依赖健康状态。

ThinkPHP 6 的定时任务日志不能靠“猜”或“默认”,必须主动设计、显式配置。关键不是记不记,而是记得准、查得快、不丢漏——尤其在 crontab 触发 + CLI 环境下,日志路径、级别、写入时机稍有偏差,失败就无声无息。
日志必须重定向到文件,且带时间戳分隔
crontab 不继承 shell 环境,不走 TP 的 runtime/log/ 自动归档逻辑。直接执行 php think sync:order 而不重定向,日志会丢失或混入系统输出。
- 在 crontab 中强制用
>>追加并捕获错误:* * * * * /www/server/php/74/bin/php /var/www/myapp/think sync:order >> /var/www/myapp/runtime/log/cron/sync_`date +\%Y\%m\%d`.log 2>&1 - 推荐在命令类内部也调用
trace()或Log::info()写入专用通道,例如:Log::channel('cron')->info('订单同步开始', ['count' => $total]); - 为 cron 单独配一个 log 通道,在
config/log.php中新增:'cron' => ['type' => 'File', 'path' => runtime_path() . 'log/cron/', 'apart_level' => ['info', 'error']]
按级别过滤,避免日志爆炸又漏关键错误
TP6 默认记录所有级别,但定时任务只需关注 info(成功标记)、warning(异常但可恢复)、error(中断性失败)。其他如 debug 在生产环境应关闭。
- 在 cron 专用通道中设置
'level' => ['info', 'warning', 'error'],不匹配的自动丢弃 - SQL 日志单独开关:若需排查慢查询,临时开启
'sql'级别,但切勿长期开启(性能损耗大) - 对失败任务补一条结构化 error 日志,包含任务类名、数据 ID、错误堆栈前 200 字符,方便快速定位重试源头
区分场景:CLI 日志 ≠ Web 日志,通道要隔离
Web 请求日志和定时任务日志混在一起,会导致检索困难、磁盘暴涨、敏感信息交叉泄露。必须物理隔离通道与目录。
- 不要复用
file默认通道;新建cron和queue两个独立通道,各自指定path - 启用
'single' => true仅适用于调试阶段(如单次手动触发);生产环境务必用日期子目录 +'apart_level'拆分,例如:'info.log'、'error.log'分开存储 - 队列消费日志建议额外加字段标识进程 PID 和队列名,例如:
Log::channel('queue')->info("job processed", ['job' => 'CancelOrderJob', 'pid' => getmypid(), 'queue' => 'order'])
失败日志必须含上下文,不能只写“执行失败”
静默失败是定时任务最大隐患。一句 Log::error('执行失败') 毫无价值;真正有用的是:谁触发的?传了什么参数?卡在哪一行?Redis 是否连通?
- 在命令类
handle()开头记录完整输入:Log::info('sync:order start', ['params' => $this->input->getOptions()]) - 捕获异常时,记录原始异常消息 + 数据快照(脱敏后):
Log::error('sync:order failed', ['data_id' => $order->id, 'msg' => $e->getMessage(), 'line' => $e->getLine()]) - 对 Redis、MySQL 等外部依赖做健康检查日志,例如连接失败时写:
Log::warning('redis unavailable', ['host' => config('redis.host')])
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











