python日志轮转RotatingFileHandler在django中的一个bug
简介
大量过时的日志会占用硬盘空间,甚至长时间运行不注意会占满硬盘导致宕机,那么就可以使用内建logging模块根据文件大小(logging.handlers.RotatingFileHandler)或者时间(logging.handlers.TimedRotatingFileHandler)进行日志轮转。使用细节参考python官方文档
问题
在django中使用时通常如下(只截取了RotatingFileHandler部分配置示例):
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'handlers': {
'default': {
'level':'DEBUG',
'class':'logging.handlers.RotatingFileHandler',
'filename': os.path.join(LOGDIR, LOGFILE), # 或者直接写路径:'c:\logs\all.log',
'maxBytes': 1024*1024*5, # 5 MB
'backupCount': 5,
}
}
}
以上配置时当文件大于5Mb时将当前日志重命名备份,新建一个空日志记录新日志。当备份日志达到5个时删除旧的备份文件。
当在python开发模式(manage.py runserver)时如果备份文件已经达到backupCount后会报错:
- linux下:
Traceback (most recent call last):
File "/usr/lib64/python2.7/logging/handlers.py", line 77, in emit
self.doRollover()
File "/usr/lib64/python2.7/logging/handlers.py", line 136, in doRollover
os.rename(sfn, dfn)
OSError: [Errno 13] Permission denied
Logged from file utils.py, line 89
- windows下
Traceback (most recent call last):
File "F:\Python27\lib\logging\handlers.py", line 77, in emit
self.doRollover()
File "F:\Python27\lib\logging\handlers.py", line 142, in doRollover
os.rename(self.baseFilename, dfn)
WindowsError: [Error 32]
Logged from file utils.py, line 89
原因
这是由于django开发模式时会同时启动两个进程加载settings.py,导致日志文件占用后无法重命名或者删除
都知道django开发模式下如果有文件变动会自动重新启动,所以同时又两个进程,一个是程序正常运行的进程,另一个是用来监听变更并重启服务的进程,他们都会加载一遍settings.py,可以在settings.py中加print然后启动会看到控制台又两次输出。
我怀疑使用uwsgi等wsgi程序时的多进程也会导致此问题,但是我使用uwsgi开启四个进程启动项目时未出现此错误,但并不代表没有此问题,因为我没有进行并发测试。
解决办法
开发环境
- 本地开发的话可以停止服务,然后删除旧的日志再启动
python manage.py runserver
增加 --reload参数不启用自动重启,也就不会又两个进程,但是本地开发不能自动重启稍有不便
生产环境
- 推荐使用sentry、elk或者一些集中日志服务使用socket或者http方式记录日志
As describe in other answers python manage.py runserver --noreload
will work. But here's another solution that still works with code reload.
Add this at the end of your settings.py
if DEBUG and os.environ.get('RUN_MAIN', None) != 'true':
LOGGING = {}
python manage.py runserver
starts a python process that launches your server in a child python process. Each time the parent detects a change it recreates a new child. The problem is that the log rotation by the child process fails because the parent still has a handle on that file. This solution tells the parent that there are no log file.
相关文章
- 二级Python选择题_二级python选择题题库
- python运行代码不成功_Python | PyCharm无法直接运行(Run)脚本
- 在pycharm中如何新建Python文件?_github下载的python源码项目怎么用
- python进制转换函数-Python中进制转换函数的使用
- 【Python】 【绘图】plt.figure()的使用
- Python 入门与基础《刷题篇》(3)
- Python udp编程_python socket udp
- python attrs_Python attrs作用是什么?
- python制作自动交易程序_Python如何实现自动化交易
- Python安装失败_python第三方库安装失败
- Python爬虫技术系列-03requests库案例
- python自动化测试—Python自动化框架及工具
- Python异步: 什么是异步? (2)
- Python 小案例(二)长宽表转换
- Python实现简单的web服务器详解编程语言
- python使用sqlite3的简单代码详解编程语言
- 小白的Python之路 day5 python模块详解及import本质编程语言
- Python学习:6.python内置函数详解编程语言
- 使用Python编程连接MySQL数据库(python连mysql)
- 在你的 Python 平台类游戏中放一些奖励
- Python 最快Web框架
- Python脚本实现Linux系统管理及自动化部署(python写linux)
- python驱动使用pip安装MySQL Python驱动的简单步骤(pip安装mysql)
- Linux环境下Python开发的历程(linux与python)
- 在Linux上运行Python脚本的简单指南(linux运行python)
- Linux中如何离开Python环境(linux怎么退出python)
- 如何使用Python连接MySQL数据库(mysql_connet)
- Python实现list反转实例汇总