社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python 日志抓狂?Loguru + 实战技巧让你告别 "黑盒" 调试

数据派THU • 3 月前 • 367 次点击  
图片
本文约1800字,建议阅读5分钟

Python 日志配置不再难,Loguru 极简用法 + 标准库封装,高效定位问题。


你是否曾为Python日志配置抓狂?那么多部件:处理器、格式器、级别、配置……感觉就像在组装一件缺少说明书的IKEA家具,最后还装反了!


别担心,今天我要分享的这个简单技巧,将彻底改变你对Python日志记录的印象。


为什么Python日志记录让人如此头疼?


1. 样板代码太多


每个教程开头都是这样一大段:


import loggingfrom logging.handlers import RotatingFileHandlerlogger = logging.getLogger('MyApp')handler = logging.StreamHandler()file_handler = RotatingFileHandler('app.log', maxBytes=5*1024*1024, backupCount=10)formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')handler.setFormatter(formatter)file_handler.setFormatter(formatter)logger.addHandler(handler)logger.addHandler(file_handler)logger.setLevel(logging.DEBUG)


等打完这些,咖啡早就凉了!


2. 错误信息像天书


"日志怎么没显示?哦,是因为忘了设置处理器,处理器又忘了设置格式器,格式器又忘了设置级别……" 日志像前任一样已读不回!


3. 日志级别让人困惑


DEBUG、INFO、WARNING、ERROR、CRITICAL——听起来简单,但问5个开发者什么是INFO、什么是DEBUG,你会得到10个答案!


拯救你的神器:Loguru


认识一下Loguru,这个库会让你的日志记录变得异常简单。


极简配置


from loguru import loggerlogger.add(    "logs/app.log"    level="DEBUG"    format="{time:YYYY-MM-DD HH:mm:ss} - {level} - {file} - {line} - {message}",    rotation="10 MB")logger.info('可以写日志了')


不需要创建文件夹,不需要设置复杂的处理器,一行配置就搞定一切!


错误追踪变得简单


Loguru能精准定位问题,每个变量的值都会给你标出来:


from loguru import logger@logger.catchdef test():    'a' + 1test()


运行后会显示详细的错误信息,包括每个变量的值,调试效率大大提升!


为什么Loguru是救星?


1. 开箱即用


无需复杂配置,导入即可开始记录日志。同一个项目中其他文件直接使用相同的logger:


from loguru import loggerlogger.info('直接使用,无需额外配置')


2. 强大的功能


Loguru内置了许多实用功能:


  • 自动日志轮转:防止日志文件过大

  • 异常捕获:使用装饰器自动记录异常

  • 色彩支持:控制台输出自带色彩,更容易阅读

  • 异步记录:不影响主程序性能


3. 结构化日志


# 记录结构化数据logger.info("用户操作", user_id=123, action="login", success=True)


这样的日志更容易被日志系统分析和查询。


传统logging还能抢救一下吗?


当然!如果你因项目限制必须使用标准logging库,这里有个简化方案:


创建可重用的日志工具函数


import loggingimport osdef setup_logger(name=None, level=logging.INFO):    """设置并返回一个配置好的logger实例"""        # 创建logger    logger = logging.getLogger(name or __name__)    logger.setLevel(level)        # 如果已经有处理器,避免重复添加    ifnot logger.handlers:        # 创建控制台处理器        console_handler = logging.StreamHandler()        console_handler.setLevel(level)                # 创建文件处理器(可选)        os.makedirs('logs', exist_ok=True)        file_handler = logging.handlers.RotatingFileHandler(            'logs/app.log', maxBytes=5*1024*1024, backupCount=3, encoding='utf-8'        )        file_handler.setLevel(level)                # 设置格式        formatter = logging.Formatter(            '%(asctime)s - [%(levelname)s] - %(name)s - %(filename)s:%(lineno)d - %(message)s',            datefmt='%Y-%m-%d %H:%M:%S'        )                console_handler.setFormatter(formatter)        file_handler.setFormatter(formatter)                # 添加处理器        logger.addHandler(console_handler)        logger.addHandler(file_handler)        return logger# 使用示例logger = setup_logger("my_app")logger.info("日志变得简单了!")


这个函数可以在项目的任何模块中重用,确保一致的日志配置。


实用场景示例


Web开发中的日志记录


from fastapi import FastAPIfrom loguru import loggerapp = FastAPI()@app.middleware("http")asyncdef log_requests(request, call_next):    logger.info(f"请求: {request.method} {request.url}")    response = await call_next(request)    logger.info(f"响应: {response.status_code}")    return response@app.get("/")asyncdef read_root():    logger.info("访问根路径")    return {"Hello""World"}


数据处理中的进度跟踪


from loguru import loggerdef process_data(data):    total = len(data)    for i, item in enumerate(data):        # 处理数据...        if i % 100 == 0:            logger.info(f"进度: {i}/{total} ({i/total*100:.1f}%)")        logger.debug(f"处理项目: {item}")        logger.success(f"数据处理完成,共处理 {total} 条记录")


脚本调试


from loguru import logger@logger.catchdef main():    logger.info("脚本开始执行")        # 你的代码在这里    # 任何异常都会被自动记录        logger.info("脚本执行完成")if __name__ == "__main__":    main()


日志最佳实践


1. 选择合适的日志级别

  • DEBUG:详细的调试信息,适用于开发环境

  • INFO:确认程序按预期运行

  • WARNING:表明已发生或即将发生意外(如磁盘空间不足)

  • ERROR:由于严重问题,程序的某些功能已经不能正常执行

  • CRITICAL:重错误,表明程序已不能继续执行


2. 日志中包含上下文信息


# 不好的做法logger.error("操作失败")# 好的做法logger.error("用户操作失败", user_id=user_id, action=action, reason=error_msg)


3. 生产环境考虑性能


# 避免在循环中使用字符串格式化if logger.isEnabledFor(logging.DEBUG):    expensive_data = generate_expensive_debug_data()    logger.debug("数据: %s", expensive_data)


写在最后


Python日志记录从让人头疼到得心应手,只需要一个正确的工具和方法。Loguru让日志记录变得简单直观,而合理的封装也能让标准logging库变得易用。


记住,良好的日志记录就像飞机的黑匣子,当程序出现问题时,它能帮你快速定位原因,节省大量调试时间。


现在,是时候告别杂乱的print语句,拥抱高效的日志记录了!


编辑:于腾凯




关于我们

数据派THU作为数据科学类公众号,背靠清华大学大数据研究中心,分享前沿数据科学与大数据技术创新研究动态、持续传播数据科学知识,努力建设数据人才聚集平台、打造中国大数据最强集团军。



图片


新浪微博:@数据派THU

微信视频号:数据派THU

今日头条:数据派THU

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/189907