本地运行Python服务程序时如何打印完整异常栈跟踪信息
完整栈跟踪输出修改方案
1. 调整program3的日志输出逻辑
当前代码中只用logging.error格式化异常对象本身,只会输出异常的基础描述,不会携带栈跟踪信息,两种修改方式二选一即可:
- 方案1:使用
logging.exception方法(默认属于ERROR日志级别,自动捕获当前上下文的异常栈)
except (socket.error, xmlrpc.client.Fault) as e: logging.exception("Agent %d was unable to play step %d.", agent, self.step)
- 方案2:给
logging.error添加exc_info=True参数,强制输出异常栈
except (socket.error, xmlrpc.client.Fault) as e: logging.error("Agent %d was unable to play step %d. Reason: %s", agent, self.step, e, exc_info=True)
注意:因为
KeyboardInterrupt是program1触发后被xmlrpc服务端封装成Fault对象返回给program3的,所以program3默认只能拿到服务端传回的基础异常信息,要获取完整栈还需要同步修改program1的逻辑。
2. 调整program1的xmlrpc服务端异常处理逻辑
xmlrpc默认的服务端实现只会把异常类型和基础描述封装到Fault对象返回,不会自动打印服务端栈,也不会把栈信息传给客户端,按需求修改即可:
2.1 仅在program1本地输出完整栈
自定义请求处理类,在调度rpc方法时捕获异常打印栈:
import traceback from xmlrpc.server import SimpleXMLRPCRequestHandler, SimpleXMLRPCServer class CustomRPCRequestHandler(SimpleXMLRPCRequestHandler): def _dispatch(self, method, params): try: return super()._dispatch(method, params) except Exception: # 服务端本地打印完整异常栈 traceback.print_exc() raise # 启动服务时指定自定义handler,示例: if __name__ == "__main__": server = SimpleXMLRPCServer(("localhost", 8000), requestHandler=CustomRPCRequestHandler) # 后续注册方法、启动服务的逻辑保持不变
2.2 让program3也能拿到完整栈
如果需要客户端也能获取到服务端的异常栈,可以在封装Fault时把栈信息加入描述:
import xmlrpc import traceback from xmlrpc.server import SimpleXMLRPCRequestHandler class CustomRPCRequestHandler(SimpleXMLRPCRequestHandler): def _dispatch(self, method, params): try: return super()._dispatch(method, params) except Exception as e: stack_info = traceback.format_exc() raise xmlrpc.client.Fault(1, f"{type(e).__name__}: {e}\n完整栈跟踪:\n{stack_info}") from e
修改后program3打印Fault时就会携带完整的服务端栈信息。
内容的提问来源于stack exchange,提问作者qwerty_99
相关产品推荐
相关产品推荐

