python - 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 文件,并释放磁盘空间。
解决方案
您正在寻找一种copytruncate
选择。这就是文件系统的工作方式。当进程打开文件的描述符并且您将删除该文件(例如从命令行)时,描述符仍将在内存中可用(通过inode
)。所以copytruncate
只会复制您的日志文件,并且当前打开的日志文件(与 gunicor 连接)将截断为 0。
推荐阅读
- multithreading - 当多个线程试图同时访问一个临界区时会发生什么?
- swift - 备用临时上下文中的 Swift 错误:错误:加载模块“AppName”失败
- python - python“pip”是否应该始终保持最新版本?
- vue.js - Vue / Buefy Datetimpciker:如何将 vue 组件的结果提交到表单?
- python-3.x - 我可以让我的用户输入接受 int 或 string 值吗?(Python)
- python - Neopixel 在运行动画时改变亮度
- clone - 关于 CREATE TABLE ... CLONE {COPY GRANTS} 行为的问题
- r - R - 生成一个图而不显示它
- node.js - 如何在集合中查找在其字段中包含特定表达式的文档?
- vue.js - 如何在 kendo-map-marker 中呈现地理点列表