首页 > 解决方案 > gunicorn 进程持有对 logrotated 文件的引用,导致磁盘空间用完

问题描述

我正在使用 logrotate 来旋转 gunicorn 访问/错误日志。

{
  su root root
  missingok
  compress
  dateext
  dateformat .%Y%m%d
  notifempty
  sharedscripts
  postrotate
      # Send USR1 signal to the gunicorn master, which will cause it to reopen log files.
      # http://docs.gunicorn.org/en/latest/deploy.html#logging
      /bin/kill -USR1 $(cat /var/run/xxxx/api.pid 2>/dev/null) 2> /dev/null || true
  endscript
}

日志得到正确轮换和压缩,并创建一个新的日志文件。但是 gunicorn 不会释放指向已删除日志文件的指针,而是继续写入该日志文件。因此,磁盘上的文件空间没有被释放并且日志行丢失。

我可以看到带有 lsof 的条目

gunicorn  22284           root    9w   REG  252,1 43263609     0 117968 /usr/cachelogic/log/gunicorn_unapi_access.log-20190410 (deleted)

如果我重新启动 gunicorn 服务,文件空间将被释放,并且该进程还将日志写入新文件。但是写入已删除文件的旧日志会丢失。

我想在不重新启动服务的情况下解决 logrotate 问题。如何确保将日志写入新的日志文件而不是 logrotated 文件,并释放磁盘空间。

标签: pythongunicornlogrotate

解决方案


您正在寻找一种copytruncate选择。这就是文件系统的工作方式。当进程打开文件的描述符并且您将删除该文件(例如从命令行)时,描述符仍将在内存中可用(通过inode)。所以copytruncate只会复制您的日志文件,并且当前打开的日志文件(与 gunicor 连接)将截断为 0。


推荐阅读