讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在Python异步代码中集成Logging日志_通过QueueHandler实现非阻塞日志

夜萱君_4369

夜萱君_4369

发布时间:2026-06-01 15:46:00

|

1044人浏览过

|

来源于php中文网

原创

直接在async def中用logging.info会卡住,因为标准Handler(如FileHandler)是同步阻塞IO,会阻塞event loop;应改用QueueHandler+QueueListener方案,将日志写入内存队列,由独立线程落盘。

如何在python异步代码中集成logging日志_通过queuehandler实现非阻塞日志

为什么直接在async def里用logging.info会卡住

因为标准logging的Handler(比如FileHandler或StreamHandler)默认是同步阻塞的——写日志时会直接调用write()或flush(),而这些IO操作在异步上下文中会阻塞整个event loop。哪怕只是logging.info("hello"),如果底层Handler碰上磁盘慢、终端缓冲满、或者被重定向到某个慢管道,就可能让协程停住几百毫秒甚至更久。

常见现象:你发现asyncio.sleep(0.1)实际耗时 200ms+,或并发请求的响应时间突然抖动,排查后发现是某处日志调用拖慢了。

  • 别在async def里直接调用logger.info(),除非你确认Handler完全无IO(比如NullHandler)
  • 不要试图用loop.run_in_executor包装单条日志——开销大、易堆积、难控制
  • QueueHandler + QueueListener是官方推荐的解耦方案,它把日志“发出去”变成内存队列写入,真正落盘交给独立线程

怎么用QueueHandler把日志送出协程线程

QueueHandler本身不干活,只负责把LogRecord对象塞进一个queue.Queue;真正的IO由另一个线程里的QueueListener完成。关键点在于:队列写入是纯内存操作,极快且不会触发任何await点。

实操步骤:

立即学习“Python免费学习笔记(深入)”;

  • 创建一个queue.Queue实例(注意不是asyncio.Queue,后者不能跨线程)
  • 新建QueueHandler并绑定该队列,把它加到你的logger的handlers中
  • 用QueueListener监听这个队列,并传入真正的IO Handler(如FileHandler)
  • 调用listener.start()启动监听线程——必须在event loop启动前或主线程中调用

示例片段:

macOS UI 自动化技能包 —— 用 Python 控制你的 Mac
macOS UI 自动化技能包 —— 用 Python 控制你的 Mac

让 macOS 自动化像说话一样简单 —— 用代码控制你的 Mac,无需学习 AppleScript 系统要求 macOS 14+ (Sonoma) Python 3.9+ 需要开启:辅助功能 + 屏幕录制权限

下载
import logging
import queue
from logging.handlers import QueueHandler, QueueListener
<p>log_queue = queue.Queue()
handler = logging.FileHandler("app.log")
queue_handler = QueueHandler(log_queue)
logger = logging.getLogger("myapp")
logger.addHandler(queue_handler)
logger.setLevel(logging.INFO)</p><p>listener = QueueListener(log_queue, handler)
listener.start()  # 这行必须在 asyncio.run() 之前执行</p>

async def里怎么安全打日志

只要QueueHandler已生效,你在任意async def里调用logger.info()都是安全的——它内部只是log_queue.put_nowait(record),没有await、没有IO、不抛异常(除非队列满且没设block=False)。

但要注意几个边界:

  • 如果队列满了,默认会阻塞主线程(不是协程线程!),所以建议初始化时设queue.Queue(maxsize=1000),并搭配listener.enqueue_sentinel()做优雅退出
  • 日志中的exc_info、stack_info仍可正常捕获,因为LogRecord序列化发生在调用方线程(即协程所在线程),不是在监听线程
  • 避免在日志格式化字符串里调用耗时函数(比如f"result={slow_func()}"),这会在协程线程里执行,和Handler无关但照样拖慢协程

为什么不用asyncio.Queue + create_task监听

有人想用asyncio.Queue配合create_task在event loop里消费日志,听起来很“async native”,但实际问题很多:

  • asyncio.Queue不能被非async线程(比如QueueListener启的线程)安全put,会引发RuntimeError: There is no current event loop in thread
  • 如果你硬要在协程里用await queue.get(),就得保证这个consumer task永不退出、且能处理背压——而标准logging模块不提供这种生命周期管理接口
  • QueueListener内置重试、sentinel信号、异常隔离,比手写consumer健壮得多;它的线程与event loop完全解耦,不会因日志IO拖慢任何协程调度

简单说:想省事又可靠,就老实用queue.Queue + QueueListener。非要“全async”方案,得自己实现一套日志协议,代价远超收益。

最容易被忽略的是listener.start()的调用时机——它必须在任何协程启动前完成,否则队列可能被协程先写入,而监听线程还没起来,导致日志丢失或卡死。这点连很多Stack Overflow答案都没强调清楚。

热门AI工具

更多
DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

1831

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

4964

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1789

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

29757

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3547

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3567

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

1223

2023.08.11

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

616

2023.08.10

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Uvicorn官方安装与入门手册
Uvicorn官方安装与入门手册

共0课时 | 0人学习

Python uv官方项目管理指南
Python uv官方项目管理指南

共0课时 | 0人学习

Python uv官方安装与入门文档
Python uv官方安装与入门文档

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn