Python Logging库完全指南:从小白到熟练

一、为什么要使用Logging?

很多初学者喜欢用print()调试,但在实际项目中会遇到问题:

  • 项目跑起来后,不能随意中断程序查看输出
  • 需要区分不同重要程度的信息(错误、警告、普通信息)
  • 需要将日志保存到文件方便后续分析
  • 在生产环境中,需要动态调整日志详细程度

这就是Logging库存在的意义!

二、快速开始:5分钟上手

基础示例

PYTHON 复制代码
import logging

# 最简单的使用方式
logging.basicConfig(level=logging.WARN)  # 设置日志级别

logging.debug('这是一条debug信息')      # 不会显示(默认级别更高)
logging.info('这是一条info信息')        # 不会显示
logging.warning('这是一条warning信息')  # 会显示√
logging.error('这是一条error信息')      # 会显示√
logging.critical('这是一条critical信息')# 会显示√

理解日志级别(从低到高)

  1. DEBUG - 调试细节,开发时使用
  2. INFO - 普通信息,确认事情按预期运行
  3. WARNING - 警告,发生了意外但不影响运行
  4. ERROR - 错误,部分功能受影响
  5. CRITICAL - 严重错误,程序可能崩溃

重要规则: 只会显示设置级别及以上的日志!

三、核心配置:让日志更实用

1. 配置日志格式和输出

PYTHON 复制代码
# 详细配置示例
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S',
    filename='app.log',  # 输出到文件
    filemode='a',         # 追加模式
    encoding='utf-8'     # 指定UTF-8编码,解决中文乱码问题
)


# 使用
logging.info("程序启动")
logging.warning("磁盘空间不足90%")
logging.error("数据库连接失败")

2. 常用格式化字段

TEXT 复制代码
%(name)s          Logger的名字
%(levelname)s     日志级别
%(message)s       日志内容
%(asctime)s       时间,可指定格式
%(filename)s      文件名
%(funcName)s      函数名
%(lineno)d        行号

四、进阶技巧:模块化使用

在实际项目中,我们通常不直接使用logging模块,而是创建自己的Logger:

1. 创建模块专用的Logger

PYTHON 复制代码
# 在每个模块中这样做
import logging


# 创建logger实例,通常以模块名命名
logger = logging.getLogger(__name__)  # 这是最佳实践!


def process_data(data):
    logger.debug(f"开始处理数据,长度: {len(data)}")
    try:
        # 你的业务逻辑
        result = data * 2
        logger.info(f"数据处理成功,结果: {result}")
        return result
    except Exception as e:
        logger.error(f"数据处理失败: {str(e)}", exc_info=True)
        return None

2. 项目级别的配置

PYTHON 复制代码
# config_logging.py - 日志配置文件
import logging
import logging.handlers
import os


def setup_logging():
    """配置项目日志系统"""
    
    # 创建formatter(定义日志格式)
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
    )
    
    # 创建logger
    logger = logging.getLogger()  # 根logger
    logger.setLevel(logging.DEBUG)  # 设置最低级别
    
    # 控制台处理器
    console_handler = logging.StreamHandler()
    console_handler.setLevel(logging.INFO)  # 控制台只显示INFO及以上
    console_handler.setFormatter(formatter)
    
    # 文件处理器
    file_handler = logging.FileHandler('app.log')
    file_handler.setLevel(logging.DEBUG)  # 文件记录所有DEBUG及以上
    file_handler.setFormatter(formatter)
    
    # 按时间切分的文件处理器(推荐生产环境使用)
    time_handler = logging.handlers.TimedRotatingFileHandler(
        'app.log',
        when='midnight',  # 每天午夜切分
        interval=1,
        backupCount=7     # 保留7天
    )
    time_handler.setFormatter(formatter)
    
    # 添加处理器
    logger.addHandler(console_handler)
    logger.addHandler(file_handler)
    # logger.addHandler(time_handler)  # 使用这个替换上面的file_handler

五、实用场景示例

场景1:Web应用日志

PYTHON 复制代码
import logging
from logging.handlers import RotatingFileHandler


# 创建logger
logger = logging.getLogger('webapp')
logger.setLevel(logging.INFO)


# 按大小滚动日志文件(最大10MB,保留5个备份)
handler = RotatingFileHandler(
    'webapp.log',
    maxBytes=10*1024*1024,  # 10MB
    backupCount=5
)


formatter = logging.Formatter(
    '%(asctime)s - %(clientip)s - %(user)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)


# 使用(假设在请求处理中)
def handle_request(request, user):
    # 添加额外信息
    extra = {'clientip': request.client_ip, 'user': user}
    logger.info('用户登录成功', extra=extra)

场景2:不同级别日志分开存储

PYTHON 复制代码
import logging


# 配置不同的处理器
logger = logging.getLogger('myapp')


# 错误日志单独保存
error_handler = logging.FileHandler('errors.log')
error_handler.setLevel(logging.ERROR)


# 所有日志保存
all_handler = logging.FileHandler('all.log')
all_handler.setLevel(logging.DEBUG)


# 设置格式
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
error_handler.setFormatter(formatter)
all_handler.setFormatter(formatter)


logger.addHandler(error_handler)
logger.addHandler(all_handler)

六、最佳实践和小贴士

应该这样做:

  1. 尽早配置日志:在程序入口处配置,不要多处配置

  2. 使用getLogger(__name__) :自动获取模块名作为logger名

  3. 合理使用级别

    • DEBUG:调试信息
    • INFO:关键流程节点
    • WARNING:可预料的问题
    • ERROR:需要关注的错误
  4. 包含上下文信息logger.error(f"用户{user_id}操作失败")

避免这样做:

  1. 不要在所有地方都用根logger
  2. 不要在日志中记录敏感信息(密码、密钥)
  3. 不要过度记录,避免日志过大

总结

Logging库看似复杂,但核心只有几个概念:

  1. Logger - 记录器(谁在记录)
  2. Handler - 处理器(记录到哪里)
  3. Formatter - 格式化器(怎么记录)
  4. Level - 级别(记录什么)
相关推荐
止语Lab36 分钟前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活36 分钟前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困42 分钟前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn42 分钟前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530141 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908401 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金1 小时前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端
人间凡尔赛1 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
IT_陈寒2 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境2 小时前
提升 Python 代码健壮性的方法大盘点
后端·python