尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

为什么我暂时抛弃了 logging

为什么我暂时抛弃了 logging
📅 发布时间:2026/6/25 13:47:34

先说我踩过最大的坑:logging 的默认输出是同步阻塞的,FastAPI 的异步特性一来,日志不但会打乱顺序,还可能悄无声息地丢失。
而且你要拿到一个像样的日志,得先写几十行配置,每次开新项目都要先把以前的代码复制过来,烦得要死。

而loguru一上来就告诉我:别折腾了,直接打就行。
它只有一个全局的logger对象,装上就能用,彩色控制台输出,自带日期、级别和超好看的格式。一句话:清爽,真的清爽。

这里为什么我说是“暂时”呢?是因为Loguru的魅力在于它直击痛点的简洁。用 logger.add() 一行代码就能搞定输出目标、格式、轮转策略等所有事情。
不过它也存在短板。如果直接代替标准库,可能出现业务代码用Loguru日志,uvicorn服务器依然打官方日志的混乱局面,或是要对标准库日志做好“拦截”,避免重复刷屏。
能用和用好,是完全不同的两个维度。在大型项目里,选择标准logging,本质上不是因为它更好用,而是因为它能让整个复杂的系统更好地在一起工作,更具确定性和可控性。

所以,对于新项目,建议从 Loguru 起步,享受它的便利。当项目成长为大型/微服务架构时,再将日志系统核心回迁到标准库logging + dictConfig上。
或组合使用,各司其职:Loguru 作用于你的业务代码 + 标准库logging作为“基础设施”,兼顾开发体验和生产系统的兼容性。

📦 安装与第一个日志

好,咱们先来安装。就一行:

uv add loguru

然后在 FastAPI 里直接开怼:

from loguru import logger from fastapi import FastAPI app = FastAPI() @app.get("/") async def hello(): logger.info("有人访问了首页,美滋滋") return {"msg": "Hello"}

跑起来后,你的终端会立马出现一条带有时间戳、级别和高亮颜色的日志,再也不用对着黑白海量的输出发呆了。

这里有个问题,在正式环境一定不要只往控制台打印,接下来重点来了:怎么把日志稳稳地写到文件里。

🔧 常用配置,一次搞懂

你可能会问:“loguru 写文件是不是又要配一堆东西?”完全不用,一行搞定:

logger.add("app.log", rotation="10 MB", retention="7 days", level="INFO")

你看,rotation 按文件大小自动轮转,retention 自动清理老日志,而且压缩、自定义格式都能在同一个方法里搞定。
这比 logging 的RotatingFileHandler + TimedRotatingFileHandler那种套娃组合直观太多了。

但说个容易翻车的点:在 FastAPI 这种异步框架里,千万别漏了 enqueue=True 参数。
官方示例可能没写,但根据我线上血的教训,不加这个参数,多并发下日志写入会阻塞事件循环,轻则响应变慢,重则日志串行甚至丢数据。正确姿势:

logger.add("app.log", rotation="10 MB", retention="7 days", level="INFO", enqueue=True)

loguru 会把日志消息扔进一个线程安全的队列,专门有后台线程负责写入,你的主流程该干嘛干嘛,完全不用分心。
这就像点一杯奶茶,小程序下单后不用在店里干等,做好了自然叫你。😊

🧩 和 Uvicorn 的日志整合

是不是以为这样就完了?还有个折磨过我的地方:FastAPI 底层用的 Uvicorn 自己也哗哗地打印日志,两边各玩各的,管理起来特难受。

我的做法是,在应用启动的地方,把 Uvicorn 的日志也“绑架”到 loguru 里来:

import logging from loguru import logger class InterceptHandler(logging.Handler): def emit(self, record): logger_opt = logger.opt(depth=6, exception=record.exc_info) logger_opt.log(record.levelname, record.getMessage()) # 在 FastAPI 的 lifespan 或 startup 事件里执行 logging.basicConfig(handlers=[InterceptHandler()], level=0)

这样,所有日志都汇聚到一个口子输出,规则统一,查找问题就像过红绿灯,一次看清。🚦

但在实际开发时,还有个问题就是如果启用了--reload模式,或者使用命令fastapi dev main.py启动的项目,那有些日志拦截还是会漏掉,
想办法把自定义的InterceptHandler拦截的更彻底些:

import logging from loguru import logger class InterceptHandler(logging.Handler): def emit(self, record): # 拿到对应的 loguru 级别 try: level = logger.level(record.levelname).name except ValueError: level = record.levelno # 找到调用栈里真正发出日志的地方 frame, depth = logging.currentframe(), 2 while frame.f_code.co_filename == logging.__file__: frame = frame.f_back depth += 1 logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage()) # 这里是关键:启动的时候,把 root logger 的所有旧 handler 都干掉, # 只留我们自己的 InterceptHandler def setup_logging(): logging.root.handlers = [InterceptHandler()] logging.root.setLevel(logging.INFO) # 把 uvicorn 那几个 logger 也顺手接管 for name in ("uvicorn", "uvicorn.access", "uvicorn.error"): logging.getLogger(name).handlers = [] logging.getLogger(name).propagate = True # 在 FastAPI 应用实例化之前就调用 setup_logging()

⚠️ 这些不足和注意点,请刻在脑子里

loguru 虽香,但也别盲目吹。我总结了几个生产环境必须注意的:

🔸 全局只有一个 logger,多进程部署(如Gunicorn多个worker)时务必注意隔离,避免写入冲突,推荐每个进程单独 add 文件,文件名可以用 PID 区分。

🔸 异常回溯虽然默认就漂亮,但要捕获完整 traceback,记得用logger.exception()或者在 add 时加上backtrace=True。

🔸 敏感信息(密码、token)一定要在日志里脱敏,loguru 支持 filter 功能,可以优雅地过滤字段。

🔸 日志文件路径别写成相对路径,否则在守护进程启动时可能写到莫名其妙的地方,建议使用绝对路径或基于项目根目录拼接。

最后啰嗦一句:
有优点,也有不足,这也是为什么前面我说“暂时”替代标准库logging的原因,享受它带来的便利,避开它会引起的坑!
日志是项目上线后你的“眼睛”,花半小时好好配一下,未来无数个深夜调试都会感谢现在的自己。

相关新闻

  • 如何用好accio work 做好客户开发,背调
  • 如何免费实现高效语音转字幕:STS-Bcut完整使用指南
  • 生成式AI落地实战:从流程锚定到组织级AI能力建设

最新新闻

  • Python的多进程居然把我坑惨了!别踩这个坑
  • 别再瞎找了!盘点2026年万众偏爱的的AI论文平台
  • Detecting hallucinations in large language models using semantic entropy
  • 如何在家中搭建游戏串流服务器?Sunshine让你随时随地畅玩PC游戏
  • Log4j2漏洞深度解析:从JNDI注入原理到企业级应急响应实战
  • 思源宋体终极指南:如何在5分钟内免费获得专业级中文字体

日新闻

  • 利用微PE工具箱进行系统安装教程
  • 渗透测试十大核心工具实战指南:从信息搜集到报告生成全流程解析
  • 暗黑破坏神2存档编辑器:网页版角色修改工具完全指南

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号