Skip to main content

Lightewight monitor library for asyncio.EventLoop

Project description

loopmon - Lightweight Event Loop monitoring

Codecov Dependabot Status PyPI PyPI - Wheel Python Version GitHub last commit (branch) GitHub Workflow Status (branch) Code Style

loopmon is a lightweight library that can detect throttling of event loops. For example, you can detect long-running coroutine or whether the blocking function is invoked inside the event loop.

Usage

import asyncio
import time
from datetime import datetime
import loopmon

async def print_collected_data(lag: float, tasks: int, data_at: datetime) -> None:
    print(f'event loop lag: {lag:.3f}, running tasks: {tasks}, at {data_at}')

async def main() -> None:
    loopmon.create(interval=0.5, callbacks=[print_collected_data])
    # Simple I/O bound coroutine does not occur event loop lag
    await asyncio.sleep(0.2)
    # Blocking function call
    time.sleep(1)

if __name__ == '__main__':
    asyncio.run(main())

will prints:

event loop lag: 0.000, running tasks: 2, at 2022-02-24 13:29:05.367330+00:00
event loop lag: 1.001, running tasks: 1, at 2022-02-24 13:29:06.468622+00:00

You can check other examples.

I recommend you to add loopmon.create(...) on beginning of async function if you are not familiar with handling loop itself. But you can also control creation, installation or staring of monitor via EventLoopMonitor.start() or EventLoopMonitor.install_to_loop().

Features

  • Detects event loop lag
    • Detects event loop running on other thread. example
  • Collect how many tasks are running in the event loop
  • Customize monitoring start and end points
  • Customize monitoring interval
  • Customize collected metrics through callbacks
  • 100% type annotated
  • Zero dependency (except typing-extentions)

How it works

Event loop is single threaded and based on Cooperative Scheduling. So if there is a task that does not yield to another tasks, any tasks on the loop can not be executed. And starvation also happens when there are too many tasks that a event loop can not handle.

Currently loopmon.SleepEventLoopMonitor is one and only monitor implementation. It periodically sleeps with remembering time just before sleep, and compares the time after awake. The starvation happen if the difference bigger than its sleeping interval.

pseudo code of SleepEventLoopMonitor

while True:
    before = loop.time()
    await asyncio.sleep(interval)
    lag = loop.time() - before - interval
    tasks = len(asyncio.all_tasks(loop))
    data_at = datetime.now(timezone.utc)
    for c in callbacks:
        loop.create_task(c(lag, tasks, data_at))

Integration examples

Prometheus

from datetime import datetime
from functools import partial
import loopmon
from prometheus_client import Gauge

async def collect_lag(gauge: Gauge, lag: float, _: int, __: datetime) -> None:
    gauge.set(lag)

async def main(gauge: Gauge) -> None:
    loopmon.create(interval=0.5, callbacks=[partial(collect_lag, gauge)])
    ...

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

loopmon-1.0.1.tar.gz (6.7 kB view details)

Uploaded Source

Built Distribution

loopmon-1.0.1-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file loopmon-1.0.1.tar.gz.

File metadata

  • Download URL: loopmon-1.0.1.tar.gz
  • Upload date:
  • Size: 6.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.3

File hashes

Hashes for loopmon-1.0.1.tar.gz
Algorithm Hash digest
SHA256 c259dd82b14c05ac2007eb3a4cb4e4d5f79cac931ce89556e9131ae5dc1abb4c
MD5 b58d451591829085deac1de73498f878
BLAKE2b-256 2f359a8dc9f6ae01bb7d5f543b4da31626845687a4587f817f0507423a8e5756

See more details on using hashes here.

File details

Details for the file loopmon-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: loopmon-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.11.3

File hashes

Hashes for loopmon-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 96ef43eaa3763804c7bc2f4aaf849a54146192c25da2680cd8ebc13856a2d37f
MD5 399a6f002437b6d0c28057f7d43ab2b2
BLAKE2b-256 a51001f09de2eff16dac02a2cba91671fa5612944fa38a81a3da4470510696eb

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page