ThinkPHP 6 默认不记录定时任务执行历史,需开发者主动实现日志与数据库记录;应在 execute() 中统一埋点写入结构化日志及 cron_task_log 表,并分层管理定时触发与队列执行历史。

ThinkPHP 6 本身不记录定时任务的执行历史,所谓“任务执行历史”必须由开发者主动设计、存储和查询——它不是框架内置功能,而是高阶运维能力的体现。
为什么默认没有执行日志?
TP6 的命令行命令(如 php think sync:order)在 CLI 环境下运行,若未显式写入日志,stdout/stderr 会被系统丢弃;crontab 默认也不保存输出。这意味着:没写日志 = 没痕迹 = 无法追溯失败、重试、耗时等关键信息。
必须手动构建可追溯的日志体系
推荐在每个自定义命令的 execute() 方法开头和结尾统一埋点:
- 用
Log::channel('cron')->info()写结构化日志,包含命令名、开始时间、参数摘要、结束状态、耗时(ms) - 日志文件建议按天分离,例如:
runtime/log/cron/sync_order_20260806.log - 捕获异常时,必须用
Log::channel('cron')->error()记录完整堆栈,不能只echo或忽略 - 避免使用
trace()默认通道,它可能因环境配置差异静默失效
进阶:落地为数据库记录表
仅靠文件日志难检索、难告警、难聚合。高阶做法是建一张 cron_task_log 表,字段至少包括:
-
command:命令全名(如sync:order) -
status:success / failed / timeout -
started_at/ended_at -
duration_ms:执行耗时,用于性能监控 -
output_preview:截取前 200 字节关键输出(如影响行数、错误摘要) -
exit_code:CLI 进程退出码,非 0 即失败
在 execute() 中用 Db::table('cron_task_log')->insert(...) 主动写入,确保无论成功失败都有记录。
配合队列时的历史对齐
当定时任务只是“触发器”,真正业务走队列(如 Queue::push('app\job\SyncOrderJob', $data)),执行历史需分层管理:
- 定时任务层:记录“是否成功推送”,推送时间、数据量、队列名
- 队列任务层:Job 类中
fire()开头写Log::channel('queue')->info(),结尾调用$job->delete()前再记一次完成态 - 两者通过唯一标识(如
trigger_id = date('YmdHis').rand(1000,9999))关联,便于全链路排查
不复杂但容易忽略。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











