zoukankan      html  css  js  c++  java
  • python logging 日志按时间间隔自动切分

    代码如下:

    import logging, os, time, re
    from stat import ST_MTIME
    from logging.handlers import TimedRotatingFileHandler
    
    
    # 自定义logger输出格式的,因为logging自带的TimedRotatingFileHandler输出格式,我个人不太喜欢
    class TimedHandler(TimedRotatingFileHandler):
        def __init__(self, filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None):
            super(TimedHandler, self).__init__(filename, when, interval, backupCount, encoding, delay, utc, atTime)
            self.when = when.upper()
            self.backupCount = backupCount
            self.utc = utc
            self.atTime = atTime
            """
            此处修改对应日志格式
            """
            if self.when == 'S':
                self.interval = 1  # one second
                self.suffix = "%Y%m%d.%H%M%S"
                self.extMatch = r"^d{4}d{2}d{2}.d{2}d{2}d{2}(.w+)?$"
            elif self.when == 'M':
                self.interval = 60  # one minute
                self.suffix = "%Y%m%d.%H%M"
                self.extMatch = r"^d{4}d{2}d{2}.d{2}d{2}(.w+)?$"
            elif self.when == 'H':
                self.interval = 60 * 60  # one hour
                self.suffix = "%Y%m%d.%H"
                self.extMatch = r"^d{4}d{2}d{2}.d{2}(.w+)?$"
            elif self.when == 'D' or self.when == 'MIDNIGHT':
                self.interval = 60 * 60 * 24  # one day
                self.suffix = "%Y%m%d"
                self.extMatch = r"^d{4}d{2}d{2}(.w+)?$"
            elif self.when.startswith('W'):
                self.interval = 60 * 60 * 24 * 7  # one week
                if len(self.when) != 2:
                    raise ValueError("You must specify a day for weekly rollover from 0 to 6 (0 is Monday): %s" % self.when)
                if self.when[1] < '0' or self.when[1] > '6':
                    raise ValueError("Invalid day specified for weekly rollover: %s" % self.when)
                self.dayOfWeek = int(self.when[1])
                self.suffix = "%Y%m%d"
                self.extMatch = r"^d{4}d{2}d{2}(.w+)?$"
            else:
                raise ValueError("Invalid rollover interval specified: %s" % self.when)
            
            self.extMatch = re.compile(self.extMatch, re.ASCII)
            self.interval = self.interval * interval  # multiply by units requested
            filename = self.baseFilename
            if os.path.exists(filename):
                t = os.stat(filename)[ST_MTIME]
            else:
                t = int(time.time())
            self.rolloverAt = self.computeRollover(t)
    
    
    def get_logger(file_name=None, log_path='logs', when='D', backup_count=3, level='warning'):
        """
        :param file_name: 自定义log名称(创建的log会放在此路径下),None 会通过时间戳来创建文件夹
        :param log_path: log的根目录
        :param when: 拆分日志的时间间隔:周(W)、天(D)、时(H)、分(M)、秒(S)切割。
        :param backup_count: 保留拆分后最新的文件数量,比如如果为3,则表示保留3天内的日志,3天前的日志会被删除;如果为0,则所有拆分的日志都会保存
        :param level: 日志输出等级,分为 info,debug,warning(warn),error 四个等级
        :return:  返回logger对象,通过调用info,debug,error等方法可以写入日志
        """
        # 选择日志输出等级
        level = level.lower()
        logger_infos = {
            'info': logging.INFO,
            'debug': logging.DEBUG,
            'warning': logging.WARNING,
            'warn': logging.WARNING,
            'error': logging.ERROR
        }
        cur_time = time.strftime('%Y%m%d.%H%M%S')
        if file_name is None:
            file_name = cur_time
        logger = logging.getLogger(file_name)
        logger.setLevel(logger_infos[level])
        if file_name == cur_time:  # 未传入名称的,以日期作为文件夹类别
            log_file_path = os.path.join(log_path, file_name)
        else:  # 传入名称的,以传入的名称作为类别
            log_file_path = os.path.join(log_path, file_name, cur_time)
        if not os.path.exists(log_file_path):
            os.makedirs(log_file_path)
        file_name = os.path.join(log_file_path, 'log')
        # 定义handler的输出格式
        formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
        fh = TimedHandler(filename=file_name, when=when, backupCount=backup_count, encoding='utf-8')
        fh.setFormatter(formatter)
        logger.addHandler(fh)  # 将logger添加到handler里面
        return logger
    
    
    if __name__ == '__main__':
        # logger = get_logger(file_name='abcd', log_path='./logs', when='S', level='debug')
        logger = get_logger(log_path='./logs', when='S', backup_count=2, level='debug')
        for i in range(100):
            logger.info(i)
            time.sleep(0.1)
    

    参考链接:https://www.cnblogs.com/mangM/p/11200987.html

  • 相关阅读:
    asp.net 中的viewstate用法?
    .net中 过滤 指定 字符串
    js中replace的用法
    restart
    外部函数
    JQuery实现Ajax 根据商品名称自动显示价格
    ListView中命令行按钮应用;
    GridView中获取行数和列数
    全局应用程序类Global
    如何获取gridview中模板列中控件的值?
  • 原文地址:https://www.cnblogs.com/jaysonteng/p/14850666.html
Copyright © 2011-2022 走看看