首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AbstractEventLoop.slow_callback_duration的异步python日志记录细节

AbstractEventLoop.slow_callback_duration的异步python日志记录细节
EN

Stack Overflow用户
提问于 2020-01-27 15:00:34
回答 2查看 487关注 0票数 4

在python 3.6代码中,我将使用以下警告:

代码语言:javascript
运行
复制
import os
os.environ['PYTHONASYNCIODEBUG'] = '1'
代码语言:javascript
运行
复制
Executing <Handle <TaskWakeupMethWrapper object at 0x7fa8653dca08>(<Future finis...events.py:295>) created at /opt/rh/rh-python36/root/usr/lib64/python3.6/asyncio/tasks.py:390> took 5.012 seconds
Executing <Handle <TaskWakeupMethWrapper object at 0x7fa8653dcc48>(<Future finis...events.py:295>) created at /opt/rh/rh-python36/root/usr/lib64/python3.6/asyncio/tasks.py:390> took 9.941 seconds
Executing <Handle <TaskWakeupMethWrapper object at 0x7fa8653dca08>(<Future finis...events.py:295>) created at /opt/rh/rh-python36/root/usr/lib64/python3.6/asyncio/tasks.py:390> took 5.038 seconds

所以这是有用的,因为我知道事情进展缓慢,但我很难弄清楚是否有办法获得更好的堆栈跟踪,这样我才能真正地跟踪正在发生的事情。

有什么方法可以从中获取更多的堆栈跟踪吗?我假设它会触发AbstractEventLoop.slow_callback_duration,如下所述:https://docs.python.org/3.6/library/asyncio-dev.html

谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2020-07-13 18:52:50

你不介意玩肮脏的把戏吧?有一些提示:

  1. 用您自己的句柄替换asyncio.base_events._format_handle,用一个参数替换一个函数,我们称之为handle
  2. 看看handle._source_traceback,它可能会给您提供您的任务来源于哪里的信息。
  3. 看看handle._callback。在您的例子中,它是TaskWakeupMethWrapper,但是还有其他的选择。
  4. TaskWakeupMethWrapper没有向公众公开任何东西,但是谁能阻止真正的黑客?

有一个用ctypes解压缩它的代码

代码语言:javascript
运行
复制
PyObject_HEAD = [
    ('ob_refcnt', ctypes.c_size_t),
    ('ob_type', ctypes.c_void_p),
]

class TaskWakeupMethWrapper_Structure(ctypes.Structure):
    _fields_ = PyObject_HEAD + [
        ('ww_task', ctypes.py_object),
    ]


class PyAsyncGenASend_Structure(ctypes.Structure):
    _fields_ = PyObject_HEAD + [
        ('ags_gen', ctypes.py_object),
        ('ags_sendval', ctypes.py_object),
        ('ags_state', ctypes.c_int),
    ]


def unwrap_task_wakeup_method(wrapper: 'TaskWakeupMethWrapper'):
    wrapper_p = ctypes.cast(
        ctypes.c_void_p(id(wrapper)),
        ctypes.POINTER(TaskWakeupMethWrapper_Structure),
    )
    return wrapper_p.contents.ww_task
  1. 打印未包装协同线的状态(例如,使用inspect.getcoroutinestate())。请注意,状态是在缓慢代码之后,所以请准备只看到CORO_CLOSED
票数 2
EN

Stack Overflow用户

发布于 2020-07-11 00:31:36

代码语言:javascript
运行
复制
async def monitor_tasks():
    while True:
        tasks = [t for t in asyncio.all_tasks() if t is not asyncio.current_task()]
        [t.print_stack(limit=5) for t in tasks]
        await asyncio.sleep(2)

loop = asyncio.get_event_loop()  # Start main event loop.
loop.create_task(monitor_tasks()) # To monitor stack trace

我更喜欢这样做。您可以使用python的日志模块打印堆栈跟踪。

摘自这个伟大的教程

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59933653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档