美文网首页Python
python 多线程中 日志按天分割

python 多线程中 日志按天分割

作者: cooooper | 来源:发表于2018-12-29 19:43 被阅读240次

    python 的 logging 模块, 在多线程应用中, logging.hanlders.TimedRotatingFileHandler 不能正常按日期分割。

    解决办法为:重写FileHandler类,用于多线程中日志按天分割。

    # 重写FileHandler类,用于多线程中日志按天分割
    class SafeFileHandler(logging.FileHandler):
        def __init__(self, filename, mode, encoding=None, delay=0):
            """
            Use the specified filename for streamed logging
            """
            encoding = None
            logging.FileHandler.__init__(self, filename, mode='a', encoding=None, delay=False)
            self.mode = mode
            self.encoding = encoding
            self.suffix = "%Y-%m-%d"
            self.suffix_time = ""
    
        def emit(self, record):
            """
            Emit a record.
    
            Always check time 
            """
            try:
                if self.check_baseFilename(record):
                    self.build_baseFilename()
                logging.FileHandler.emit(self, record)
            except (KeyboardInterrupt, SystemExit):
                raise
            except:
                self.handleError(record)
                
        def check_baseFilename(self, record):
            """
            Determine if builder should occur.
            
            record is not used, as we are just comparing times, 
            but it is needed so the method signatures are the same
            """
            timeTuple = time.localtime()
            
            if self.suffix_time != time.strftime(self.suffix, timeTuple) or not os.path.exists(self.baseFilename+'.'+self.suffix_time):
                return 1
            else:
                return 0
        def build_baseFilename(self):
            """
            do builder; in this case, 
            old time stamp is removed from filename and
            a new time stamp is append to the filename
            """
            if self.stream:
                self.stream.close()
                self.stream = None
            
            # remove old suffix
            if self.suffix_time != "":
                index = self.baseFilename.find("."+self.suffix_time)
                if index == -1:
                    index = self.baseFilename.rfind(".")
                self.baseFilename = self.baseFilename[:index]
            
            # add new suffix
            currentTimeTuple = time.localtime()
            self.suffix_time = time.strftime(self.suffix, currentTimeTuple)
            self.baseFilename  = self.baseFilename + "." + self.suffix_time
            
            self.mode = 'a'
            if not self.delay:
                self.stream = self._open()
    

    之后,Logger定义日志的各种参数(格式等):

    class Logger(object):
        # 日志级别关系映射
        level_relations = {
            'debug':logging.DEBUG,
            'info':logging.INFO,
            'warning':logging.WARNING,
            'error':logging.ERROR,
            'critical':logging.CRITICAL
        }
    
        def __init__(self, filename, level='info', when='D', backCount=7,
                     fmt= '%(asctime)s  -  %(pathname)s  [line:%(lineno)d]  -  %(levelname)s:  %(message)s'):
            self.logger = logging.getLogger('mylogger')
            # 创建日志目录(路径logdir可从自定义配置文件导入,或实例化时传入)
            self.mkdir(logdir)
            # 设置日志格式
            format_str = logging.Formatter(fmt)
            self.logger.setLevel(self.level_relations.get(level))#设置日志级别
            # 指定间隔时间自动生成文件的处理器(用于debug)
            th = SafeFileHandler(filename=filename, mode='a')
            # 设置文件里写入的格式
            th.setFormatter(format_str)
            # 把对象加到logger里
            self.logger.addHandler(th)
    
        def mkdir(self, path) -> None:
            # 如果不存在则创建目录
            if not os.path.exists(path):
                os.makedirs(path)
    

    实例化日志:

    mylogger = Logger(filename='all.log', level='debug')
    

    相关文章

      网友评论

        本文标题:python 多线程中 日志按天分割

        本文链接:https://www.haomeiwen.com/subject/xkbplqtx.html