logging 是 Python 标准库中的一个模块,用于记录和管理应用程序的日志信息。相较于直接使用 print,logging 模块提供了更灵活、更强大的日志记录功能,能够控制日志的输出格式、级别、目标位置(如文件、控制台),以及自动处理日志文件轮换等操作。
相关链接:
官方文档
一、logging 模块的基本概念
Logger:
Logger 是日志系统的核心对象,负责记录日志消息。每个日志记录都与一个 Logger 实例关联,且可以有不同的日志级别和输出目标。
Log Level(日志级别):
- 日志级别用于指定日志的重要性,
logging 提供了五种常用的日志级别:DEBUG:详细信息,通常只在诊断问题时使用。INFO:确认一切按预期运行的消息。WARNING:表示可能会出现的问题,提醒你要注意。ERROR:表示程序在执行某些操作时遇到了问题,但程序没有停止运行。CRITICAL:表示严重的错误,可能导致程序无法继续运行。
Handler(处理器):
Handler 决定了日志消息的输出目标,比如输出到文件、控制台或远程服务器。logging 支持多种处理器,如 StreamHandler(输出到控制台)、FileHandler(输出到文件)等。
Formatter(格式化器):
Formatter 用于指定日志消息的显示格式,比如是否包括时间戳、日志级别等信息。
Filter(过滤器):
Filter 可以进一步控制哪些日志消息会被处理器记录,通常用于根据自定义规则过滤日志。
二、logging 的基本使用步骤
- 基本配置:
可以使用
logging.basicConfig 配置日志系统,指定日志的级别、格式以及输出目标。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| import logging
# 配置日志记录器
logging.basicConfig(
level=logging.INFO, # 设置日志级别为INFO,DEBUG级别的日志不会显示
format='%(asctime)s - %(levelname)s - %(message)s', # 设置日志的输出格式
datefmt='%Y-%m-%d %H:%M:%S', # 设置时间格式
handlers=[logging.StreamHandler()] # 指定输出到控制台
)
# 开始记录日志
logging.debug("这是一条调试信息")
logging.info("这是一条普通信息")
logging.warning("这是一个警告信息")
logging.error("这是一个错误信息")
logging.critical("这是一个严重错误信息")
|
输出示例:
1
2
3
4
| 2024-09-24 15:35:12 - INFO - 这是一条普通信息
2024-09-24 15:35:12 - WARNING - 这是一个警告信息
2024-09-24 15:35:12 - ERROR - 这是一个错误信息
2024-09-24 15:35:12 - CRITICAL - 这是一个严重错误信息
|
但是注意⚠️,什么时候不适合使用 basicConfig:
• basicConfig 是全局性的:一旦调用 basicConfig,它会应用于全局日志配置。如果你想为每个 Worker 实例创建单独的 logger,且可能有不同的日志级别或输出目标,basicConfig 不能满足这个需求。
• 自定义多个 Handler:当你需要为不同的 logger 配置不同的 Handler(如文件处理器、控制台处理器等)时,basicConfig 过于简单,无法为不同的实例分别配置。
- Logger 的基本用法:
你可以创建多个
Logger 实例来记录不同模块的日志。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| import logging
# 创建一个自定义的Logger
logger = logging.getLogger('my_logger')
# 设置Logger的日志级别
logger.setLevel(logging.DEBUG)
# 创建Handler,设置输出位置和日志格式
handler = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
# 将Handler添加到Logger中
logger.addHandler(handler)
# 记录日志
logger.debug("调试信息")
logger.info("普通信息")
logger.warning("警告信息")
logger.error("错误信息")
logger.critical("严重错误信息")
|
输出示例:
1
2
3
4
5
| 2024-09-24 15:35:12 - my_logger - DEBUG - 调试信息
2024-09-24 15:35:12 - my_logger - INFO - 普通信息
2024-09-24 15:35:12 - my_logger - WARNING - 警告信息
2024-09-24 15:35:12 - my_logger - ERROR - 错误信息
2024-09-24 15:35:12 - my_logger - CRITICAL - 严重错误信息
|
三、logging 配置详解
日志级别控制:
日志系统会过滤比设置级别低的日志。例如设置为 INFO 级别,则 DEBUG 级别的日志不会显示。
1
| logging.basicConfig(level=logging.WARNING)
|
日志格式化:
格式化器定义了日志的输出格式。常用的格式占位符有:
%(asctime)s:日志的时间%(name)s:Logger 的名称%(levelname)s:日志的级别%(message)s:日志消息内容
例如:
1
| formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
|
Handler(处理器):
Handler 定义了日志的输出目标。常用的处理器包括:
StreamHandler:将日志输出到控制台。FileHandler:将日志输出到文件中。
例如,将日志记录到文件中:
1
2
| file_handler = logging.FileHandler('logfile.log')
file_handler.setLevel(logging.INFO)
|
日志轮换:
logging 还支持日志文件轮换,通过 RotatingFileHandler 来限制日志文件的大小,并可以自动备份日志。
1
2
3
4
5
| from logging.handlers import RotatingFileHandler
# 创建一个RotatingFileHandler, 10MB为最大文件大小,最多保留5个旧文件
handler = RotatingFileHandler('logfile.log', maxBytes=10*1024*1024, backupCount=5)
logger.addHandler(handler)
|
四、综合示例:多处理器输出日志并使用日志轮换
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
| import logging
from logging.handlers import RotatingFileHandler
# 创建日志记录器
logger = logging.getLogger('my_logger')
logger.setLevel(logging.DEBUG)
# 创建一个控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
# 创建一个日志文件处理器,并设置轮换机制
file_handler = RotatingFileHandler('app.log', maxBytes=5*1024*1024, backupCount=3)
file_handler.setLevel(logging.DEBUG)
# 设置日志格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)
file_handler.setFormatter(formatter)
# 将处理器添加到日志记录器中
logger.addHandler(console_handler)
logger.addHandler(file_handler)
# 测试日志
logger.debug("这是调试信息")
logger.info("这是普通信息")
logger.warning("这是警告信息")
logger.error("这是错误信息")
logger.critical("这是严重错误信息")
|
五、未捕获异常自动记录
通过全局捕获异常的 sys.excepthook,可以将未捕获的异常记录到日志中:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| import logging
import sys
# 配置日志记录器
logging.basicConfig(level=logging.ERROR, filename='error.log')
def handle_exception(exc_type, exc_value, exc_traceback):
if issubclass(exc_type, KeyboardInterrupt):
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
logging.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
# 全局未捕获异常的处理
sys.excepthook = handle_exception
# 测试未捕获异常
raise ValueError("测试未捕获的异常")
|
总结
logging 提供了强大且灵活的日志管理功能,适用于简单到复杂的应用。- 你可以控制日志的输出位置、格式、轮换机制,以及日志级别过滤。
- 通过捕获未处理的异常,确保应用程序在遇到异常时能够记录下详细信息,便于调试和维护。
根据项目需求,你可以简单地使用 basicConfig 来快速记录日志,或者配置复杂的 Logger 来满足更高级的日志需求。
💬 评论