1.7.6 计划任务日志与故障排查

计划任务日志与故障排查重点在于确认任务是否被调度、是否执行成功以及输出是否可追踪。排查应形成“调度记录 → 执行日志 → 运行环境 → 权限与安全”的闭环,并为关键任务显式定义日志路径与格式,便于统一检索与留存。

原理草图(日志与排查路径):

文章图片

常见日志来源与定位命令(含解释):

# 1) 查看 cron 调度记录(RHEL/CentOS)
grep CRON /var/log/cron

# 2) Ubuntu/Debian 常用位置
grep CRON /var/log/syslog

# 3) systemd 定时器与服务日志
journalctl -u backup.timer --since "today"
journalctl -u backup.service -n 50 --no-pager

# 4) 用户邮件输出(若 MAILTO 生效)
sudo ls -l /var/spool/mail/
sudo tail -n 50 /var/spool/mail/$USER

# 5) 审计与 SELinux(排查权限拒绝)
sudo ausearch -m avc -ts recent
sudo grep denied /var/log/audit/audit.log | tail -n 20

标准化任务日志示例(含输出与错误重定向):

# /etc/cron.d/backup  示例:每天 02:30 执行备份
# 分 时 日 月 周 用户 命令
30 2 * * * root /usr/local/bin/backup.sh >> /var/log/backup/backup.log 2>&1

配套脚本示例(统一日志头、PATH、锁文件、超时):

#!/bin/bash
# /usr/local/bin/backup.sh
set -euo pipefail

export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

LOG_DIR="/var/log/backup"
LOCK_FILE="/var/run/backup.lock"
mkdir -p "$LOG_DIR"

{
  echo "==== $(date '+%F %T') host=$(hostname) task=backup ===="
  # 防并发:如果已锁定则退出
  exec 9>"$LOCK_FILE"
  flock -n 9 || { echo "backup already running"; exit 1; }

  # 执行命令(示例)
  tar -czf /data/backup/$(date +%F).tar.gz /etc

  echo "backup ok"
} >> "$LOG_DIR/backup.log" 2>&1

systemd 定时器示例与日志定位:

# /etc/systemd/system/backup.service
[Unit]
Description=Daily backup service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# /etc/systemd/system/backup.timer
[Unit]
Description=Daily backup timer

[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true

[Install]
WantedBy=timers.target
# 启用并查看状态与日志
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers | grep backup
journalctl -u backup.timer -n 20
journalctl -u backup.service -n 50

典型故障与排查步骤(含命令解释):

# 1) 任务未触发:服务状态与语法校验
systemctl status crond        # 确认 cron 服务是否运行
crontab -l                    # 查看当前用户任务
crontab -u root -l            # 查看指定用户任务

# 2) 时间与时区检查
timedatectl                   # 时区与时间同步状态
date                          # 当前系统时间

# 3) 环境变量缺失导致命令找不到
env -i /bin/bash -lc '/usr/local/bin/backup.sh'
# 若此处失败,说明依赖环境变量或路径

# 4) 权限问题检查
ls -l /usr/local/bin/backup.sh
sudo -u root /usr/local/bin/backup.sh   # 以任务用户手动执行

日志轮转建议(避免日志占满磁盘):

# /etc/logrotate.d/backup
/var/log/backup/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    copytruncate
}

排错案例演练(最小复现):

# 1) 创建一个每分钟写日志的测试任务
echo '* * * * * /usr/bin/date >> /var/log/cron_test.log 2>&1' | crontab -

# 2) 观察调度与输出
sleep 70
tail -n 3 /var/log/cron_test.log
grep CRON /var/log/cron | tail -n 3

练习与自检:
1. 将测试任务改为使用相对路径(如 date),观察是否执行失败并解释原因。
2. 配置一个 systemd timer,并验证 OnCalendarPersistent 的行为差异。
3. 人为移除脚本执行权限,定位故障日志与修复步骤。
4. 为关键任务添加锁文件并模拟并发触发,验证锁机制效果。