Python 脚本的日志怎么做才不会把磁盘写满

举报
yd_262967087 发表于 2026/10/27 06:00:50 2026/10/27
【摘要】 长期运行的脚本如果只用 print 或简单写文件,几个月后日志能吃掉几十 G。这篇讲 logging 的正确配置、按大小切割、以及保留策略。

一、别用 print 当日志

`print` 没有级别、没有时间戳、不能重定向。用标准库 `logging`:


import logging

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s [%(levelname)s] %(message)s",
    datefmt="%Y-%m-%d %H:%M:%S",
)
log = logging.getLogger(__name__)
log.info("started")

二、按大小切割

`RotatingFileHandler` 是最省心的方案:


from logging.handlers import RotatingFileHandler

handler = RotatingFileHandler(
    "/var/log/myapp/app.log",
    maxBytes=10 * 1024 * 1024,   # 10 MB
    backupCount=5,                # 最多保留 5 个历史文件
    encoding="utf-8",
)
handler.setFormatter(logging.Formatter(
    "%(asctime)s [%(levelname)s] %(message)s"))

log = logging.getLogger("app")
log.addHandler(handler)
log.setLevel(logging.INFO)

这样最多占用 60 MB(6 个文件 × 10 MB),不会无限增长。

三、按天切割

如果需要按日期归档,用 `TimedRotatingFileHandler`:


from logging.handlers import TimedRotatingFileHandler

handler = TimedRotatingFileHandler(
    "/var/log/myapp/app.log",
    when="midnight",
    interval=1,
    backupCount=7,      # 保留 7 天
    encoding="utf-8",
)

注意 `when="midnight"` 是按**服务器本地时区**切的。如果服务跑在 UTC 而你在东八区,切割时间会差 8 小时。要么统一时区,要么用 `utc=True` 并自己换算。

四、systemd 服务的日志

如果服务由 systemd 管理,可以直接让 systemd 接管:


StandardOutput=append:/var/log/myapp/app.log
StandardError=append:/var/log/myapp/app.log

但这样没有切割。两种做法:

1. 用 `logrotate` 定期切

2. 让 Python 自己写文件并切割(上面两种 Handler),systemd 只接 stderr

我更倾向第二种,因为切割策略和业务逻辑在同一个地方,不容易漏配。

五、logrotate 配置示例

如果选择交给 logrotate:


/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0640 root root
    postrotate
        systemctl reload myapp 2>/dev/null || true
    endscript
}

`delaycompress` 让最新一个归档不压缩,方便直接看。

六、别把敏感信息写进日志

这是最容易忽略的。日志里绝对不能出现:

• 密码、API key、token

• 完整 cookie

• 用户身份证、手机号全号

脱敏写法:


def mask(s, keep=4):
    if not s or len(s) <= keep * 2:
        return "***"
    return s[:keep] + "*" * (len(s) - keep * 2) + s[-keep:]

log.info("token=%s", mask(token))

七、日志级别别全开

生产环境用 `INFO`,排查时临时改 `DEBUG`。全开 `DEBUG` 会让日志量涨几十倍,还可能把敏感数据打出来。

小结

日志三件事:**会切割、能查、不泄密**。用 `RotatingFileHandler` 解决第一个,用统一格式和时间戳解决第二个,脱敏函数解决第三个。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。