python日志处理
一、日志概念
日志是一种可以追踪某些软件运行时所发生事件的方法。 软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情。 一个事件可以用一个可包含可选变量数据的消息来描述。 此外,事件也有重要性的概念,这个重要性也可以被称为严重性级别(level)。
Python自身也提供了一个用于记录日志的标准库模块--logging。 logging模块定义的函数和类为应用程序和库的开发实现了一个灵活的事件日志系统,由标准库模块提供日志记录API,关键好处是所有Python模块都可以使用这个日志记录功能。 所以,你的应用日志可以将你自己的日志信息与来自第三方模块的信息整合起来。
总之,日志的作用就是:
- 调试软件程序
- 了解软件程序运行情况,确定软件运行是否运行正常
- 软件程序故障分析与定位
二、logging模块
1、logging日志级别
| 日志级别 | 数值 | 使用范围 |
|---|---|---|
| CRITICAL | 50 | 特别糟糕的事情,如内存耗尽,磁盘空间为空,一般很少使用 |
| ERROR | 40 | 发生错误时,如IO操作失败或者连接问题 |
| WARNING | 30 | 发生很重要的事情,但并不是错误,是警告信息 |
| INFO | 20 | 处理请求或者状态变化等日常事务 |
| DEBUG | 10 | 调试过程中使用DEBUG等级,如算法中每个循环的中间状态 |
| NOTSET | 0 | 很少使用 |
内建等级中,级别最低的是DEBUG,级别最高的是CRITICAL。例如setLevel(logging.INFO),此时函数参数为INFO,那么该logger将只会处理INFO、WARNING、ERROR和CRITICAL级别的日志,而DEBUG级别的消息将会被忽略/丢弃。
2、logging四大组件
在实际操作中,一般是先创建日志记录器(logging.getLogger),然后再设置日志级别(logger.setLevel),接着再创建日志文件,也就是日志保存的地方(logging.FileHandler),然后再设置日志格式(logging.Formatter),最后再将日志处理程序记录到记录器(addHandler)

| 组件名称 | 类名 | 功能简介 |
|---|---|---|
| 日志器 | Logger | 可供程序直接调用的接口,app通过调用提供的api来记录日志 |
| 处理器 | Handler | 决定将日志记录分配至正确的目的地 |
| 过滤器 | Filter | 对日志信息进行过滤,提供更细粒度的日志来判断输出哪条日志记录 |
| 格式器 | Formatter | 决定日志记录的最终输出格式 |
日志器(loggers)是入口,真正工作的是处理器(handler),处理器(handler)还可以通过过滤器(filter)和格式器(formatter)对要输出的日志内容做过滤和格式化等处理操作。
Logger类:配置方法和消息发送方法
- 配置方法
| 方法 | 功能描述 |
|---|---|
| Logger.setLevel() | 设置记录器将会处理的最低严重级别的日志 |
| Logger.addHandler() | 为Logger对象添加一个handler对象 |
| Logger.removeHandler() | 为Logger对象移除一个handler对象 |
| Logger.addFilter() | 为Logger对象添加一个filter对象 |
| Logger.removeFilter() | 为Logger对象移除一个filter对象 |
- 消息发送方法
| 方法 | 功能描述 |
|---|---|
| Logger.debug(),Logger.info(),Logger.warning(),Logger.error(),Logger.critical(), | 创建一个与其方法名对应等级的日志记录 |
| Logger.exception() | 创建一个类似与Logger.error()的日志记录 |
| Logger.log() | 需要获取一个明确的日志level参数来创建一个日志记录 |
Handler类:常用配置方法
| 方法 | 功能描述 |
|---|---|
| Handler.setLevel() | 设置Handler将会处理的最低严重级别的日志 |
| Handler.setFormatter() | 为Handler设置一个格式器对象 |
| Handler.addFilter() | 为Handler添加一个过滤器对象 |
| Handler.removeFilter() | 为Handler移除一个过滤器对象 |
需要说明的是,应用程序代码不应该直接实例化和使用Handler实例。因为Handler是一个基类,它只定义了素有handlers都应该有的接口,同时提供了一些子类可以直接使用或覆盖的默认行为。下面是一些常用的Handler
| Handler | 功能描述 |
|---|---|
| logging.FileHandler | 将日志消息发送到磁盘文件,默认情况下文件大小会无限 |
| logging.StreamHandler | 将消息发送到输出到Stream,如std.out,std.err任 file-like对象,也就是显示在调试终端 |
| logging.handlers.Rotating.FileHandler | 将日志消息发送到磁盘文件,并支持日志文件按大小切割 |
| logging.handlers.TimedRotatingFileHandler | 将日志消息发送到磁盘文件,并支持日志文件按时间切割 |
| logging.handlers.HTTPHandler | 将日志消息以GET或POST的方式发送给一个HTTP服务器 |
| logging.handlers.SMTPHandler | 将日志消息发送给一个指定的email地址 |
| logging.handlers.NullHandler | 该Handler实例会忽略error messages,通常被想使用logging的library开发者使用来避免'No handlers could be found for logger XXX'信息的出现. |
Filter类:可以被Handler和Logger用来做比level更细粒度的、更复杂的过滤功能。
Formater类:用于配置日志信息的最终顺序、结构和内容
Formater对象与logging.Handler基类不同的是,应用代码可以直接实例化Formatter类。另外,如果你的应用程序需要一些特殊的处理行为,也可以实现一个Formatter的子类来完成。
| 格式 | 说明 |
|---|---|
| %(levelno)s | 打印日志级别的数值 |
| %(levelname)s | 打印日志级别的名称 |
| %(pathname)s | 打印当前执行程序的路径,其实就是sys.argv[0] |
| %(filename)s | 打印当前执行程序名 |
| %(funcName)s | 打印日志的当前函数 |
| %(lineno)d | 打印日志的当前行号 |
| %(asctime)s | 打印日志的时间 |
| %(thread)d | 打印线程ID |
| %(threadName)s | 打印线程名称 |
| %(process)d | 打印进程ID |
| %(message)s | 打印日志信息 |
三、示例
import logging
#创建日志级别
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
#创建日志文件
handler_warn = logging.FileHandler('warning_log.txt')
handler_warn.setLevel(logging.INFO)
#定义日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler_warn.setFormatter(formatter)
#将日志处理程序记录到记录器
logger.addHandler(handler_warn)

浙公网安备 33010602011771号