You need to enable JavaScript to run this app. 基于CherryPy的Python服务部署为systemd后日志无法轮转的问题
优惠活动
大模型
产品
解决方案
定价
更多

基于CherryPy的Python服务部署为systemd后日志无法轮转的问题

systemd环境下Python日志轮转失效的原因与解决方案

核心原因分析

  • 时区环境差异:交互shell/screen启动的进程会加载用户目录下的.bashrc、.profile等配置,通常会显式设置TZ时区变量;而systemd启动的系统服务默认不加载用户shell配置,仅使用系统全局时区(由/etc/localtime定义)。
    这是最高发的诱因:如果你平时用的时区是Asia/Shanghai,但系统全局时区是UTC,那么systemd下的进程认知的“午夜”是UTC的0点(即北京时间早上8点)。你以为跨了现实中的午夜,但进程实际还要再过8小时才会触发轮转,表现为“不轮转”。
  • 运行用户与环境变量缺失:你提供的单元文件没有指定User/Group,默认会用root身份启动服务,而非平时使用的ubuntu用户。脚本依赖的HOME、PYTHONPATH等用户级环境变量会指向root的主目录(/root),可能导致配置加载异常、时区配置读取错误,间接影响轮转逻辑。
  • 轮转触发条件未满足:Python原生的TimedRotatingFileHandler只有在有新日志写入时,才会检查是否到达轮转时间阈值。如果服务跨午夜的时段恰好没有任何日志输出,轮转动作会被推迟到下一次写日志时才执行,长时间无日志时就会看起来像“从未轮转”。

对应解决方法

  • 统一时区配置:二选一即可:
    1. 在单元文件的[Service]段添加显式时区配置:Environment=TZ=你的时区标识(比如Asia/Shanghai),直接给进程指定时区,不依赖系统全局配置。
    2. 修改系统全局时区:执行timedatectl set-timezone 你的时区标识,统一所有系统服务的时区。

    验证方法:可以在[Service]段临时添加ExecStartPre=/usr/bin/date,启动服务后用journalctl -u 你的服务名查看输出的时间,和交互shell下的date结果对比,确认时区是否一致。

  • 显式指定运行用户:在[Service]段添加配置,让服务和平时screen下用同一个用户运行:
    User=ubuntu
    Group=ubuntu
    Environment=HOME=/home/ubuntu
    
    避免用户环境变量、权限的差异问题。
  • 适配轮转触发逻辑:
    如果确认跨午夜后有新日志仍不轮转,且时区、用户都没问题,可以测试手动触发一条日志,看是否会立即轮转。如果需要不依赖日志写入的定期轮转,可以替换为第三方的ConcurrentLogHandler,它的内置后台线程会主动按时间检查轮转。
  • 完善单元文件配置:补充必要的运行规则,避免其他异常:
    Restart=on-failure
    StandardOutput=journal
    StandardError=journal
    

修复后的完整单元文件示例

[Unit]
Description=RCS API Server
After=multi-user.target

[Service]
Type=simple
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/rcs-sender/
Environment=TZ=Asia/Shanghai
ExecStart=/usr/bin/python3 /home/ubuntu/rcs-sender/rcs_api_server.py
Restart=on-failure
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.02 16:36:02