情况
日常应用的是concurrent-log来复印Python新项目的日志,该库是根据原生态logging库的二次开发 ,以适用多进程日志复印,但有一个不满意的地区便是日志文件的后缀名是日期末尾(自然很有可能有别的方法能够设定,但也没有寻找) ,无论怎样能处理自身的要求就可以了,全过程不重要
修改前log文件
解决方案
对ConcurrentTimedRotatingFileHandler类下的doRollover方法重写
class PrivateConcurrentTimedRotatingFileHandler(ConcurrentTimedRotatingFileHandler): # 重写doRollover方法,用以支撑点日志旋转的文件命名 def doRollover(self): """ 本方法承继Python标准库,修改的一部分已在正下方应用注解标识出 """ 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) # 每日形成的日志文件沒有后缀名 ,必须修改源代码:TimedRotatingFileHandler类下的doRollover方法--> # dfn = self.rotation_filename(self.baseFilename "." time.strftime(self.suffix, timeTuple)后边拼凑文件后缀名 # dfn = self.rotation_filename(self.baseFilename "." time.strftime(self.suffix, timeTuple) ".log") dfn = self.rotation_filename(self.baseFilename "." time.strftime(self.suffix, timeTuple) ".log") """ 假如旋转文档早已形成,则表明别的过程早已解决过旋转 解决日志文件早已旋转当今过程中未载入文档的日志团本,修改刚开始 """ # 立即修改静态变量 ,由于代码执行到这里早已获得到非再入过程锁,确保同一时间只有一个进程对自变量开展修改 # 因为Python GIL,同一时间同一过程内只有一个进程运作 ,进程转换后缓存文件全自动无效,即别的进程能够看到修改后的全新值 # 纪录每一次开启旋转姿势的時间,无论翻转是不是确实实行 ConcurrentTimedRotatingFileHandler.before_rollover_at = self.rolloverAt if os.path.exists(dfn): # 由于过程自变量不容易在运行内存同歩,因此 存有别的过程早已旋转过日志文件那时候当今过程中还标志为未翻转 # 日志內容建立時间假如不大于下一个解决旋转時刻 ,则将日志载入翻转后的日志文件,而不是当今的baseFilename # 当今硬盘上的baseFilename针对当今过程中的标志团本而言早已是旋转后要载入的文档 # 因此 当文件存有时,此次已不开展旋转姿势 pass else: self.rotate(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
重写后,启用自身的子类PrivateConcurrentTimedRotatingFileHandler就可以
def get_logger(self): """在logger中加上日志句柄并回到 ,假如logger现有句柄,则立即回到 大家这儿加上2个句柄,一个輸出日志到控制面板 ,另一个輸出到日志文件。 2个句柄的日志等级不一样,在环境变量中可设定 。 """ if not self.logger.handlers: # 防止反复日志 console_handler = logging.StreamHandler() console_handler.setFormatter(self.formatter) console_handler.setLevel(self.console_output_level) self.logger.addHandler(console_handler) # 每日再次建立一个日志文件,数最多保存backup_count份 # 每日形成的日志文件沒有后缀名 ,必须修改源代码:TimedRotatingFileHandler类下的doRollover方法--> # dfn = self.rotation_filename(self.baseFilename "." time.strftime(self.suffix, timeTuple)后边拼凑文件后缀名 # dfn = self.rotation_filename(self.baseFilename "." time.strftime(self.suffix, timeTuple) ".log") file_handler = PrivateConcurrentTimedRotatingFileHandler(filename=os.path.join(self.log_path, self.log_file_name), when='MIDNIGHT', interval=1, backupCount=self.backup_count, delay=True, encoding='utf-8' ) file_handler.setFormatter(self.formatter) file_handler.setLevel(self.file_output_level) self.logger.addHandler(file_handler)
修改后log文件