如何记录 cron 定时任务的执行日志?
记录 cron 日志的核心:在命令尾部加 >> /path/to/logfile 2>&1 重定向输出到文件,配 logrotate 做轮转。也可用 logger 命令写入 syslog。
最基本的做法:在 crontab 的命令末尾加 >> /path/to/logfile 2>&1,把标准输出和标准错误都写入日志文件。再加 logrotate 防止日志无限增长。
方法一:输出重定向(最常用)
# 每天凌晨 2 点执行备份,日志写入文件
0 2 * * * /home/user/backup.sh >> /var/log/backup.log 2>&1
>>追加写入(>是覆盖);2>&1把错误输出也合并到同一个文件。
建议在脚本内部打印时间戳,便于事后定位:
#!/bin/bash
echo "$(date '+%Y-%m-%d %H:%M:%S') 开始备份"
/path/to/actual-backup-command
status=$?
echo "$(date '+%Y-%m-%d %H:%M:%S') 备份结束,exit_code=$status"
exit "$status"
核查执行结果时,将任务名、运行标识和退出码写入日志。按 DataKit 日志采集指南接入观测云后,先确认一轮任务的开始和完成记录都能找到;日志没有更新时,还要区分任务未运行、任务无输出和采集异常。
方法二:写入 syslog
0 2 * * * /home/user/backup.sh 2>&1 | logger -t backup
logger 将输出交给系统日志服务,实际目的地由配置决定,不保证是 /var/log/syslog 或 rsyslog。管道默认返回最后一个命令的状态,不等于备份状态;需要保留退出码时在 Bash 脚本中用 backup-command 2>&1 | logger -t backup 后立即读取 status=${PIPESTATUS[0]} 并 exit "$status"。
方法三:logrotate 防止日志膨胀
# /etc/logrotate.d/backup
/var/log/backup.log {
daily
rotate 7
compress
missingok
notifempty
}
轮转规则需由调度器实际执行 logrotate;长时间保持打开文件的任务还需处理重开文件,不能认为 daily 配置会自行触发。
常见问题(FAQ)
Q:cron 本身有日志吗?
A:有。cron 守护进程的记录在 /var/log/syslog(Debian/Ubuntu)或 /var/log/cron(CentOS/RHEL)中,记录"什么时候执行了哪个任务",但不包含脚本输出。
Q:脚本没输出也没报错,但任务似乎没执行?
A:cron 环境较精简,通常有有限的默认 PATH,但与交互shell不同,脚本里要用命令的绝对路径;另外检查 % 字符需要转义为 \%。
Q:如何知道任务执行失败?
A:脚本失败时记录错误原因和退出码,并返回非零状态。后续检查应按任务名和运行标识匹配,不能把没有新日志直接等同于执行失败。