Django使用logging模块里的时间分割和文件大小分割记录日志
问题描述:
RotatingFileHandler和TimedRotatingFileHandler在生成新的文件时,会抛出 PermissionError 异常(其它分割文件的也同样会出现)
Watching for file changes with StatReloader [INFO][2021-12-30 21:43:35,642] Watching for file changes with StatReloader --- Logging error --- Traceback (most recent call last): File "d:pythonpython3.8liblogginghandlers.py", line 69, in emit self.doRollover() File "d:pythonpython3.8liblogginghandlers.py", line 393, in doRollover self.rotate(self.baseFilename, dfn) File "d:pythonpython3.8liblogginghandlers.py", line 110, in rotate os.rename(source, dest) PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问。: 'D:\python_sxt\Envs\django\logger_study\log\logging_study_timed.log' -> 'D:\python_sxt\Envs\django\logger_study\log\logging_study_timed.log.2021-12-30_21-42-38' Call stack: File "manage.py", line 23, inmain() File "manage.py", line 18, in main execute_from_command_line(sys.argv) File "D:python_sxtEnvsdjango_envlibsite-packagesdjangocoremanagement__init__.py", line 425, in execute_from_command_line utility.execute() File "D:python_sxtEnvsdjango_envlibsite-packagesdjangocoremanagement__init__.py", line 419, in execute self.fetch_command(subcommand).run_from_argv(self.argv) File "D:python_sxtEnvsdjango_envlibsite-packagesdjangocoremanagementbase.py", line 373, in run_from_argv self.execute(*args, **cmd_options) File "D:python_sxtEnvsdjango_envlibsite-packagesdjangocoremanagementcommandsrunserver.py", line 66, in execute super().execute(*args, **options) File "D:python_sxtEnvsdjango_envlibsite-packagesdjangocoremanagementbase.py", line 417, in execute output = self.handle(*args, **options) File "D:python_sxtEnvsdjango_envlibsite-packagesdjangocoremanagementcommandsrunserver.py", line 101, in handle self.run(**options) File "D:python_sxtEnvsdjango_envlibsite-packagesdjangocoremanagementcommandsrunserver.py", line 108, in run Performing system checks... 4040 System check identified no issues (0 silenced).
原因分析:
如上图,通过查看资源管理器发现创建应用会启用两个python进程,因为我开启了pipenv所以图上是四个
DJango默认会开启两个进程:第一个是reload自动重载,第二个才是Django主应用
解决方案:
目前找到以下几种解决方案:
方法一:在manage文件后面加启动参数 --noreload 关闭自动重载
python manage.py runserver --noreload
效果:
可以看到关闭自动重载后,python主进程之开了一个,而且没有报错
缺点:一棒子打死,别的代码修改也不能自动重载,只能手动重启
方法二:使用模块concurrent_log_handler
pip install concurrent_log_handler #安装模块
#setting.py
import concurrent_log_handler #导入模块
······
LOGGING = {
······
'handlers': {
······
},
'file': {
'level': 'INFO',
'class': 'concurrent_log_handler.ConcurrentRotatingFileHandler',#修改这里
'filename': os.path.join(base_LOG_DIR, "log_study.log"),
'maxBytes': 1024 * 1024 * 50,
'backupCount': 3,
'formatter': 'standard',
'encoding': 'utf-8',
},
},
'loggers': {
'': {
'handlers': ['console', 'file'],
'level': 'DEBUG',
},
},
}
concurrent_log_handler适用于windows系统
linux需要安装ConcurrentLogHandler
缺点:需要安装三方库,没有TimedRotatingFileHandler 方法三:使用进程id 命名log文件
#setting.py
import os
base_LOG_DIR = os.path.join(base_DIR, "log")
loggerpid = str(os.getpid())
LOGGING = {
······
'timed_file': {
······
'filename': os.path.join(base_LOG_DIR,f"logging_study_timed{loggerpid}.log"),
······
},
}
方法四:
添加delay参数为True
'delay': True,



