美文网首页
快速上手Python2中logging使用

快速上手Python2中logging使用

作者: 时间煮菜 | 来源:发表于2020-02-23 16:44 被阅读0次

    日志记录的重要性

    • 日志记录更容易排查到问题的所在之处
    • 节省时间

    日志记录的流程框架

    从下图中我们可以看出看到这几种 Python 类型,LoggerLogRecordFilterHandlerFormatter

    类型说明:

    Logger:日志,暴露函数给应用程序,基于日志记录器和过滤器级别决定哪些日志有效。

    LogRecord :日志记录器,将日志传到相应的处理器处理。

    Handler :处理器, 将(日志记录器产生的)日志记录发送至合适的目的地。

    Filter :过滤器, 提供了更好的粒度控制,它可以决定输出哪些日志记录。

    Formatter:格式化器, 指明了最终输出中日志记录的布局。

    img
    1. 判断 Logger 对象对于设置的级别是否可用,如果可用,则往下执行,否则,流程结束。
    2. 创建 LogRecord 对象,如果注册到 Logger 对象中的 Filter 对象过滤后返回 False,则不记录日志,流程结束,否则,则向下执行。
    3. LogRecord 对象将 Handler 对象传入当前的 Logger 对象,(图中的子流程)如果 Handler 对象的日志级别大于设置的日志级别,再判断注册到 Handler 对象中的 Filter 对象过滤后是否返回 True 而放行输出日志信息,否则不放行,流程结束。
    4. 如果传入的 Handler 大于 Logger 中设置的级别,也即 Handler 有效,则往下执行,否则,流程结束。
    5. 判断这个 Logger 对象是否还有父 Logger 对象,如果没有(代表当前 Logger 对象是最顶层的 Logger 对象 root Logger),流程结束。否则将 Logger 对象设置为它的父 Logger 对象,重复上面的 3、4 两步,输出父类 Logger 对象中的日志输出,直到是 root Logger 为止。

    日志输出格式

    • 日志的输出格式可以认为设置,默认格式为下图所示。
    img

    日志基本使用

    logging 使用非常简单,使用 basicConfig() 方法就能满足基本的使用需要,如果方法没有传入参数,会根据默认的配置创建Logger 对象,默认的日志级别被设置为 WARNING,默认的日志输出格式如上图,该函数可选的参数如下表所示。

    参数名称 参数描述
    filename 日志输出到文件的文件名
    filemode 文件模式,r[+]、w[+]、a[+]
    format 日志输出的格式
    datefat 日志附带日期时间的格式
    style 格式占位符,默认为 "%" 和 “{}”
    level 设置日志输出级别
    stream 定义输出流,用来初始化 StreamHandler 对象,不能 filename 参数一起使用,否则会ValueError 异常
    handles 定义处理器,用来创建 Handler 对象,不能和 filename 、stream 参数一起使用,否则也会抛出 ValueError 异常

    示例代码如下:

    import logging
    
    logging.basicConfig()
    logging.debug('This is a debug message')
    logging.info('This is an info message')
    logging.warning('This is a warning message')
    logging.error('This is an error message')
    logging.critical('This is a critical message')
    

    传入常用的参数,示例代码如下(这里日志格式占位符中的变量放到后面介绍):

    import logging
    
    logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
    logging.debug('This is a debug message')
    logging.info('This is an info message')
    logging.warning('This is a warning message')
    logging.error('This is an error message')
    logging.critical('This is a critical message')
    

    生成的日志文件 test.log ,内容如下:

    13-10-18 21:10:32 root:DEBUG:This is a debug message
    13-10-18 21:10:32 root:INFO:This is an info message
    13-10-18 21:10:32 root:WARNING:This is a warning message
    13-10-18 21:10:32 root:ERROR:This is an error message
    13-10-18 21:10:32 root:CRITICAL:This is a critical message
    

    但是当发生异常时,直接使用无参数的 debug()、info()、warning()、error()、critical() 方法并不能记录异常信息,需要设置 exc_info 参数为 True 才可以,或者使用 exception() 方法,还可以使用 log() 方法,但还要设置日志级别和 exc_info 参数。

    import logging
    
    logging.basicConfig(filename="test.log", filemode="w", format="%(asctime)s %(name)s:%(levelname)s:%(message)s", datefmt="%d-%M-%Y %H:%M:%S", level=logging.DEBUG)
    a = 5
    b = 0
    try:
        c = a / b
    except Exception as e:
        # 下面三种方式三选一,推荐使用第一种
        logging.exception("Exception occurred")
        logging.error("Exception occurred", exc_info=True)
        logging.log(level=logging.DEBUG, msg="Exception occurred", exc_info=True)
    

    logging等级使用

    级别 何时使用
    DEBUG 详细信息,一般只在调试问题时使用。
    INFO 证明事情按预期工作。
    WARNING 某些没有预料到的事件的提示,或者在将来可能会出现的问题提示。例如:磁盘空间不足。但是软件还是会照常运行。
    ERROR 由于更严重的问题,软件已不能执行一些功能了。
    CRITICAL 严重错误,表明软件已不能继续运行了。
    级别 数字值
    CRITICAL 50
    ERROR 40
    WARNING 30
    INFO 20
    DEBUG 10
    NOTSET 0

    打印到控制台

    import logging
    logging.debug('debug 信息')
    logging.warning('只有这个会输出。。。')
    logging.info('info 信息')
    

    由于默认设置的等级是warning,所有只有warning的信息会输出到控制台。

    WARNING:root:只有这个会输出。。。
    

    需求:

    输出log到控制台以及将日志写入log文件。
    保存2种类型的log, all.log 保存debug, info, warning, critical 信息, error.log则只保存error信息,同时按照时间自动分割日志文件。

    import logging
    from logging import handlers
    
    class Logger(object):
        level_relations = {
            'debug':logging.DEBUG,
            'info':logging.INFO,
            'warning':logging.WARNING,
            'error':logging.ERROR,
            'crit':logging.CRITICAL
        }#日志级别关系映射
        def __init__(self,filename,level='info',when='D',backCount=3,fmt='%(asctime)s - %(pathname)s[line:%(lineno)d] - %(levelname)s: %(message)s'):
            self.logger = logging.getLogger(filename)
            format_str = logging.Formatter(fmt)#设置日志格式
            self.logger.setLevel(self.level_relations.get(level))#设置日志级别
            sh = logging.StreamHandler()#往屏幕上输出
            sh.setFormatter(format_str) #设置屏幕上显示的格式
            th = handlers.TimedRotatingFileHandler(filename=filename,when=when,backupCount=backCount,encoding='utf-8')#往文件里写入#指定间隔时间自动生成文件的处理器
            #实例化TimedRotatingFileHandler
            #interval是时间间隔,backupCount是备份文件的个数,如果超过这个个数,就会自动删除,when是间隔的时间单位,单位有以下几种:
            # S 秒
            # M 分
            # H 小时、
            # D 天、
            # W 每星期(interval==0时代表星期一)
            # midnight 每天凌晨
            th.setFormatter(format_str)#设置文件里写入的格式
            self.logger.addHandler(sh) #把对象加到logger里
            self.logger.addHandler(th)
    if __name__ == '__main__':
        log = Logger('all.log',level='debug')
        log.logger.debug('debug')
        log.logger.info('info')
        log.logger.warning('警告')
        log.logger.error('报错')
        log.logger.critical('严重')
        Logger('error.log', level='error').logger.error('error')
    

    相关文章

      网友评论

          本文标题:快速上手Python2中logging使用

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