Command-line introspection toolsΒΆ
Source code: Lib/asyncio/tools.py
The asyncio module can be executed as a script to inspect asyncio
tasks in another Python process:
$ python -m asyncio ps [--retries N] PID
$ python -m asyncio pstree [--retries N] PID
PID is the process ID of the Python process to inspect. The commands use
Pythonβs remote debugging support to read the target
process state, but do not execute code in the target process. They are only
available on supported platforms and may require permission to inspect another
process. See Permission requirements for details.
See also
- Call graph introspection
Programmatic APIs for inspecting the async call graph of a task or future in the current process.
The command examples below use this program, which creates a task hierarchy suitable for inspection and prints its process ID:
import asyncio
import os
async def play(track):
await asyncio.sleep(3600)
print(f"π΅ Finished: {track}")
async def album(name, tracks):
async with asyncio.TaskGroup() as tg:
for track in tracks:
tg.create_task(play(track), name=track)
async def main():
print(f"PID: {os.getpid()}", flush=True)
async with asyncio.TaskGroup() as tg:
tg.create_task(
album("Sundowning", ["TNDNBTG", "Levitate"]),
name="Sundowning",
)
tg.create_task(
album("TMBTE", ["DYWTYLM", "Aqua Regia"]),
name="TMBTE",
)
asyncio.run(main())
Run the program in one terminal and leave it running:
$ python example.py
PID: 12345
Then pass the printed process ID to the commands from another terminal. Thread IDs, task IDs, file paths, and line numbers vary between runs and source layouts.
Added in version 3.14.
Command-line optionsΒΆ
- ps PIDΒΆ
Display a table of pending tasks in the process PID. The table includes the thread ID, task ID, task name, coroutine stack, awaiter chain, awaiter name, and awaiter ID:
$ python -m asyncio ps 12345 tid task id task name coroutine stack awaiter chain awaiter name awaiter id ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ 18445801 0x10a456060 Task-1 TaskGroup._aexit -> TaskGroup.__aexit__ -> main 0x0 18445801 0x10a439f60 Sundowning TaskGroup._aexit -> TaskGroup.__aexit__ -> album TaskGroup._aexit -> TaskGroup.__aexit__ -> main Task-1 0x10a456060 18445801 0x10a439d70 TMBTE TaskGroup._aexit -> TaskGroup.__aexit__ -> album TaskGroup._aexit -> TaskGroup.__aexit__ -> main Task-1 0x10a456060 18445801 0x10a2a3a80 TNDNBTG sleep -> play TaskGroup._aexit -> TaskGroup.__aexit__ -> album Sundowning 0x10a439f60 18445801 0x10a2a38a0 Levitate sleep -> play TaskGroup._aexit -> TaskGroup.__aexit__ -> album Sundowning 0x10a439f60 18445801 0x10a2d7150 DYWTYLM sleep -> play TaskGroup._aexit -> TaskGroup.__aexit__ -> album TMBTE 0x10a439d70 18445801 0x10a6bdaa0 Aqua Regia sleep -> play TaskGroup._aexit -> TaskGroup.__aexit__ -> album TMBTE 0x10a439d70
- pstree PIDΒΆ
Display the same task and coroutine relationships as a tree:
$ python -m asyncio pstree 12345 βββ (T) Task-1 βββ main example.py:12 βββ TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:75 βββ TaskGroup._aexit Lib/asyncio/taskgroups.py:124 βββ (T) Sundowning β βββ album example.py:7 β βββ TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:75 β βββ TaskGroup._aexit Lib/asyncio/taskgroups.py:124 β βββ (T) TNDNBTG β β βββ play example.py:4 β β βββ sleep Lib/asyncio/tasks.py:702 β βββ (T) Levitate β βββ play example.py:4 β βββ sleep Lib/asyncio/tasks.py:702 βββ (T) TMBTE βββ album example.py:7 βββ TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:75 βββ TaskGroup._aexit Lib/asyncio/taskgroups.py:124 βββ (T) DYWTYLM β βββ play example.py:4 β βββ sleep Lib/asyncio/tasks.py:702 βββ (T) Aqua Regia βββ play example.py:4 βββ sleep Lib/asyncio/tasks.py:702
- --retries NΒΆ
Retry failed attempts to inspect the target process up to N times. See Sampling efficiency for details about failed process memory reads.
Added in version 3.15.