Python Logging 模块

2015-06-11 Thursday     python , program

用 Python 写代码时,经常需要打印日志,其实内部提供了一个灵活的 logging 模块,基本可以满足绝大部分的需求,如下简单介绍其使用方式。

简介

Python 中使用最多的日志打印模块,采用层级管理,支持多线程,logging 模块包含了四大组件:

  • Logger 提供了应用程序可使用的接口;
  • Handler 将 logger 创建的日志记录发送到合适的目的输出,例如文件、标准输出等;
  • Filter 提供了更细粒度的控制工具来决定输出哪条日志记录,丢弃哪条日志记录;
  • Formatter 决定日志记录的最终输出格式。

获取 logger 对象可以通过 Logger 类直接创建实例,不过常用 logging.getLogger() 方法获取,入参是一个可选的 name 标示,默认是 root ,当以相同的 name 参数调用时,返回的对象相同。

logger 层级结构与 name 相关,其名字以 . 分割层级,例如,有一个名称为 foo 的 logger,其它名称分别为 foo.barfoo.bar.bazfoo.bam 都是 foo 的后代。

child 完成对日志处理后,默认将日志消息传递给与其祖先 loggers 相关的 handlers,因此,通常只需要设置顶层的 logger 及其 handlers ,然后按需设置子类。

也可以将 logger 的 propagate 属性设置为 False 来关闭这种传递机制。

使用示例

默认会输出到终端,可以直接类似如下方式使用。

import logging

logging.basicConfig(
	level=logging.DEBUG,
	format='%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
logging.info('this is a loggging info message')
logging.debug('this is a loggging debug message')
logging.warning('this is loggging a warning message')
logging.error('this is an loggging error message')
logging.critical('this is a loggging critical message')

更多示例如下。

import logging

format ='[%(levelname)8s]\t (%(threadName)10s)\t %(message)30s')

logger = logging.getLogger('mylogger')    # 创建一个 logger ,默认使用 root 作为名称
logger.setLevel(logging.DEBUG)            # DEBUG/INFO/WARNING/ERROR/CRITICAL
logger.addHandler()
logger.addFilter()
logger.debug()

fh = logging.FileHandler('test.log')      # 创建一个 handler ,用于写入日志文件
fh.setLevel(logging.DEBUG)
fh.setFormatter()
fh.addFilter()
fh.removeFilter()

ch = logging.StreamHandler()              # 再创建一个 handler ,用于输出到控制台
ch.setLevel(logging.DEBUG)

# 定义handler的输出格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
ch.setFormatter(formatter)

# Logger.addHandler() Logger.removeHandler()
# Logger.addFilter()  Logger.removeFilter()
#
logger.addHandler(fh)                     # 给 logger 添加 handler
logger.addHandler(ch)

logger.info('foorbar')                    # 记录一条日志

日志处理流程

日志的写入流程如下图所示。

logging process

简单描述下日志的处理流程:

  1. 用户代码中调用日志记录函数,如 logger.info(...)logger.debug(...) 等;
  2. 判断日志级别是否满足,可以通过 logger.setLevel(logging.DEBUG) 进行设置;
  3. 根据日志记录函数调用时掺入的参数,创建一个日志记录 (Class LogRecord) 对象;
  4. 判断 logger 上设置的过滤器规则,不满足则将日志记录交给该 logger 上的各个 handler;
  5. 判断要记录的日志级别是否满足 handler 设置的级别要求;

注意,其中有一步如果 propagate 值为 1,那么日志会直接传递给上级 logger 的 handlers 进行处理,此时上一级 logger 的日志等级并不会对该日志消息进行等级过滤。



如果喜欢这里的文章,而且又不差钱的话,欢迎打赏个早餐 ^_^


About This Blog

Recent Posts

Categories

Related Links

  • RTEMS
    RTEMS
  • GNU
  • Linux Kernel
  • Arduino

Search


This Site was built by Jin Yang, generated with Jekyll, and hosted on GitHub Pages
©2013-2018 – Jin Yang