【新手python程序员必须明白的真相】17.新手Python程序员必须明白的日志记录技巧:logging早用对,排查问题快!

在这里插入图片描述

从print到logging:掌握这6个关键点,让你的代码学会"自检",bug无处遁形!

新手Python程序员必须明白的日志记录技巧
为什么需要日志?
基础配置四步走
等级管理艺术
格式化才是灵魂
异常处理正确姿势
性能优化实战

目录:

  1. 为什么新手需要日志?
  2. 基础配置四步走
  3. 等级管理艺术
  4. 格式化才是灵魂
  5. 异常处理正确姿势
  6. 性能优化实战

嗨,你好呀,我是你的老朋友精通代码大仙。“程序员的三大错觉:这次肯定没bug、注释不用写、日志不需要”,这话你听着耳熟吗?我见过太多新手用print调试到崩溃,最后发现日志才是排查问题的核武器。今天咱们就手把手教你用logging模块,让你的代码学会"自检"!


1. 为什么新手需要日志?

痛点场景:凌晨两点,线上服务突然挂掉。你手忙脚乱地翻着服务器上残留的print输出,却发现关键信息都没打印…

# 典型的print调试灾难
def process_data(data):
    print("开始处理数据")  # 上线后这些print全被注释了
    # ...业务逻辑...
    print(f"处理结果:{result}")  # 结果忘记取消注释

正确认知:logging模块是代码的"黑匣子",它能:

  • 自动记录时间戳
  • 区分不同严重级别的事件
  • 动态控制输出目标(文件/控制台)
  • 保留异常堆栈信息

生死案例

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

def process_data(data):
    logging.info("开始处理数据")
    try:
        # ...业务逻辑...
        logging.info(f"处理结果:{result}")
    except Exception as e:
        logging.error("数据处理异常", exc_info=True)  # 自动记录堆栈

小结:日志不是可选项,而是代码的急救包。


2. 基础配置四步走

常见翻车:直接import logging就开始用,结果发现日志没输出…

import logging
logging.debug("这行不会显示")  # 默认只显示WARNING以上级别

正确配置

import logging

# 一次性基础配置(程序启动时执行)
logging.basicConfig(
    level=logging.DEBUG,  # 设置根日志级别
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    handlers=[
        logging.FileHandler("app.log"),  # 输出到文件
        logging.StreamHandler()  # 输出到控制台
    ]
)

参数详解

  • level:日志级别过滤阈值
  • format:消息模板(后文详解)
  • handlers:输出处理器(文件/邮件/HTTP等)

避坑指南

  1. basicConfig只能调用一次
  2. 尽早配置(建议在入口文件顶部)
  3. 生产环境慎用DEBUG级别

3. 等级管理艺术

等级误用现场

# 新手常见错误:把业务日志用ERROR级别
logging.error("用户张三登录成功")  # 狼来了式日志

五级警戒线

  1. DEBUG:挤牙膏调试信息(开发环境专用)
  2. INFO:业务关键流程记录(如"订单已支付")
  3. WARNING:预期内的异常(如"配置文件缺失,使用默认值")
  4. ERROR:需要干预的问题(如"数据库连接失败")
  5. CRITICAL:系统级故障(如"磁盘空间不足")

实战技巧

# 不同模块设置不同级别
logger = logging.getLogger("payment")
logger.setLevel(logging.INFO)  # 支付模块日志级别

# 动态调整级别
if config.DEBUG:
    logger.setLevel(logging.DEBUG)

4. 格式化才是灵魂

默认格式的尴尬

WARNING:root:连接超时

(看不出时间、模块、上下文)

高阶格式化

format = "%(asctime)s [%(levelname).1s] %(filename)s:%(lineno)d - %(message)s"
# 输出示例:
# 2023-08-25 14:20:35 [E] main.py:89 - 数据库连接失败

魔法变量大全

  • %(name)s:日志器名称
  • %(thread)d:线程ID
  • %(funcName)s:函数名
  • %(process)d:进程ID
  • %(pathname)s:完整文件路径

结构化日志进阶

# 适合ELK等日志系统
logging.info("订单创建", extra={
    "order_id": 123,
    "amount": 99.9,
    "user_id": "U1001"
})

5. 异常处理正确姿势

无效日志现场

try:
    db.insert(data)
except Exception as e:
    logging.error(f"插入失败:{e}")  # 丢失堆栈信息!

三种正确姿势

  1. 自动捕获异常栈
logging.error("插入失败", exc_info=True)
  1. 使用exception方法
logging.exception("插入失败") 
  1. 完整异常对象
try:
    # ...
except ValueError as e:
    logging.error(f"参数错误:{e}", stack_info=True)

错误码映射技巧

ERROR_CODE_MAP = {
    1045: "数据库认证失败",
    2003: "数据库连接超时"
}

try:
    db.connect()
except DBError as e:
    code = e.args[0]
    logging.error(ERROR_CODE_MAP.get(code, "未知数据库错误"))

6. 性能优化实战

文件日志的坑

# 直接使用FileHandler可能阻塞主线程
handler = logging.FileHandler("app.log")  # 默认同步写入

三大优化策略

  1. 使用RotatingFileHandler防爆盘
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler(
    "app.log", 
    maxBytes=10*1024*1024,  # 10MB
    backupCount=5
)
  1. 异步日志处理
from concurrent_log_handler import ConcurrentRotatingFileHandler
  1. 生产环境禁用DEBUG
if not DEBUG:
    logging.disable(logging.DEBUG)

内存监控技巧

# 在日志中记录内存使用
import psutil
logging.info(
    "内存使用统计",
    extra={"memory": psutil.virtual_memory().percent}
)

写在最后

当你开始认真对待日志,代码就有了自我诊断的能力。记住:好的日志不是写出来的,而是设计出来的。那些你深夜埋下的logging.info,终将成为照亮bug的明灯。编程路上,愿你的每个error都有迹可循,每次排查都直击要害。保持这份细致,你离高手就不远了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

精通代码大仙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值