From 1e006673e4914c428457e5974e2b17398a12ccd8 Mon Sep 17 00:00:00 2001 From: DingZQ Date: Mon, 2 Jun 2025 18:52:04 +0800 Subject: [PATCH] Print run_simulation log to log file --- epanet/epanet.py | 61 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/epanet/epanet.py b/epanet/epanet.py index 0c2ba18..a64aa59 100644 --- a/epanet/epanet.py +++ b/epanet/epanet.py @@ -4,6 +4,8 @@ import os import sys import json import base64 +import subprocess +import logging from typing import Any sys.path.append("..") from api import project @@ -290,7 +292,64 @@ def run_project(name: str, readable_output: bool = False) -> str: data = {} - result = os.system(command) + # DingZQ, 2025-06-02, 使用subprocess.Popen捕获输出到全局日志, 原来的代码是这么写的 + # result = os.system(command) + + """ + 执行带参数的外部exe并捕获输出到全局日志 + + :param exe_path: exe文件路径 + :param arguments: 命令行参数列表 + :param timeout: 执行超时时间(秒) + :return: 进程退出状态码 + """ + result = -1 + try: + # 启动子进程 + with subprocess.Popen( + command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, # 合并错误输出和标准输出 + text=True, # 文本模式(Python 3.7+) + bufsize=1, # 行缓冲 + encoding='utf-8', # 编码设置 + errors='replace' # 编码错误处理方式 + ) as process: + + # 实时读取输出流 + while True: + output_line = process.stdout.readline() + error_line = process.stderr.readline() + if output_line == '' and process.poll() is not None: + break + + if error_line == '' and process.poll() is not None: + break + + if output_line: + stripped_line = output_line.rstrip() + logging.info(f"EXE_OUTPUT: {stripped_line}") + + if error_line: + stripped_line = error_line.rstrip() + logging.error(f"EXE_ERROR: {stripped_line}") + + # 获取退出状态码 + returncode = process.poll() + + # 记录结束状态 + logging.info("-" * 60) + if returncode == 0: + logging.info(f"成功结束! 退出码: {returncode}") + else: + logging.error(f"异常结束! 退出码: {returncode}") + + result = returncode + + except Exception as e: + logging.exception(f"执行过程中出错: {str(e)}") + result = -1 # 自定义错误码 + if result != 0: data['simulation_result'] = 'failed' else: