賞金將在 3 天后到期。此問題的答案有資格獲得 150聲望賞金。 Basj正在尋找一個規范的答案。
在 Flask 路由中記錄未捕獲運算式的標準方法是什么logging?
這幾乎有效:
import logging, sys, flask
logging.basicConfig(filename='test.log', filemode='a', format='%(asctime)s %(levelname)s %(message)s')
sys.excepthook = lambda exctype, value, tb: logging.error("", exc_info=(exctype, value, tb))
logging.warning("hello")
app = flask.Flask('hello')
@app.route('/')
def index():
sjkfq # uncaught expresion
return "hello"
app.run()
但日志中有一些 ANSI 轉義字符:[31m[1m等(可能用于控制臺顏色)
test.log在生成的檔案中查看此處:
2022-10-21 16:23:06,817 WARNING hello
2022-10-21 16:23:07,096 INFO [31m[1mWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.[0m
* Running on http://127.0.0.1:5000
2022-10-21 16:23:07,097 INFO [33mPress CTRL C to quit[0m
2022-10-21 16:23:07,691 ERROR Exception on / [GET]
Traceback (most recent call last):
File "C:\Python38\lib\site-packages\flask\app.py", line 2525, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python38\lib\site-packages\flask\app.py", line 1822, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python38\lib\site-packages\flask\app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python38\lib\site-packages\flask\app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "D:\test.py", line 10, in index
sjkfq
NameError: name 'sjkfq' is not defined
2022-10-21 16:23:07,694 INFO 127.0.0.1 - - [21/Oct/2022 16:23:07] "[35m[1mGET / HTTP/1.1[0m" 500 -
請注意,如果您運行相同的代碼,這是完全可重現的。
是否有記錄的方法可以使用 Python 正確記錄 Flask 路由中未捕獲的例外logging?我在https://flask.palletsprojects.com/en/2.2.x/logging/中沒有完全找到這個。
(注意:這段代碼表明它不是正確的記錄方式。我們不應該截取記錄字串,做一些逆向工程來清除轉義字符,然后記錄到檔案。肯定有標準的記錄方式。)
uj5u.com熱心網友回復:
所以問題是那些 ANSII 字符[31m[1m指定終端中訊息的顏色。
據我了解,Flask 從 werkzeug 獲取日志并添加一些顏色。
正如您從這個問題中看到的那樣,沒有辦法通過設定中的任何簡單標志來禁用燒瓶日志記錄中的著色(不幸的是)
您可以做的是添加格式化程式,該格式化程式將在記錄之前獲取訊息并洗掉顏色樣式。
import logging, sys, flask
import click
class NoColorFormatter(logging.Formatter):
def format(self, record: logging.LogRecord) -> str:
return click.unstyle(super().format(record))
werkzeug_logger = logging.getLogger("werkzeug")
root_logger = logging.getLogger()
handler = logging.FileHandler("test.log")
handler.setFormatter(NoColorFormatter("%(asctime)s %(levelname)s %(message)s"))
werkzeug_logger.addHandler(handler)
root_logger.addHandler(handler)
sys.excepthook = lambda exctype, value, tb: logging.error(
"", exc_info=(exctype, value, tb)
)
logging.warning("hello")
app = flask.Flask("hello")
@app.route("/")
def index():
sjkfq # uncaught expresion
return "hello"
if __name__ == "__main__":
app.run()
uj5u.com熱心網友回復:
我使用裝飾器來捕獲例外,這也可以記錄錯誤:
from flask import abort
from functools import wraps
def catch_uncaught(function):
"""
catches uncaught exceptions and logs them
aborts the request
"""
@wraps(function)
def wrapper(*args, **kwargs):
try:
res = function(*args, **kwargs)
return res # no errors occurred
except Exception as e:
# log stack trace
logging.error("\n" traceback.format_exc() "\n")
# abort the request instead of crashing
abort(500, "Internal Server error, do not retry")
return wrapper
(這也將中止請求而不是使服務器崩潰 - 但這是“可選的”。如果您更喜歡崩潰,return function(*args, **kwargs)在記錄而不是中止之后)
然后,您可以將此裝飾器放在要捕獲例外的路由之上以記錄它們:
@app.route("/")
@catch_uncaught
def index():
sjkfq # uncaught exception
return "hello"
這可能不是標準方式,但效果很好
uj5u.com熱心網友回復:
問題隱藏在燒瓶罩下的 werkzeug 服務器中。如果我們修補變數werkzeug.serving._log_add_style那么函式_ansi_style將不會改變任何日志條目的顏色。
import flask
import logging
import werkzeug.serving
werkzeug.serving._log_add_style = False
logging.basicConfig(filename='test.log', filemode='a', format='%(asctime)s %(levelname)s %(message)s')
logging.warning("hello")
app = flask.Flask("hello")
@app.route("/")
def index():
sjkfq # uncaught expression
return "hello"
app.run()
日志看起來像這樣
2022-10-27 18:31:56,193 WARNING hello
2022-10-27 18:31:56,199 INFO WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
* Running on http://127.0.0.1:5000
2022-10-27 18:31:56,199 INFO Press CTRL C to quit
2022-10-27 18:32:01,920 ERROR Exception on / [GET]
Traceback (most recent call last):
File "/Users/me/.env/test/lib/python3.8/site-packages/flask/app.py", line 2525, in wsgi_app
response = self.full_dispatch_request()
File "/Users/me/.env/test/lib/python3.8/site-packages/flask/app.py", line 1822, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Users/me/.env/test/lib/python3.8/site-packages/flask/app.py", line 1820, in full_dispatch_request
rv = self.dispatch_request()
File "/Users/me/.env/test/lib/python3.8/site-packages/flask/app.py", line 1796, in dispatch_request
return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
File "flask_logging.py", line 10, in index
sjkfq # uncaught expression
NameError: name 'sjkfq' is not defined
2022-10-27 18:32:01,922 INFO 127.0.0.1 - - [27/Oct/2022 18:32:01] "GET / HTTP/1.1" 500 -
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/522528.html
上一篇:Flask添加自定義后臺任務
