如何在Python logging中捕获未处理错误并写入日志文件
解决未处理异常自动写入日志文件的问题
要让未处理的异常自动写入日志,核心是把Python默认输出到stderr的异常信息引导到你的logging系统中,无需在每个函数里手动添加logger.error。下面是两种实用方案:
方案一:重写系统异常钩子(sys.excepthook)
Python内置的sys.excepthook负责处理未捕获的异常,我们可以重写这个函数,将异常信息传递给logger完成记录:
import sys import logging import os # 保留你的原有日志配置逻辑 def get_datadir_path(): # 此处替换为你实际的路径获取逻辑 return "./" logger = logging.getLogger() logger.setLevel(logging.DEBUG) c_format = logging.Formatter('%(name)s:%(funcName)s - %(levelname)s - %(message)s') f_format = logging.Formatter('%(asctime)s - [%(levelname)s] -[%(name)s:%(funcName)s:%(lineno)d]- %(message)s', datefmt='%d-%b-%y %H:%M:%S') LOG_FILENAME = 'check.log' LOG_FILENAME = os.path.join(get_datadir_path(), LOG_FILENAME) f_handler = logging.FileHandler(LOG_FILENAME) f_handler.setFormatter(f_format) f_handler.setLevel(logging.DEBUG) c_handler = logging.StreamHandler(sys.stdout) c_handler.setFormatter(c_format) c_handler.setLevel(logging.DEBUG) logger.addHandler(c_handler) logger.addHandler(f_handler) # 重写异常钩子,捕获所有未处理异常 def handle_uncaught_exception(exc_type, exc_value, exc_traceback): # 跳过Ctrl+C触发的KeyboardInterrupt,避免冗余日志 if issubclass(exc_type, KeyboardInterrupt): sys.__excepthook__(exc_type, exc_value, exc_traceback) return # 用logger.exception自动记录完整异常栈 logger.exception("未处理的异常", exc_info=(exc_type, exc_value, exc_traceback)) sys.excepthook = handle_uncaught_exception # 测试示例代码 def test_func(): i = "hello" x = i /3 test_func()
关键说明:
logger.exception会自动包含完整的异常栈信息(traceback),能清晰展示错误发生的调用链和具体行号,比单纯用logger.error更实用。- 重写
sys.excepthook后,所有未被try-except捕获的异常都会被自动拦截并写入日志文件与控制台。
方案二:用try-except包裹主入口
如果你的程序有明确的主入口函数,可以直接用try-except包裹整个主逻辑:
# (原有日志配置保持不变) def main(): # 所有业务逻辑放在这个函数内 test_func() if __name__ == "__main__": try: main() except Exception as e: logger.exception("主程序未处理异常") # 可选:异常触发后退出程序 sys.exit(1)
这种方式适合结构简单的小型程序,而sys.excepthook更适配多模块、复杂调用链的场景。
内容的提问来源于stack exchange,提问作者ShashwatTheCoder
相关产品推荐
相关产品推荐

