所以这是一个重现问题的复制粘贴示例。
import logging
from flask import Flask
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
def app_builder(app_name, log_file):
app = Flask(app_name)
app.debug = True
handler = logging.FileHandler(log_file)
handler.setLevel(logging.DEBUG)
app.logger.addHandler(handler)
return app
def _simple(env, resp):
resp(b'200 OK', [(b'Content-Type', b'text/plain')])
return [b'root']
if __name__ == "__main__":
app = app_builder(app_name='app', log_file='app.log')
@app.route('/')
def index():
return '<a href="/app/error">click for error</a>'
@app.route('/error')
def error():
1/0
return 'error page'
app2 = app_builder(app_name='app2', log_file='app2.log')
@app2.route('/')
def index():
return 'you are getting responses from app2'
app.debug = True
app2.debug = True
application = DispatcherMiddleware(_simple, {
'/app': app,
'/app2': app2
})
run_simple(hostname='localhost',
port=5000,
application=application,
use_reloader=True,
use_debugger=True)
要显示错误,请导航至 http://localhost:5000/app/error
,我想知道为什么堆栈跟踪没有出现在 app.log
中文件。我假设 DispatcherMiddleware
或 run_simple
在记录异常之前以某种方式捕获异常。如果我只运行 app
使用 app.run()
的实例错误记录工作正常。
最佳答案
当 app.debug = True
时,不会调用正常的异常处理程序。看着
在 Flask 中的 app.py
代码中:
def log_exception(self, exc_info):
"""Logs an exception. This is called by :meth:`handle_exception`
if debugging is disabled and right before the handler is called.
^^^^^^^^^^^^^^^^^^^^^^^^
The default implementation logs the exception as error on the
:attr:`logger`.
确实,当设置 app.debug = True
时,异常传播被设置
显式为 True,这会阻止调用 log_exception
。这是文档的摘录(重点是我的):
PROPAGATE_EXCEPTIONS: explicitly enable or disable the propagation of exceptions. If not set or explicitly set to None this is implicitly true if either TESTING or DEBUG is true.
所以,我设法让 werkzeug 调试和日志记录工作愉快 连同一点点调整和以下代码:
import logging
from flask import Flask
from werkzeug.serving import run_simple
from werkzeug.wsgi import DispatcherMiddleware
## NEW CODE HERE
import functools
from flask._compat import reraise
def my_log_exception(exc_info, original_log_exception=None):
original_log_exception(exc_info)
exc_type, exc, tb = exc_info
# re-raise for werkzeug
reraise(exc_type, exc, tb)
##
def app_builder(app_name, log_file):
app = Flask(app_name)
app.debug = True
app.config.update(PROPAGATE_EXCEPTIONS=False)
handler = logging.FileHandler(log_file)
handler.setLevel(logging.DEBUG)
app.logger.addHandler(handler)
## NEW CODE
app.log_exception = functools.partial(my_log_exception, original_log_exception=app.log_exception)
##
return app
# rest of your code is unchanged
关于python - 为什么在使用 werkzeug 运行 Flask 应用程序时日志记录不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39646236/