zoukankan      html  css  js  c++  java
  • Python logging 模块简介

    Logging 模块

    简介

    Python的 logging 模块提供了灵活的日志处理相关功能, 可以用来追踪程序运行的情况。

    logging 模块提供了一系列标准的日志等级: DEBUG, INFO, WARNING, ERROR, CRITICAL, 顾名思义可以大致看出它们各自的使用情况。 logging 模块设置的默认等级时 WARNING, 这意味着默认情况下,日志级别为 WARNING, ERROR, CRITICAL 的日志会被记录,而 DEBUG, INFO 的日志会被忽略。

    不同等级的value值如下,只有当value大于 logger 的值才会记录日志。

    Level    Value
    CRITICAL 50
    ERROR    40
    WARNING  30
    INFO     20
    DEBUG    10
    UNSET     0
    

    简单输出日志

    下面看一个简单的官方文档上的例子:

    import logging
    logging.warning('Watch out!')  # will print a message to the console
    logging.info('I told you so')  # will not print anything
    

    输出如下:

    WARNING:root:Watch out!
    

    可以看到info记录的信息没有输出,这是因为默认输出级别不低于WARNING级别的。

    输入日志到文件

    logging 支持输出日志到文件,参考下面示例:

    import logging
    logging.basicConfig(filename='example.log',level=logging.DEBUG)
    logging.debug('This message should go to the log file')
    logging.info('So should this')
    logging.warning('And this, too')
    

    其中level是指的记录等级, 输出如下:

    DEBUG:root:This message should go to the log file
    INFO:root:So should this
    WARNING:root:And this, too
    

    几个基本概念

    loggers

    logger是logging模块提供的日志类 Logger 的实例,它暴露出接口可以直接供程序调用。
    每个实例都有一个名字,并且示例间有类之间那种继承关系,根据logger的名字来区分,比如叫"scan"的logger是叫"scan.text"和"scan.html"的父类(没错,他们是以点号错分隔符)。

    所有logger共同的父类是 root , 就是上面示例中的中间那个默认的root。 basicConfig 默认的输出格式为: severity:logger name:message

    logger的通过 logging.getLogger(name) 来创建,有种在包里命名的惯用做法是:

    logger = logging.getLogger(__name__)
    

    这样的好处是可以从logger的名字清楚的看到记录的来源。

    handlers 和轮转日志

    handlers 承担 logging 模块里负责处理合适的信息到不同的地方的角色,下面通过设置一个RotatingFileHandler来展示handler的特性。

    有时候需要创建多个轮转日志,每个日志保存一定长度的内容,最多保留一定数量的日志,其余的丢弃,这种情况下,可以定义 RotatingFileHandler 来实现:

    logging_rotatingfile_example.py
    import glob
    import logging
    import logging.handlers
    
    LOG_FILENAME = 'logging_rotatingfile_example.out'
    
    # Set up a specific logger with our desired output level
    my_logger = logging.getLogger('MyLogger')
    my_logger.setLevel(logging.DEBUG)
    
    # Add the log message handler to the logger
    handler = logging.handlers.RotatingFileHandler(
        LOG_FILENAME,
        maxBytes=20,
        backupCount=5,
    )
    my_logger.addHandler(handler)
    
    # Log some messages
    for i in range(20):
        my_logger.debug('i = %d' % i)
    
    # See what files are created
    logfiles = glob.glob('%s*' % LOG_FILENAME)
    for filename in logfiles:
        print(filename)
    

    运行输出如下:

    logging_rotatingfile_example.out
    logging_rotatingfile_example.out.1
    logging_rotatingfile_example.out.2
    logging_rotatingfile_example.out.3
    logging_rotatingfile_example.out.4
    logging_rotatingfile_example.out.5
    

    当日志内容达到定义的 maxBytes 时,会自动重命名文件后加上后缀".1",如果已经存在后续的".1",".2"等则自动重命名他们向后加1,最后最多只保留 backupCount 定义数量的日志文件。

    其它有用的handler参见这里

    Formatters 和 个性化输出

    Formatters 可以用来控制日志输出的格式,参考下面的示例:

    import logging
    
    # create logger
    logger = logging.getLogger('simple_example')
    logger.setLevel(logging.DEBUG)
    
    # create console handler and set level to debug
    ch = logging.StreamHandler()
    ch.setLevel(logging.DEBUG)
    
    # create formatter
    formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    # add formatter to ch
    ch.setFormatter(formatter)
    
    # add ch to logger
    logger.addHandler(ch)
    
    # 'application' code
    logger.debug('debug message')
    logger.info('info message')
    logger.warn('warn message')
    logger.error('error message')
    logger.critical('critical message')
    

    输出如下:

    2016-11-27 23:18:51,128 - simple_example - DEBUG - debug message
    2016-11-27 23:18:51,128 - simple_example - INFO - info message
    2016-11-27 23:18:51,128 - simple_example - WARNING - warn message
    2016-11-27 23:18:51,128 - simple_example - ERROR - error message
    2016-11-27 23:18:51,128 - simple_example - CRITICAL - critical message
    

    可以看到 %(asctime)s - %(name)s - %(levelname)s - %(message)s 这里对格式化输出的影响。
    其中默认的日期时间显示的格式是ISO8601格式, 也可以自定义时间格式,如下面的例子:

    import logging
    logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
    logging.warning('is when this event was logged.')
    

    输出:

    python test12.py
    11/27/2016 11:22:41 PM is when this event was logged.
    

    好有个比较有用的格式化参数时 %(lineno)d, 显示logger调用的时候所处的行数。具体的格式和作用可以参见这里

    其它

    logger.exception

    ERROR 的等级记录日志,但和 DEBUG 等级一样会输出详细的错误信息,通常用在exception处理中

    Filter Object

    Filters 是可以被handlers和loggers用来过滤日志的输出的,因为用的不多,具体可参见文档

    线程安全

    logging模块是通过线程锁保证线程安全的。

    Logging Flow

    官方文档上看到的logging流程图,可以帮助理解日志记录流程,参见这里

    从配置文件获取logging的配置

    参见这里

    参考资料

  • 相关阅读:
    哪种写法更好?<script></script> vs/or <script type=”text/javasript”></script>
    JS 脚本应该放在页面哪个位置 head body foot
    List<T> ForEach break
    嵌套JSON 取出name与value
    C# 改变图片尺寸(压缩),Image Resize
    tornado
    appachebench网站压力测试
    mysql分区分表
    redis的持久化存储,RDB与AOF
    MEMCACHE的内存管理和删除策略
  • 原文地址:https://www.cnblogs.com/nisen/p/6107996.html
Copyright © 2011-2022 走看看