Logging Rotatingfilehandler and Timedrotatingfilehandler are not supported for multi-process (because each process maintains a fixed file handle, which causes the rename of each other to interfere with each other when a conditional rollback is reached. For example, a process has turned Worker.log into worker.log.2016-06-01, and other processes have been written to worker.log.2016-06-01, and others have many problems .
Therefore, to adapt to multi-process handle, the code is as follows:
# -*- coding: utf-8 -*-import logging, os, re, time, datetimetry: import codecsexcept ImportError: codecs = None class myloggerhandler (logging. Filehandler): def __init__ (self, filename, when= ' D ', backupCount=0, encoding=none, delay=false): self.prefix = filename self.when = when.upper () # S - Every second a new file # m - every minute a new file # h - every hour a new file # d - every day a new file if self.when == ' S ': self.suffix = "%Y- %m-%d_%h-%m-%s " self.extmatch = r "^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}-\d{2}$" elif self.when == ' M ': self.suffix = "%y-%m-%d_%h-%m" Self.extmatch = r "^\d{4}-\d{2}-\d{2}_\d{2}-\d{2}$" elif self.when == ' H ': self.suffix = "%y-%m-%d_%h" Self.extmatch = r "^\d{4}-\d{2}-\d{2}_\d{2}$ " elif self.when == ' d ': self.suffix = "%y-%m-%d" self.extmatch = r "^\d{4}-\d{ 2}-\d{2}$ " else: raise valueerror ("invalid rollover interval specified: %s " % self.when) self.filefmt = Os.path.join ("Logs", "%s.%s" % (self.prefix, self.suffix)) self.filepath = datetime.datetime.now (). Strftime (SELF.FILEFMT) _dir = os.path.dirname (Self.filepath) try: &Nbsp; if os.path.exists (_dir) is False: os.makedirs (_dir) except Exception: print "Can not make dirs" print "filepath is " + self.filepath pass self.backupcount = backupcount if codecs is None: encoding = None logging. filehandler.__init__(self, self.filepath, ' A ', encoding, delay) def Shouldchangefiletowrite (self): _filepath = Datetime.datetime.now (). Strftime (SELF.FILEFMT) if _ filepath != self.filepath: self.filepath = _filepath return 1 return 0 def dochangefile (self): self.basefilename = os.path.abspath (Self.filepath) if self.stream is not None: Self.stream.flush () self.stream.close () if not self.delay: self.stream = self._open () if self.backupcount > 0: for s in Self.getfilestodelete (): os.remove (s) def getfilestodelete (self): dirname, basename = os.path.split (Self.baseFilename) filenames = os.listdir (DirName) result = [] prefix = self.prefix + "." &nBsp; plen = len (prefix) for fileName in fileNames: if filename[:p len] == prefix: suffix = fileName[plen:] if re.compile (Self.extMatch). Match (suffix): result.append (Os.path.join (dirname, filename)) result.sort () if len (Result) < self.backupcount: result = [] &nbsP; else: result = result[:len (Result) - self.backupCount] Return result def emit (Self, record): "" " Emit a record. "" " try: if Self.shouldchangefiletowrite (): self.dochangefile () Logging. Filehandler.emit (Self, record) except ( Keyboardinterrupt, systemExit): raise except: Self.handleerror (Record)
Use the same way as Timedrotatingfilehandler, such as file configuration press:
[Handler_workerfile2]class=log_kit. Myloggerhandlerlevel=infoformatter=simpleformatterargs= (R ' Worker.log ', ' M ', 5) # A file for one minute, keeping only the latest 5 #args= (R ' Worker.log ', ' D ', 5) # one file per day, keeping only the latest 5
Python logging multi-process Write compatibility module