Декоратор для логирования длительных асинхронных функций

Декоратор должен await-ить функцию и сравнивать elapsed с limit. Внутри тестовой корутины замените time.sleep на await asyncio.sleep.

Короткий ответ

Что ответить на собеседовании

Декоратор должен await-ить функцию и сравнивать elapsed с limit. Внутри тестовой корутины замените time.sleep на await asyncio.sleep.

Подробный разбор

Ответ с пояснениями

Условие

Необходимо реализовать декоратор slowlog, который будет измерять время работы асинхронной функции. Если время выполнения превышает заданный порог (в секундах), информация о таком вызове должна выводиться в консоль через модуль logging.

import time, asyncio, logging
logging.basicConfig(level=logging.INFO)

def slowlog():
    # ...

@slowlog(limit=2)
async def test_func(wait_time):
    # ...
    time.sleep(wait_time)
    return wait_time

asyncio.run(test_func(1))  # не должно логироваться
asyncio.run(test_func(3))  # должно логироваться

В примере показано, как использовать декоратор: при вызове test_func(1) лог не появляется, а при test_func(3) — появляется, так как время выполнения превышает установленный лимит.

Ответ

Декоратор должен await-ить функцию и сравнивать elapsed с limit. Внутри тестовой корутины замените time.sleep на await asyncio.sleep.

from functools import wraps
from time import perf_counter
import logging
import asyncio

logger = logging.getLogger(__name__)

def slowlog(limit):
    if limit < 0:
        raise ValueError('Порог не может быть отрицательным')
    def decorate(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            started = perf_counter()
            try:
                return await func(*args, **kwargs)
            finally:
                elapsed = perf_counter() - started
                if elapsed > limit:
                    logger.info('%s выполнялась %.3f с', func.__name__, elapsed)
        return wrapper
    return decorate

@slowlog(limit=2)
async def test_func(wait_time):
    await asyncio.sleep(wait_time)
    return wait_time

time.sleep блокировал бы event loop. Здесь логируется и медленное завершение с ошибкой; аргументы и результаты в лог не передаются. Обработчик logging должен быть настроен на INFO.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее