Как отследить время, необходимое для каждой функции в маршруте в Flask? - PullRequest
0 голосов
/ 06 апреля 2020

Сейчас я пытаюсь собрать статистику по каждому запросу в flask, я могу зафиксировать время, затраченное на выполнение запроса. Есть ли способ захвата времени, затраченного на каждую функцию внутри маршрута.

MY Code capturing the time taken by a route
@app.teardown_request
def teardown_func(response):
    print("tearing down reqest")
    print("Request",request)
    required_data = {
        "path": request.full_path,
        "url": request.url,
        "json_data": request.get_json(),
        "start": request.start_time,
        "stop": dt.utcnow(),
        "total_elapsed_time": (dt.utcnow() - request.start_time).total_seconds()
    }
    print("request data",required_data)
    return response

def call_func():
    sleep(5)
    print("FunctionCalled")

def another_func():
    sleep(5)
    print("FunctionCalled2")


@app.route('/',methods=['GET','POST'])
def hello2():
    time.sleep(10)
    call_func()
    another_func()
    return 'Hello World'

Как рассчитать, что call_fun c () и another_fun c () заняли 5 секунд поиска в исполнении этого маршрута?

1 Ответ

1 голос
/ 06 апреля 2020

Один из способов - использовать декоратор для функций, которые вы sh используете во времени. Затем декоратор добавит имя функции с истекшим временем выполнения функции в словарь, хранящийся в глобальном атрибуте приложения g timings. Это может быть зарегистрировано в хуке teardown_request или after_request или, как это делается здесь, с помощью функции / view:

from flask import Flask, Response, g
import time

app = Flask(__name__)

@app.before_request
def before_request_func():
    g.timings = {}

from functools import wraps
def time_this(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start = time.time()
        r = func(*args, **kwargs)
        end = time.time()
        g.timings[func.__name__] = end - start
        return r
    return wrapper


@time_this
def call_func():
    time.sleep(1)

@time_this
def another_func():
    time.sleep(2)

@app.route('/',methods=['GET','POST'])
def hello2():
    call_func()
    another_func()
    return Response('Hello World: ' + str(g.timings), mimetype='text/plain')

Update

Я просто хочу отметить, что когда вы определяете время функции представления, время не будет создано и добавлено в словарь timings до тех пор, пока функция не вернется, поэтому в этом случае словарь timings лучше всего обрабатывать в after_request функция подключения, например:

@app.after_request
def after_request_func(response):
    # just append timings to the output response:
    response.data += ('\n' + str(g.timings)).encode('ascii')
    return response

@app.route('/',methods=['GET','POST'])
@time_this
def hello2():
    call_func()
    another_func()
    return Response('Hello World', mimetype='text/plain')

Выходы:

Hello World
{'call_func': 1.0014231204986572, 'another_func': 2.0004665851593018, 'hello2': 3.001889705657959}
...