python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > python logging日志

python进阶之logging日志模块的使用

作者:青铜发条

Python logging模块功能强大,支持多级别、多输出、格式化,核心组件,下面就来具体介绍一下logging日志模块的使用,具有一定的参考价值,感兴趣的可以了解一下

引言

在软件开发中,日志(Logging)是不可或缺的工具。它帮助我们追踪程序执行流程、诊断错误、监控系统状态,是调试、运维和分析用户行为的关键。Python 内置的 logging 模块功能强大且灵活,远超简单的 print 语句。

一、logging对比print

你可能习惯用 print() 输出信息,但 logging 模块提供了 print 无法比拟的优势:

二、基本使用方法

2.1 导入 logging 模块

import logging

2.2 日志级别介绍

日志级别用于控制日志的详细程度。logging 模块提供了以下几种日志级别:

级别数值说明
CRITICAL50致命,严重错误,程序可能无法继续运行
ERROR40错误,但程序仍可运行
WARNING30警告,表示潜在的问题,但程序仍能正常运行。默认级别)
INFO20提示,程序正常运行时的信息
DEBUG10调试,详细的调试信息,通常用于开发阶段
NOTSET0继承,继承父记录器的级别

注意:默认日志级别是 WARNING,即低于 WARNING 的日志不会被输出。

需要设置日志显示的最低显示级别。如显示所有日志,设置为最低级别DEBUG:

logging.basicConfig(level=logging.DEBUG)

2.3 简单使用示例

快速使用日志的完整功能示例:

import logging
logging.basicConfig(level=logging.INFO)

logging.debug("这是一条调试信息")
logging.info("这是一条普通信息")
logging.warning("这是一条警告信息")
logging.error("这是一条错误信息")
logging.critical("这是一条严重错误信息")

运行结果:

三、logging 模块的核心组件

logging 模块基于一个经典的 生产者-过滤器-处理器 模型,主要由四个核心对象构成:

说明示例
logging.Logger记录器,用于发出日志消息logger = logging.getLogger("my_logger")
logging.Handler处理器,决定日志输出位置(如文件、控制台等)handler = logging.FileHandler("app.log")
logging.Formatter格式化器,控制日志输出的格式formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
logging.Filter过滤器,用于更精细地控制日志记录filter = logging.Filter("module.name")

3.1 Logger (记录器)

角色:应用程序的接口。你通过 Logger 对象调用 debug(), info(), warning(), error(), critical() 方法来记录日志。

关键属性:

层级结构:Logger 按名称形成树状结构。myapp 是 myapp.module 的父 Logger。日志消息会沿着这个层级向上传播,除非设置了 propagate=False。

3.2 Handler (处理器)

角色:决定日志消息的最终去向。一个 Logger 可以有多个 Handler

常见 Handler

处理器说明
StreamHandler输出到控制台(sys.stdout / sys.stderr)
FileHandler输出到文件(文本)
RotatingFileHandler按大小轮转日志文件
TimedRotatingFileHandler按时间轮转日志文件
SMTPHandler通过邮件发送日志
SocketHandler / DatagramHandler通过网络发送日志
NullHandler空处理器,用于避免无 handler 时的警告

3.3 Formatter (格式化器)

Formatter 常用格式字段如下:

字段说明示例输出
%(asctime)s日志创建时间2023-01-01 12:00:00,123
%(levelname)s日志级别名称INFO
%(message)s日志消息内容程序启动成功
%(name)s记录器名称my_logger
%(filename)s生成日志的文件名app.py
%(lineno)d生成日志的行号42
%(funcName)s生成日志的函数名main
%(pathname)s生成源文件的完整路径
%(module)s生成模块名(文件名去掉 .py)
%(process)d生成进程ID
%(thread)d生成线程 ID

3.4 Filter (过滤器)

3.5 核心组件快速使用示例

import logging

# 1. 获取一个 Logger 实例(通常使用模块名)
logger = logging.getLogger(__name__)

# 2. 设置 Logger 级别
logger.setLevel(logging.DEBUG)

# 3. 创建 Handler (例如,输出到控制台)
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO) # Handler 级别

# 4. 创建 Formatter
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
console_handler.setFormatter(formatter)

# 5. 将 Handler 添加到 Logger
logger.addHandler(console_handler)

# 6. 记录日志
logger.debug("调试信息")
logger.info("普通信息")
logger.warning("警告信息")
logger.error("错误信息")
logger.critical("严重错误")

运行结果:

四、高级用法与最佳实践

1、配置分离:将日志配置独立出来

将配置放在单独的文件中,是大型项目的标准做法。推荐使用 dictConfig

# logging_config.py
import logging
from logging.config import dictConfig
​
LOGGING_CONFIG = {
    "version": 1,
    "disable_existing_loggers": False,  # 避免禁用第三方库日志
    "formatters": {
        "detailed": {
            "format": "%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s"
        },
        "simple": {
            "format": "%(name)s - %(levelname)s - %(message)s"
        }
    },
    "handlers": {
        "file": {
            "class": "logging.handlers.RotatingFileHandler", # 轮转文件
            "level": "DEBUG",
            "formatter": "detailed",
            "filename": "app.log",
            "maxBytes": 10485760,  # 10MB
            "backupCount": 5,      # 保留 5 个备份
            "encoding": "utf-8"
        },
        "console": {
            "class": "logging.StreamHandler",
            "level": "INFO",
            "formatter": "simple"
        }
    },
    "loggers": {
        "myapp": {  # 为你的应用定义 logger
            "level": "DEBUG",
            "handlers": ["file", "console"],
            "propagate": False
        }
    }
}
​
dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("myapp") # 创建全局 logger 实例

在其他模块中使用:

# main.py
from logging_config import logger
​
logger.info("应用启动")

2、RotatingFileHandler 分割日志文件

FileHandler 会无限增长文件。使用 RotatingFileHandlerTimedRotatingFileHandler 可以自动管理日志文件大小和数量。

3、捕获异常信息

try:
    result = 1 / 0
except Exception as e:
    logger.error("发生异常", exc_info=True) # exc_info=True 会自动记录 traceback
    # 或者使用
    # logger.exception("发生异常") # 等价于 logger.error(..., exc_info=True)

4、在多模块项目中使用name

# myapp/utils.py
import logging
logger = logging.getLogger(__name__) # __name__ 是 'myapp.utils'
​
def some_function():
    logger.info("在 utils 模块中执行")

这样日志会清晰地显示来源 myapp.utils - INFO - 在 utils 模块中执行

5、避免重复日志

问题:如果 Loggerpropagate=True(默认)且父 Logger 也有 Handler,日志可能被多次输出。

解决方案:在配置中为你的应用 Logger 设置 "propagate": False

处理中文FileHandlerRotatingFileHandler 中指定 encoding="utf-8"

总结

Python 的 logging 模块是一个功能完备、设计精良的日志框架。掌握其核心组件(Logger, Handler, Formatter, Filter)的工作原理,是构建可靠应用的基础。通过合理的配置(尤其是使用 dictConfig 分离配置),你可以轻松实现:

告别 print,拥抱 logging,让你的应用拥有清晰、可追溯的“生命日志”!

到此这篇关于python进阶之logging日志模块的使用的文章就介绍到这了,更多相关python logging日志 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文