4 - Python内置模块 - logging模块

本文详细介绍了Python内置的logging模块,包括日志级别、日志格式字符串、快速使用方法,如修改日期格式、输出到文件及构建消息。还讨论了logger类、handler类、Formatter类和Filter类的功能和使用,以及日志信息的传递流程和处理机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 logging模块

这个模块定义了一些函数和类,它们为应用程序和库实现了一个灵活的事件日志系统。下面先来了解下日志的级别分类。

1.1 日志级别

下面是日志级别以及对应的数字值表:

Level Numeric value
CRITICAL 50
ERROR 40
WARNING 30
INFO 20
DEBUG 10
NOTSET 0

之所以设置级别是为了控制输出信息,以及针对日志进行了分类:

  • Error一般为程序的错误信息
  • Warning为程序的告警信息
  • info和debug则可以是提示或者调试信息

当我们需要对我们的程序运行时输出的日志进行分类打印时,可以使用这种简便而快速的方法。

基本上所以的软件程序日志输出都分为上述级别。

1.2 日志格式字符串

logging模块中定义好的可以用于format格式字符串常用的如下:

字段/属性名称 使用格式 描述
asctime %(asctime)s 日志事件发生的时间–人类可读时间,如:2003-07-08 16:49:45,896
created %(created)f 日志事件发生的时间–时间戳,就是当时调用datetime.datetime.now()函数返回的值
relativeCreated %(relativeCreated)d 日志事件发生的时间相对于logging模块加载时间的相对毫秒数(目前还不知道干嘛用的)
msecs %(msecs)d 日志事件发生事件的毫秒部分
levelname %(levelname)s 该日志记录的文字形式的日志级别(‘DEBUG’, ‘INFO’, ‘WARNING’, ‘ERROR’, ‘CRITICAL’)
levelno %(levelno)s 该日志记录的数字形式的日志级别(10, 20, 30, 40, 50)
name %(name)s 所使用的日志器名称,默认是’root’,因为默认使用的是 rootLogger
message %(message)s 日志记录的文本内容,通过 msg % args计算得到的
pathname %(pathname)s 调用日志记录函数的源码文件的全路径
filename %(filename)s pathname的文件名部分,包含文件后缀
module %(module)s filename的名称部分,不包含后缀
lineno %(lineno)d 调用日志记录函数的源代码所在的行号
funcName %(funcName)s 调用日志记录函数的函数名
process %(process)d 进程ID
processName %(processName)s 进程名称,Python 3.1新增
thread %(thread)d 线程ID
threadName %(thread)s 线程名称

1.3 快速使用

了解了级别和格式,我们就可以按照如下方式定义日志然后输出了。

import logging

FORMAT = "%(asctime)s loggerName:%(name)s logLevel:%(levelname)s logNum:%(levelno)s Line:%(lineno)s message:%(message)s"
logging.basicConfig(level=logging.INFO, format=FORMAT)

logging.info("hello world")
# 2019-03-05 21:42:01,952 loggerName:root logLevel:INFO logNum:20 Line:6 message:hello world

注意:

日志格式,这里使用了空格进行分段,便于收集处理,当然分割符是自己指定的,但最好不要用00分割,会产生意想不到的问题

1.3.1 修改日期格式

basicConfig提供了一个参数datefmt用来便捷的修改日志为指定格式

import logging

FORMAT = "%(asctime)s %(name)s %(levelname)s %(levelno)s %(lineno)s %(message)s"
logging.basicConfig(level=logging.INFO, format=FORMAT, datefmt='%Y-%m')

logging.error("hello world")
# 2019-03 root ERROR 40 6 hello world

格式采用c风格的标准的时间占位符,比如:"%Y/%m/%d %H:%M:%S"

1.3.2 输出到文件中

basicConfig的filename参数用于指定输出的文件名称以及文件的位置。

import logging

FORMAT = "%(asctime)s %(name)s %(levelname)s %(levelno)s %(lineno)s %(message)s"
logging.basicConfig(level=logging.INFO, format=FORMAT, datefmt='%Y-%m', filename='log.txt')

logging.error("hello world")

1.3.3 构建消息

如果需要自定义format中关键字占位符,动态的传递消息,可以使用extra来传递

import logging

FORMAT = "%(asctime)s %(helloworld)s %(message)s"
logging.basicConfig(level=logging.INFO, format=FORMAT, datefmt='%Y/%m/%d %H:%M:%S')

logging.error("hello world", extra={
   'helloworld':'daxin'})
# 2019/03/05 22:04:03 daxin hello world

在调用时通过extra传递字典来为自定义关键字传值。(很少用)

2 处理流程

logging模块要输出一个日志要经过以下工序:
loggingflow
看起来相对比较复杂,那么先从四大组件开始了解

3 logger类

        logger类被称为日志记录器,但从来不直接实例化,总是通过logging.getLogger(name)来实例化。对于具有相同名称的getLogger()的多次调用总是返回对同一个Logger对象的引用。它的主要功能有:

  1. 基于日志严重等级(默认的过滤设施)或filter对象(过滤器)来决定要对哪些日志进行后续处理;
  2. 将日志消息传送给所有绑定的日志handlers。

消息的级别会通过getEffectiveLevel()转换为数字和logger设置的级别想比较,只有大于等于,才会被logger转发至所有绑定的handler

3.1 getLogger工厂方法

        logging模块建议使用getlogger方法,来构建一个新的logger实例,并且当传入的name相同时,多次执行返回的是相同的logger,为什么这样做呢?因为logger本身是跨线程的,并且是线程安全的,我们没必要为每一个线程创建一个用于输出日志的logger,而且这样很浪费内存空间。

习惯上称getLogger为工厂方法

import logging

mylogger = logging.getLogger('daxin')        # logger的名称必须为str
print(mylogger)  # <Logger daxin (WARNING)>  

这样就构建了一个logger,级别为warning,那为什么是warning呢,和logger的父系结构有关。

3.2 实例常用方法

logger类包含如下常用方法:

方法 功能
setLevel(level) 设置logger的日志级别,可以设置为数字或者logging对应的级别
getEffectiveLevel() 获取对应的数字级别显示
addHandler(hdlr) 为logger添加一个Handler,可以添加多个
removeHandler(hdlr) 为logger删除一个Handler
addFilter(filter) 为logger添加一个Filter,可以添加多个
removeFilter(filter) 为logger删除一个Filter
getChild(suffix) 为logger创建一个子logger

以及对应分类的触发日志的方法:

方法 功能
debug(msg, *args, **kwargs) 标识消息为 debug/10 级别
info(msg, *args, **kwargs) 标识消息为 info/20 级别
warning(msg, *args, **kwargs) 标识消息为 warning/30 级别
error(msg, *args, **kwargs) 标识消息为 error/40 级别
critical(msg, *args, **kwargs) 标识消息为 critical/50 级别

logger对象具有的属性:

属性 含义
handlers 所有绑定的handler列表
level 当前logger的级别
name 当前logger的名称
parent 当前logger的父logger,根节点为root
filters 所有绑定的filter列表
propagate 是否进行消息传递(默认为True,表示传递) – 后面会说

举个栗子&#

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值