我正在尝试使用python 3.3.4和PyQt4编写GUI应用程序的旋转日志文件。
我的主脚本中有以下代码片段:
import logging
import resources
logger = logging.getLogger('main.test')
def main():
logger.setLevel(logging.DEBUG)
fh = RotatingFileHandler(resources.LOG_FILE_PATH, maxBytes=500, backupCount=5)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
logger.info('main')
我的maxBytes很低,所以我可以测试旋转是否正常工作,但事实并非如此。每当应该轮换日志时,我都会收到以下错误:
Traceback (most recent call last):
File "C:\Python33\lib\logging\handlers.py", line 73, in emit
self.doRollover()
File "C:\Python33\lib\logging\handlers.py", line 176, in doRollover
self.rotate(self.baseFilename, dfn)
File "C:\Python33\lib\logging\handlers.py", line 116, in rotate
os.rename(source, dest)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\myuser\\.logtest\\test.log.1'
没有记录任何内容。任何帮助深表感谢。 谢谢
答案 0 :(得分:2)
您可以直接在basicConfig()中指定处理程序,而不是向记录器对象添加处理程序。如果将RotatingFileHandler添加到logger对象,则一个对象可能会打开日志文件,而另一个对象可能会尝试重命名它,从而抛出PermissionError。
下面的代码看起来效果很好。
import logging
import resources
from logging.handlers import RotatingFileHandler
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', handlers=[RotatingFileHandler(filename=resources.LOG_FILE_PATH, maxBytes=500, backupCount=5)])
logger = logging.getLogger('main.test')
def main():
logger.setLevel(logging.DEBUG)
logger.info('main')
答案 1 :(得分:2)
在这个问题上花了半天时间,因为以前的答案解决了我的问题。
我的工作解决方案是使用 https://pypi.org/project/concurrent-log-handler/ 而不是 RotatingFileHandler。在 Flask 应用等多线程场景中,当我们旋转达到最大大小的日志文件时,将会引发 PermissionError。
安装 pypiwin32
以消除 No Module name win32con
错误。
答案 2 :(得分:0)
检查文件是否未被保持打开状态,例如Windows文件索引,反病毒或其他软件。无法重命名已打开的文件。
答案 3 :(得分:0)
我将应用程序更改为使用dictConfig并创建了一个包含字典配置的单独文件。在我的主要应用程序的顶部,我有:
from log.logger import LOGGING
logging.config.dictConfig(LOGGING)
logger = logging.getLogger('testlogging')
然后在log.logger
我有:
import logging
import sys
import resources
LOGGING = {
"version":1,
"handlers":{
"fileHandler":{
"class":"logging.handlers.RotatingFileHandler",
"formatter":"myFormatter",
"filename":resources.LOG_FILE_PATH,
"maxBytes":100000,
"backupCount":5
},
"console":{
"class":"logging.StreamHandler",
"formatter":"myFormatter"
}
},
"loggers":{
"aoconnect":{
"handlers":["fileHandler", "console"],
"level":"DEBUG",
}
},
"formatters":{
"myFormatter":{
"format":"%(asctime)s - %(name)s - %(levelname)s - %(message)s"
}
}
}
这一切看起来都很顺利。
答案 4 :(得分:0)
不能在basicConfig()和RotatingFileHandler()中指定相同的文件名。我遇到了同样的问题,我从basicConfig()中删除了filename参数,现在它可以工作了。
答案 5 :(得分:0)
在我的情况下,文件大小已满,在删除server.log
文件后,它可以正常工作
LOGS_DIR = os.path.join(BASE_DIR, 'logs')
LOGGING = {
'version': 1,
'handlers': {
'log_file': {
'level': 'INFO',
'class': 'logging.handlers.RotatingFileHandler',
'filename': os.path.join(LOGS_DIR, 'server.log'),
'backupCount': 10, # keep at most 10 log files
'maxBytes': 5*1024*1024 # 5242880 bytes (5MB)
},
},
'loggers': {
'django': {
'handlers':['log_file'],
'propagate': True,
'level':'INFO',
},
},
}
答案 6 :(得分:0)
在我的情况下(Windows Server 2016 + IIS + FastCGI + Flask),最后我通过关闭文件夹中的文件索引来修复它。 how-to
来源: https://stackoverflow.com/a/22467917/9199668
顺便说一句,它正常工作了几个月...我不知道为什么...