如何跟踪 Flask 中路线中每个功能所花费的时间?

Ak4*_*k47 1 python logging flask python-2.7

现在我正在尝试捕获 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'
Run Code Online (Sandbox Code Playgroud)

我如何计算 call_func() 和 another_func() 在执行该路由时花费了 5 秒的时间?

Boo*_*boo 5

一种方法是在您希望计时的函数周围使用装饰器。然后,装饰器将函数的名称和函数的运行时间添加到保存在应用程序全局g属性中的字典中timings。这可以在一个teardown_requestafter_request钩子中登录,或者像这里所做的那样,通过/视图函数:

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')
Run Code Online (Sandbox Code Playgroud)

更新

我只想说明一点,当您为视图函数计时时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')
Run Code Online (Sandbox Code Playgroud)

输出:

Hello World
{'call_func': 1.0014231204986572, 'another_func': 2.0004665851593018, 'hello2': 3.001889705657959}
Run Code Online (Sandbox Code Playgroud)