Python基础(11) logging


0. 前言


1. 组件介绍

  • 总体流程如下(非常建议看看):
    image_1cbguc95h1em5144t12q68us1va69.png-69.8kB

1.1. Loggers

  • Logger的功能:
    1. 为开发人员提供接口,可以在运行中输出日志。
    2. 决定产生日志的Level,以及使用的filter。
    3. 指定日志输出的位置,即指定handler。
  • 如果不指定名称,则返回根Logger,默认Level为warning
  • Logger存在等级,通过.来区分:
    • 比如logging.getLogger('a')就是loggint.getLogger('a.b')的父级。
    • 存在其他所有Logger的共同祖先——根Logger。
    • 如果当前Logger没有指定Level,会默认使用祖先的Level。
    • 默认情况下,子类产生的日志(不是全部日志,而是满足子类Level的日志,可以参考之前的总体流程图)会传递给父类的Handler。
    • 可以通过设置propagate设置,是否使用父类的Handler。
  • 多次获取同一个名称的Logger,获取的是同一实例。
  • 建议使用的获取Logger的方式是:
    • logger = logging.getLogger(__name__)
    • 其中__name__是当前模块的名称(包括package名称)。
  • 常用方法:
Logger.setLvel()
Logger.addHandler()
Logger.removeHandler()
Logger.addFilter()
Logger.removeFilter()
Logger.debug() # 还有 info warning error critical 
Logger.exception() # 与Logger.error()只有一个区别,会打印 stack trace 信息,因此仅用于 exception handler
Logger.log(lvl, msg, *args, **kwargs) # 可以指定level等级,其他与debug等无差别

1.2. Handlers

  • Handler用于指定日志信息的去向。
  • 每个Logger可以指定任意数量的Handler(不指定Handler也没关系)。
  • Python有很多实现好了的Handler,可以参考这里这里(推荐)
    • class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False)
      • 作用:通过文件大小,将日志文件分为多个。
      • maxBytes指定文件大小,backupCount指定最多保存的文件数量。这两个参数都可以设置为0,表示文件大小无限制和文件全部保存。
      • mode指定打开日志文件的模式。
      • 文件命名:假设filename=app.log,则正在写入的文件名为app.log,之前保存的日志文件名为app.log.1app.log.2等。
    • class logging.handlers.TimedRotatingFileHandler(filename, when='h', interval=1, backupCount=0, encoding=None, delay=False, utc=False, atTime=None)
      • 作用:通过时间,分割日志文件。
      • 通过wheninterval设置时间间隔。
      • when取值可以是S, M, H, D分别表示秒、分、小时、天,之后通过设置interval来设置时间间隔。
      • when取值为W0, W1, ..., W6, midnight,其中W0代表星期一,依次类推。此时表示每周一/…/每周日/每天0点生成新的日志文件。此时interval没有用处。
      • 文件命名:可以设置属性suffix来确定后缀,添加文件名后。默认suffix%Y-%m-%d_%H-%M-%S
      • delay如果为True,则日志文件只有在执行过emit()后才会创建。
      • atTime可以设置rollover的启动的时间,需要为datetime.time实例。
  • 一般应用代码不用直接创建Handler对象。
  • 常用方法:
setLevel()
setFormatter()
addFilter()
removeFilter()

1.3. Filters

  • 用于过滤LogRecord
  • 需要定义以下函数,用于创建新的Filter对象。
def should_log(record):
    ...
    # 根据最终输出的布尔值,来确定是否需要进行过滤
    # 0或None则表示需要过滤
    # 其他表示不需要过滤
    return True

logging_filter = logging.Filter()  
logging_filter.filter = should_log

1.4. Formatters

  • 用于定义日志信息的格式
  • logging.Formatter.__init__(fmt=None, datefmt=None, style='%')
  • 默认值:
    • fmt=None等价于'%(message)s'
    • datefmt=None等价于 IOS8601 格式。自己设置等价于time.strftime()
    • style=None等价于%,还可以取值为${
  • 可用关键字,详细资料参考这里
%(name)s             Logger的名字
%(levelno)s          数字形式的日志级别
%(levelname)s     文本形式的日志级别
%(pathname)s     调用日志输出函数的模块的完整路径名,可能没有
%(filename)s        调用日志输出函数的模块的文件名
%(module)s          调用日志输出函数的模块名
%(funcName)s     调用日志输出函数的函数名
%(lineno)d           调用日志输出函数的语句所在的代码行
%(created)f          当前时间,用UNIX标准的表示时间的浮 点数表示
%(relativeCreated)d    输出日志信息时的,自Logger创建以 来的毫秒数
%(asctime)s                字符串形式的当前时间。默认格式是 “2003-07-08 16:49:45,896”。逗号后面的是毫秒
%(thread)d                 线程ID。可能没有
%(threadName)s        线程名。可能没有
%(process)d              进程ID。可能没有
%(processName)d              进程名称。可能没有
%(message)s            用户输出的消息

2. 配置方法

2.1. 使用Python创建loggers, handlers, filters

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')

2.2. 创建一个配置文件

  • 配置文件,建议名称logging.conf
[loggers]
keys=root,simpleExample

[handlers]
keys=consoleHandler

[formatters]
keys=simpleFormatter

[logger_root]
level=DEBUG
handlers=consoleHandler

[logger_simpleExample]
level=DEBUG
handlers=consoleHandler
qualname=simpleExample
propagate=0

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)

[formatter_simpleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s - %(message)s
datefmt=
  • 运行程序
import logging
import logging.config

logging.config.fileConfig('logging.conf')

# create logger
logger = logging.getLogger('simpleExample')

# 'application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')

2.3. 创建一个字典


3. 查漏补缺

3.1. 配置缺失

  • 参考:What happens if no configuration is provided
  • 对于Python 3.6,如果存在Logger但没有配置相应的Handler,默认会使用logging.lastResort,即StreamHandler
  • 请注意,如果有以下条件。如果子类输出日志信息,会输出到console中。
    • 两个logger互为父子关系。
    • 父类存在Handler,子类不存在Handler。
    • 子类的propagate设置为False

3.2. 使用Module-Level方法

  • logging.debug等:就是使用Root Logger进行操作。

  • logging.basicConfig(**kwargs)

    • 用于创建Root Logger。
    • 只有第一次调用的时候有效,之后调用都不会起作用。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值