在使用 TimedRotatingFileHandler python日志切分的时候,遇到错误:
os.rename(source, dest)
PermissionError: [WinError 32] 另一个程序正在使用此文件,进程无法访问
代码是单进程的,最初遇到这个错误比较疑惑,最后发现是在代码中
import django
django.setup()
引用了django,因此同时有一个django进程存在。
解决方法
这样修改后,最终实现效果与之前有所不同,不会有类似logger.log这样的命名格式,所有的log文件名都加上了时间戳,可以通过suffix控制切割的频率。
class SafeFileHandler(FileHandler):
def __init__(self, filename, mode="a", encoding=None, delay=0, suffix="%Y-%m-%d_%H"):
if codecs is None:
encoding = None
current_time = time.strftime(suffix, time.localtime())
FileHandler.__init__(self, filename + "." + current_time, mode, encoding, delay)
self.filename = os.fspath(filename)
self.mode = mode
self.encoding = encoding
self.suffix = suffix
self.suffix_time = current_time
def emit(self, record):
try:
if self.check_base_filename():
self.build_base_filename()
FileHandler.emit(self, record)
except(KeyboardInterrupt, SystemExit):
raise
except:
self.handleError(record)
def check_base_filename(self):
time_tuple = time.localtime()
if self.suffix_time != time.strftime(self.suffix, time_tuple) or not os.path.exists(
os.path.abspath(self.filename) + '.' + self.suffix_time):
return 1
else:
return 0
def build_base_filename(self):
if self.stream:
self.stream.close()
self.stream = None
# if self.suffix_time != "":
# index = self.baseFilename.find("." + self.suffix_time)
# if index == -1:
# index = self.baseFilename.rfind(".")
# self.baseFilename = self.baseFilename[:index]
current_time_tuple = time.localtime()
self.suffix_time = time.strftime(self.suffix, current_time_tuple)
self.baseFilename = os.path.abspath(self.filename) + "." + self.suffix_time
if not self.delay:
self.stream = open(self.baseFilename, self.mode, encoding=self.encoding)