如何使用Python logging模块记录Flask路由中未捕获的异常?
解决Flask路由未捕获异常的标准日志记录方案
问题根源分析
你的代码出现ANSI转义字符([31m[1m这类颜色控制符),主要有两个原因:
- Flask默认给日志添加了彩色控制台处理器,即使你配置了文件日志,Flask的默认日志输出仍会带颜色格式。
sys.excepthook仅捕获主线程的未捕获异常,而Flask路由请求是在子线程处理的,根本触发不到这个钩子。
正确实现方案
方案一:配置Flask专属日志处理器(推荐)
直接替换Flask默认的彩色日志处理器,添加自定义的文件日志格式,确保输出无颜色控制符:
import logging from flask import Flask app = Flask('hello') # 移除Flask默认的彩色控制台处理器 for handler in app.logger.handlers[:]: app.logger.removeHandler(handler) # 添加文件日志处理器,配置无颜色格式 file_handler = logging.FileHandler('test.log') file_formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s') file_handler.setFormatter(file_formatter) app.logger.addHandler(file_handler) app.logger.setLevel(logging.DEBUG) # 全局捕获所有未捕获异常 @app.errorhandler(Exception) def handle_uncaught_exception(e): # exc_info=e 自动记录完整异常栈 app.logger.error('路由未捕获异常', exc_info=e) return "服务器内部错误", 500 @app.route('/') def index(): sjkfq # 未捕获异常 return "hello" if __name__ == '__main__': app.run()
方案二:全局配置logging并关闭Flask彩色日志
通过环境变量或Flask配置关闭彩色日志,同时全局配置logging模块:
import logging import os from flask import Flask # 关闭Flask彩色日志(生产环境默认关闭,也可直接设置配置) os.environ['FLASK_ENV'] = 'production' # 或者直接设置:app.config['LOG_COLORS'] = False # 全局配置文件日志 logging.basicConfig( filename='test.log', filemode='a', format='%(asctime)s %(levelname)s %(message)s', level=logging.DEBUG ) app = Flask('hello') # 全局异常捕获 @app.errorhandler(Exception) def handle_exception(e): logging.error('路由未捕获异常', exc_info=e) return "服务器错误", 500 @app.route('/') def index(): sjkfq return "hello" app.run()
核心要点
- 必须用Flask的
@app.errorhandler(Exception)捕获路由异常,因为请求在子线程处理,sys.excepthook无效。 - 移除或替换Flask默认的彩色日志处理器,是避免ANSI字符写入文件的关键。
- 使用
exc_info参数记录异常,会自动生成完整的栈追踪信息,无需手动处理异常类型和追踪对象。
内容的提问来源于stack exchange,提问作者Basj
相关产品推荐
相关产品推荐

