Python logging 日志模块

介绍

Python 内置的 logging 是标准日志模块,替代 print(),用于程序调试、问题排查、运行记录,支持分级输出、文件持久化、格式化、多模块复用等核心功能,是生产环境必备工具。

为什么用 logging,不用 print?

特性 print() logging
日志分级 无,全部输出 5 个级别,可开关
持久化 需手动写文件 自动写入文件
格式美化 无 时间、级别、模块、行号
多模块复用 不支持 全局单例,随处调用
生产环境 禁用麻烦 可直接关闭调试日志

结论:只要是正式项目,必须用 logging。


日志 5 个级别(从低到高)

DEBUG < INFO < WARNING < ERROR < CRITICAL
  • DEBUG:调试细节,开发时用
  • INFO:程序正常运行信息(如启动成功)
  • WARNING:警告,不影响运行,但需要注意
  • ERROR:错误,部分功能失败
  • CRITICAL:严重错误,程序可能崩溃

默认级别:WARNING,低于它的日志不会输出。


入门使用

import logging

# 基础配置
logging.basicConfig(level=logging.DEBUG)

# 输出日志
logging.debug("调试信息")
logging.info("普通信息")
logging.warning("警告信息")
logging.error("错误信息")
logging.critical("严重错误")

输出:

DEBUG:root:调试信息
INFO:root:普通信息
WARNING:root:警告信息
ERROR:root:错误信息
CRITICAL:root:严重错误

进阶使用-基本配置

通过 basicConfig 常用参数

logging.basicConfig(
    # 1. 日志级别
    level=logging.DEBUG,

    # 2. 输出到文件(默认控制台)
    filename="app.log",

    # 3. 写入模式:w=覆盖,a=追加
    filemode="a",

    # 4. 日志格式(最关键)
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s - %(lineno)d",

    # 5. 时间格式
    datefmt="%Y-%m-%d %H:%M:%S"
)

常用 format 字段

字段 含义
%(asctime)s 时间
%(name)s 日志器名称
%(levelname)s 日志级别
%(message)s 日志内容
%(lineno)d 代码行号
%(filename)s 文件名
%(module)s 模块名

logging 四大核心组件

logging 不是简单函数,而是模块化设计,由 4 个组件协作:

1. Logger(日志器)

产生日志的入口,全局唯一,可设置级别。

logger = logging.getLogger("my_app")  # 命名日志器
logger.setLevel(logging.DEBUG)

2. Handler(处理器)

决定日志输出到哪:

  • StreamHandler → 控制台
  • FileHandler → 文件
  • RotatingFileHandler → 按大小切分
  • TimedRotatingFileHandler → 按时间切分(生产常用)

3. Formatter(格式器)

定义日志长什么样。

4. Filter(过滤器)

过滤不需要的日志(极少用)。


高级使用-企业级标准配置

同时输出到控制台 + 文件 + 自动按天切割

import logging
from logging.handlers import TimedRotatingFileHandler

def get_logger():
    # 1. 创建日志器
    logger = logging.getLogger("my_project")
    logger.setLevel(logging.DEBUG)  # 全局最低级别
    logger.handlers.clear()  # 避免重复添加handler

    # 2. 日志格式
    formatter = logging.Formatter(
        "%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s",
        datefmt="%Y-%m-%d %H:%M:%S"
    )

    # 3. 控制台处理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.DEBUG)
    console_handler.setFormatter(formatter)

    # 4. 文件处理器(每天生成一个文件,保留 30 天)
    file_handler = TimedRotatingFileHandler(
        filename="project.log",
        when="midnight",  # 每天凌晨切割
        interval=1,
        backupCount=30,
        encoding="utf-8"
    )
    file_handler.setLevel(logging.INFO)  # 文件只记录 INFO 及以上
    file_handler.setFormatter(formatter)

    # 5. 添加处理器
    logger.addHandler(console_handler)
    logger.addHandler(file_handler)

    return logger

# 全局使用
logger = get_logger()

使用:

logger.debug("连接数据库成功")
logger.info("服务启动")
logger.warning("磁盘空间不足")
logger.error("请求接口失败")

多模块使用

只要名字相同,全局共用一个日志器,不用重复配置。

a.py

from log_config import logger

def test():
    logger.info("a 模块运行")

b.py

from log_config import logger

def run():
    logger.error("b 模块出错")

main.py

import a
import b
from log_config import logger

logger.info("主程序启动")
a.test()
b.run()

所有日志统一输出,不会混乱。


常见问题与坑

1. 日志重复输出

原因:多次 addHandler
解决:每次获取 logger 前清空

logger.handlers.clear()

2. 中文乱码

文件处理器加 encoding="utf-8"

FileHandler("app.log", encoding="utf-8")

3. 日志不输出

检查级别:

logger.setLevel(logging.DEBUG)
handler.setLevel(logging.DEBUG)

使用建议

  1. 项目 只配置一次 logger,全局复用
  2. 开发用 DEBUG,生产用 INFO
  3. 文件日志用 TimedRotatingFileHandler 按天切割
  4. 格式必须包含:时间、级别、文件名、行号
  5. 禁止在生产环境用 print()

总结

  • logging 是 Python 标准日志库,功能强大、生产必备
  • 5 个级别:DEBUG/INFO/WARNING/ERROR/CRITICAL
  • 四大组件:Logger/Handler/Formatter/Filter
  • 企业用法:控制台 + 按天切割文件 + 统一格式
  • 多项目可直接复制我提供的标准配置使用

原文出处:/show_1GW3IGLyrUEx.html