You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Cron任务未执行日志轮换的问题排查求助

问题描述

我编写了一段带日志轮换功能的Python脚本:当data.log文件大小超过100KB时执行日志轮换操作。直接在周日16-17点通过命令行运行时一切正常,但通过Cron定时任务(规则00 16 * * *)运行时,仅打印「********** New execution starts **********」,虽进入logCheck函数却未完成日志轮换,此时data.log已超过1.5MB。运行环境为Red Hat Enterprise Linux Server。

脚本代码如下:

import os, sys
import os.path
from datetime import datetime

# log rotation if above 1MB
def logCheck():
    if os.path.getsize('data.log') > 100000:
        print(f'Performing log rotation')
        os.remove('data_old.log') if os.path.exists('data_old.log') else None
        os.rename('data.log', 'data_old.log')
        sys.exit(0)


print(f'********** New execution starts **********')
now = datetime.now()
if now.strftime("%A") == 'Sunday' and now.strftime("%H") == '16':
    logCheck()

print(f'Script execution starts')
***other code***

Cron任务配置:

00 16 * * * /usr/local/bin/python3 /absolute_path/script.py
问题原因及解决办法

1. 相对路径导致日志文件找不到

Cron的默认工作目录是执行用户的主目录(如/home/username),而非脚本所在的/absolute_path/。脚本中使用'data.log'这类相对路径时,Cron运行时会去主目录查找文件,自然找不到目标文件,os.path.getsize会抛出异常,但脚本未做异常捕获,直接导致函数退出,无法执行后续轮换操作。

解决方法:

  • 方法一:在脚本开头切换工作目录到脚本所在路径:
    # 脚本开头添加
    os.chdir(os.path.dirname(os.path.abspath(__file__)))
    
  • 方法二:所有文件路径使用绝对路径,例如将'data.log'改为'/absolute_path/data.log','data_old.log'同理。

2. 时区不匹配(可能性较低)

Cron使用系统默认时区,Python的datetime.now()也依赖系统时区,若系统时区与预期不一致,可能导致now.strftime("%A") == 'Sunday'判断失效。不过你提到已进入logCheck函数,这条可能性稍低,但可排查:

  • 在Cron任务中指定时区,例如添加TZ=Asia/Shanghai(替换为你需要的时区),或直接修改系统时区;
  • 在脚本中打印当前时间及时区,确认是否符合预期:
    print(f"当前时间: {now}, 时区: {datetime.now().astimezone().tzinfo}")
    

3. 权限不足

Cron执行任务的用户(默认是当前用户)可能没有data.log所在目录的读写权限,或无法删除/重命名data_old.log。

解决方法:

  • 检查/absolute_path/目录和日志文件的权限,确保Cron执行用户拥有读、写、执行权限;
  • 在Cron任务中指定有权限的用户,例如:
    00 16 * * * username /usr/local/bin/python3 /absolute_path/script.py
    

4. 未捕获异常导致无报错信息

脚本的logCheck函数未做异常处理,一旦os.path.getsize或文件操作抛出异常,会直接终止函数,且无法看到错误信息。

解决方法:

  • 给logCheck添加异常捕获,打印错误详情:
    def logCheck():
        try:
            if os.path.getsize('data.log') > 100000:
                print(f'Performing log rotation')
                if os.path.exists('data_old.log'):
                    os.remove('data_old.log')
                os.rename('data.log', 'data_old.log')
                sys.exit(0)
        except Exception as e:
            print(f"logCheck执行错误: {str(e)}")
            sys.exit(1)
    
  • 修改Cron任务,将输出重定向到日志文件以便排查:
    00 16 * * * /usr/local/bin/python3 /absolute_path/script.py >> /absolute_path/cron_script.log 2>&1
    

内容的提问来源于stack exchange,提问作者KnowledgeSeeeker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:13:30