Python 2.7: Every time a log experiences a rollover event (logs with a RotatingFileHandler) a 'backup' log is generated.
For instance :
logFile = 'general.log'
file_handler = logging.handlers.TimedRotatingFileHandler(logFile,when="midnight")
Results in midnight roll over and on rollover event the following file is created:
general.log.2015-01-21
Does this module offer any flexibility how these filenames are structured?
ie use a different convention ... 20150121_general.log
Short answer is no: according to TimedRotatingFileHandler documentation you have no way to do it.
The suffix change based on when
parameter like you can see in the code https://hg.python.org/cpython/file/2.7/Lib/logging/handlers.py#l187
From the same source code you can see that override suffix
is simple but you must override extMatch
too:
class MyTimedRotatingFileHandler(TimedRotatingFileHandler):
def __init__(self, *args, **kwargs):
super(MyTimedRotatingFileHandler,self).__init__(*args,**kwargs)
self.suffix = "%Y%m%d"
self.extMatch = re.compile(r"^\d{4}\d{2}\d{2}$")
Unfortunately replace dot separator and swap suffix
and basename
is not so simple and you must rewrite doRollover()
and getFilesToDelete()
methods.
A hacking can be something like this (untested)... I hope it works but I cannot give any warrant :)
class MyTimedRotatingFileHandler(TimedRotatingFileHandler):
self.extMatch = r"^\d{4}-\d{2}-\d{2}$"
def getFilesToDelete(self):
""" CUT, PASTE AND .... HACK
"""
dirName, baseName = os.path.split(self.baseFilename)
fileNames = os.listdir(dirName)
result = []
extMatch = re.compile(r"^\d{4}\d{2}\d{2}$")
ends = "_" + baseName + ".log"
elen = len(ends)
for fileName in fileNames:
if fileName[-elen:] == ends:
date = fileName[-elen:]
if self.extMatch.match(date):
result.append(os.path.join(dirName, fileName))
result.sort()
if len(result) < self.backupCount:
result = []
else:
result = result[:len(result) - self.backupCount]
return result
def doRollover(self):
"""
CUT AND PAST FROM TimedRotatingFileHandler
customize file name by prefix instead suffix
"""
if self.stream:
self.stream.close()
self.stream = None
# get the time that this sequence started at and make it a TimeTuple
currentTime = int(time.time())
dstNow = time.localtime(currentTime)[-1]
t = self.rolloverAt - self.interval
if self.utc:
timeTuple = time.gmtime(t)
else:
timeTuple = time.localtime(t)
dstThen = timeTuple[-1]
if dstNow != dstThen:
if dstNow:
addend = 3600
else:
addend = -3600
timeTuple = time.localtime(t + addend)
#################################################
# THE HACK!!!! ##################################
##################################################
dfn = time.strftime("%Y%m%d", timeTuple) + "_" +self.baseFilename + ".log"
if os.path.exists(dfn):
os.remove(dfn)
# Issue 18940: A file may not have been created if delay is True.
if os.path.exists(self.baseFilename):
os.rename(self.baseFilename, dfn)
if self.backupCount > 0:
for s in self.getFilesToDelete():
os.remove(s)
if not self.delay:
self.stream = self._open()
newRolloverAt = self.computeRollover(currentTime)
while newRolloverAt <= currentTime:
newRolloverAt = newRolloverAt + self.interval
#If DST changes and midnight or weekly rollover, adjust for this.
if (self.when == 'MIDNIGHT' or self.when.startswith('W')) and not self.utc:
dstAtRollover = time.localtime(newRolloverAt)[-1]
if dstNow != dstAtRollover:
if not dstNow: # DST kicks in before next rollover, so we need to deduct an hour
addend = -3600
else: # DST bows out before next rollover, so we need to add an hour
addend = 3600
newRolloverAt += addend
self.rolloverAt = newRolloverAt
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With