Gunicorn在日志轮换后保留旧日志

3 投票
2 回答
4317 浏览
提问于 2025-04-18 09:18

我正在使用 logrotated 来轮换 gunicorn 的访问日志。这是我的 logrotated 配置

/opt/api/log/access.log {
    daily
    rotate 10
    missingok
    notifempty
    compress
    sharedscripts
    postrotate
        killall -s USR1 gunicorn
    endscript
}

日志轮换得很顺利,文件被压缩了,还生成了一个新的 access.log 文件。不过,gunicorn 并没有释放对旧日志文件的“指针”,所以轮换后其实并没有释放磁盘空间。

我可以通过 lsof 命令看到旧日志文件的相关信息。

如果我执行 initctl restart api,gunicorn 会重启,这样磁盘空间才会真正释放。

有没有比重启服务更干净的方法来释放磁盘空间呢?

2 个回答

1

我自己回答一下,看来我遇到了这个错误:https://github.com/benoitc/gunicorn/issues/627

这个问题有解决办法,但还没有在新版本中发布。

3

通常,Linux系统中的进程会接收一个特殊的信号,用来通知它们日志文件的轮换。在这种情况下,你是向系统中所有的gunicorn进程发送SIGUSR1信号。

这里有几个问题:

  • 你的系统中是否有这样的进程在运行?

  • gunicorn进程是否能接受SIGUSR1信号?

根据gunicorn的源代码,发送SIGUSR1确实应该会让日志轮换。

...所以我怀疑可能是killall没有把命令发送给正确的进程。

要确认这一点,可以用ps命令查看你的进程列表。如果找到了gunicorn进程,可以修改workers/base.py文件,添加一条日志记录,看看它们是否收到了信号。试着手动发送这个信号,如果成功了,那就说明是日志轮换的配置出了问题,没能正常工作。

撰写回答