Python日志模块全面解析
文章目录
前言:为什么不用print而要用logging?
日常的开发离不开日志,打印日志可以帮助我们排查问题、熟悉代码框架。打印一条日志,简单的print就行,那为什么还要用logging模块呢?print的确能够打印日志,但是当遇到复杂的工业场景,print就显得力不从心了。
一、logging模块的五大核心优势
1. 分级管理
日志分为五级(DEBUG/INFO/WARNING/ERROR/CRITICAL),可动态控制输出。比如:
2. 格式定制
自动添加时间、模块名、行号等信息,告别手动拼接字符串的麻烦。
# 示例格式:2023-10-01 12:00:00 - WARNING - main.py (Line 10) - 文件内容为空
3. 多路输出
一条日志可同时输出到控制台、文件、甚至发送邮件给运维人员。想象这样一个场景:将ERROR级日志实时发送到运维群聊,而DEBUG日志持久化到数据库。
4. 异常捕获
无需修改代码,通过配置文件即可调整日志行为,适合微服务环境。
5. 动态控制
无需修改代码,通过logging.config模块或字典配置就能动态调整日志行为。这在微服务架构中尤为重要,可以通过热更新配置实现日志策略切换。
二、logging模块核心组件
1. Logger(记者)
2. Handler(发布渠道)
3. Filter(过滤器)
4. Formatter(排版工具)
三、怎么使用logging模块
1.基础使用:控制台日志
import logging
import logging
logging.debug("this is a debug message.")
logging.info("this is a info message.")
logging.warning("this is a warning message!")
logging.error("this is a error message!")
logging.critical("this is a critical message!")
输出如下:
WARNING:root:this is a warning message!
ERROR:root:this is a error message!
CRITICAL:root:this is a critical message!
为什么debug和info级别的日志都没输出呢?这是因为logging默认的输出级别就是warning,即只输出warning级别或更高级别的日志。
这里,介绍一下日志的分级,按照严重性,由低到高为:
级别 | 使用场景 |
---|---|
DEBUG | 记录详细信息,通常在诊断问题时使用 |
INFO | 记录常规信息,确认一切按期进行 |
WARNING | 表示发生了意外情况,或在不久的将来会出现某些问题(例如“磁盘空间不足”)。程序仍按预期工作。 |
ERROR | 发生了更严重的问题,程序无法执行某些功能 |
CRITICAL | 发生了严重错误,程序本身可能无法继续运行 |
2.将日志写到文件
上面只是在控制台输出日志,在生产开发环境中,往往需要将日志打印到文件中保存起来,以便日后使用。实现如下:
import logging
logger = logging.getLogger(__name__)
logging.basicConfig(filename='test.log', encoding='utf-8', level=logging.INFO)
logger.debug("this is a debug message.")
logger.info("this is a info message.")
logger.warning("this is a warning message!")
logger.error("this is a error message!")
logger.critical("this is a critical message!")
这样,日志就打印到了文件test.log中,如下:
INFO:__main__:this is a info message.
WARNING:__main__:this is a warning message!
ERROR:__main__:this is a error message!
CRITICAL:__main__:this is a critical message!
在上面,第二行创建了一个记录器logger,并直接使用模块的名字作为记录器的名字(在日志中体现为__main__),如果不设置,系统会默认创建名为root的根记录器(在日志中体现为root,如1简单使用中的输出)。
第三行对记录器进行一些基本的配置,设置了日志文件名、编码方式和日志级别,这都是通过logging.basicConfig配置的,其支持的所有配置有:
下面详细介绍下一些重要的字段
format
它接受一个字符串,其中可以包含各种日志记录的字段占位符,这些占位符会在日志记录时被实际的值替换。常用占位符有:
占位符 | 含义 |
---|---|
%(asctime)s | 日志记录的时间,格式默认为 YYYY-MM-DD HH:MM:SS,sss |
%(levelname)s | 日志级别,如 DEBUG、INFO、WARNING、ERROR、CRITICAL |
%(name)s | 日志记录器的名称 |
%(message)s | 日志消息内容 |
%(filename)s | 包含日志记录调用的源文件的文件名 |
%(lineno)s | 日志记录调用所在的源文件的行号 |
该字段默认格式为levelname:name:message,比如上面的日志中,
levelname是INFO,name是__main__,message是this is a info message.,这三者之间用冒号分隔
如下,使用上面提到的6个常用占位符,打印一条日志:
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(name)s - %(filename)s - %(lineno)s - %(message)s')
logging.info("this is a info message.")
2025-03-17 15:30:54,006 – INFO – root – test.py – 3 – this is a info message.
style
支持’%', ‘{’ 或 '$'三种风格:
# 使用 % 风格配置日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', style='%')
# 使用 { 风格配置日志
logging.basicConfig(level=logging.INFO, format='{asctime} - {levelname} - {message}', style='{')
# 使用 $ 风格配置日志
logging.basicConfig(level=logging.INFO, format='$asctime - $levelname - $message', style='$')
3. 记录变量
logging也支持记录变量,支持’%', ‘{’ 或 '$'三种风格格式化的方式
logging.warning('It is %s, %d years old, %.2fm high', 'Tom', 6, 1.2)
WARNING:root:It is Tom, 6 years old, 1.20m high
总结
为什么用logging?:专业分级、灵活输出、规范管理。
核心四件套:Logger(收集)、Handler(输出)、Filter(过滤)、Formatter(排版)。
避坑指南:
优先使用Logger对象而非全局的logging.xxx()。
生产环境避免日志文件无限增长(用RotatingFileHandler)。
通过合理配置logging模块,你的程序将拥有清晰的“诊断报告”,问题排查效率提升10倍!
参考链接:
https://docs.python.org/3/howto/logging.html#logging-basic-tutorial
作者:程序员出道