当前位置 博文首页 > Python 如何限制输出日志的大小

    Python 如何限制输出日志的大小

    作者:写意山水 时间:2021-05-23 18:25

    限制输出日志的大小有多种方法,最优雅的莫过于直接使用rotate机制,这种机制广泛存在于各种编程语言,Python也不例外。其次,还可以使用mount挂载一个文件,作为日志存储的位置,因为文件大小是有限的,所以日志的大小也被限制。还有可以用ulimit。

    RotatingFileHandler

    RotatingFileHandler是logging.handler的一种,在python docs中,这个类的构造函数示例用法如下

    class logging.handlers.RotatingFileHandler(filename, mode=‘a', maxBytes=0, backupCount=0, encoding=None, delay=False)
    

    参数

    filename 输出的文件名,如果使用Python 3.6或者更新版本的Python,filename可以是一个Path对象,Path对象可以让你更优雅地操作文件路径,它是Python新增的特性。

    mode 有"w"和"a",如果是w,那么每次输出日志,都会覆盖之前已经存在的日志,从第一行开始输出,如果是a,会保留之前的日志,在之前的日志后输出。

    maxBytes 日志最大的大小,单位是字节

    backupCount 如果日志大小达到maxBytes,会将旧日志加上.1或.2这样的后缀,与filename区分,并在新的filename文件第一行开始输出。如果为1,则有最多有一个旧日志的备份。

    encoding 字符编码,常用的有utf-8

    import logging
    from logging.handlers import RotatingFileHandler
    log = logging.getLogger()
    handler = RotatingFileHandler("test", "a", 4096, 2, "utf-8")
    log.addHandler(handler)
    #更高级的logging特性
    log.setLevel(logging.INFO) #设置过滤的日志等级
    formatter = logging.Formatter("%(asctime)s %(levelname)s: %(message)")
    log.setFormatter(formatter) #设置日志输出的格式

    Mount

    先创建文件,并格式化成ext4文件系统

    dd if=/dev/zero of=./logfs bs=1M count=4
    mkfs.ext4 ./logfs
    mkdir log
    sudo mount -t ext4 ./logfs ./log
    python test.py 2>./log/test.log

    需要注意的是,这种方法可能有权限问题,如果python程序权限不够,需要更改挂载后log目录的权限,使用sudo chmod 777 -R log

    补充:

    python控制日志级别输出,可进行全局限流,可控制控制台输出,可用于线上配置,进行日志的简单记录

    # coding=utf-8
    import logging
    import datetime
    import os
    CONSOLE = True
    LEVEL = "DEBUG"
    # log/2020-09/2020-09-27_APPLICATION_NAME.log
    APPLICATION_NAME = "APPLICATION_NAME"
    # 只生成GBK的日志文件
    class RecordLog:
     def __init__(self):
      """
      1、控制日志是否在控制台中打印
      2、控制日志输出的级别
      """
      # 设置是否控制台打印
      self._console = CONSOLE
      # 等级字典
      self._level_dict = {'DEBUG':1,'INFO':2,'WARNING':3,'ERROR':4,'CRITICAL':5}
      # 设置当前支持的日志等级
      self._current_level_num = self._level_dict[LEVEL]
     def get_log_file_name(self,):
      """
      创建日志文件夹,创建或调用日志文件,日志存储
      :return: log/log_folder(月份)/log_file(每天的log)
      """
      now = str(datetime.datetime.now())
      log_folder = now[:7]
      log_file = now[:10] + "_" + APPLICATION_NAME + ".log"
      if os.path.exists("log/" + log_folder):
       pass
      else:
       os.makedirs("log/" + log_folder)
      return "log/" + log_folder + "/" + log_file
     def log_content(self, content='开始记录',level="DEBUG"):
      """
      记录日志
      :param content: 记录的内容
      :param level: DEBUG, INFO, WARNING, ERROR, CRITICAL
      :return:
      """
      LOG_FILE_NAME = self.get_log_file_name()
      now1 = datetime.datetime.now()
      now_date = now1.strftime("%Y-%m-%d-%H:%M:%S")
      text = " %s %s -- %s" % (level, now_date, content)
      if level in ['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL']:
       level_num = self._level_dict[level]
       # 控制台输出
       if self._console:
        print(text)
       logger = logging.getLogger()
       fh = logging.FileHandler(filename=LOG_FILE_NAME, encoding="utf-8", mode="a")
       # formatter = logging.Formatter("%(asctime)s - %(name)s-%(levelname)s %(message)s")
       # fh.setFormatter(formatter)
       logger.addHandler(fh)
       # 设置日志等级
       if "DEBUG" == level and level_num >= self._current_level_num:
        logger.setLevel(logging.DEBUG)
       elif "INFO" == level and level_num >= self._current_level_num:
        logger.setLevel(logging.INFO)
       elif "WARNING" == level and level_num >= self._current_level_num:
        logger.setLevel(logging.WARNING)
       elif "ERROR" == level and level_num >= self._current_level_num:
        logger.setLevel(logging.ERROR)
       else:
        logger.setLevel(logging.CRITICAL)
       logger.info(text)
      else:
       raise Exception('日志等级传参错误: %s ; 正确格式为:DEBUG, INFO, WARNING, ERROR, CRITICAL'%level)
    if __name__ == '__main__':
     #
     log = RecordLog()
     log.log_content(level='DEBUG')
    

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持站长博客。如有错误或未考虑完全的地方,望不吝赐教。

    js
    下一篇:没有了