fix(system): 优化服务状态检查的异常处理逻辑
在 `system.py` 中更新了服务状态检查的异常处理逻辑,当 supervisor 未安装或未运行时,记录为 WARNING 并返回友好的错误信息。增强了日志记录的可读性,确保在出现问题时提供清晰的反馈。同时,在 `position_manager.py` 中改进了止损止盈检查的错误日志,确保记录详细的错误信息以便于调试。
This commit is contained in:
parent
c750478af9
commit
3a2536ae96
|
|
@ -917,14 +917,28 @@ async def list_trading_services(_admin: Dict[str, Any] = Depends(require_system_
|
|||
"raw": status_all
|
||||
}
|
||||
except Exception as e:
|
||||
# 如果 supervisorctl status 失败,可能返回非 0 exit code
|
||||
# 但 _run_supervisorctl 已经处理了 status 命令的 exit 3 (stopped)
|
||||
# 如果是其他错误,记录日志并返回空列表
|
||||
# supervisor 未安装/未运行时(如 unix socket 不存在)避免刷 ERROR,改为 WARNING 并返回友好说明
|
||||
err_msg = str(e).strip()
|
||||
if not err_msg:
|
||||
err_msg = repr(e)
|
||||
is_supervisor_unavailable = (
|
||||
"no such file" in err_msg.lower()
|
||||
or "connection refused" in err_msg.lower()
|
||||
or "sock" in err_msg.lower()
|
||||
or "unix://" in err_msg.lower()
|
||||
)
|
||||
if is_supervisor_unavailable:
|
||||
logger.warning(f"列出服务失败(supervisor 未运行或不可用): {err_msg}")
|
||||
return {
|
||||
"summary": {"total": 0, "running": 0, "stopped": 0, "unknown": 0},
|
||||
"services": [],
|
||||
"error": "supervisor 未安装或未运行,请检查 supervisord 或配置 SUPERVISOR_CONF"
|
||||
}
|
||||
logger.error(f"列出服务失败: {e}")
|
||||
return {
|
||||
"summary": {"total": 0, "running": 0, "stopped": 0, "unknown": 0},
|
||||
"services": [],
|
||||
"error": str(e)
|
||||
"error": err_msg
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2032,30 +2032,41 @@ class BinanceClient:
|
|||
# 优先尝试 WebSocket 下单(减少 REST 超时)
|
||||
if self._ws_trade_client and self._ws_trade_client.is_connected():
|
||||
try:
|
||||
# 准备 WS 参数(需包含 apiKey, timestamp, signature)
|
||||
# 准备 WS 参数(与币安 WS 文档一致:apiKey, timestamp, recvWindow, 其余同 REST)
|
||||
ws_params = dict(params)
|
||||
ws_params["apiKey"] = self.api_key
|
||||
ts_ms = int(time.time() * 1000)
|
||||
if "timestamp" not in ws_params:
|
||||
ws_params["timestamp"] = int(time.time() * 1000)
|
||||
# 计算签名:币安要求参与签名的值格式与 REST 一致(布尔小写、空值不参与或为空串)
|
||||
ws_params["timestamp"] = ts_ms
|
||||
else:
|
||||
ws_params["timestamp"] = int(ws_params["timestamp"])
|
||||
# 扩大接收窗口,避免服务器与本地时钟偏差导致签名被拒
|
||||
ws_params["recvWindow"] = 60000
|
||||
# 币安 WS 文档中 closePosition 为 STRING,发送与签名均用 "true"/"false"
|
||||
if ws_params.get("closePosition") is True:
|
||||
ws_params["closePosition"] = "true"
|
||||
elif ws_params.get("closePosition") is False:
|
||||
ws_params["closePosition"] = "false"
|
||||
# 计算签名:参与签名的字符串必须与 REST 一致(键按字母序、值统一为字符串,布尔为 true/false)
|
||||
if "signature" not in ws_params:
|
||||
import hmac
|
||||
import hashlib
|
||||
from urllib.parse import urlencode
|
||||
def _param_val_for_signature(v):
|
||||
def _val_for_sig(v):
|
||||
if v is True:
|
||||
return "true"
|
||||
if v is False:
|
||||
return "false"
|
||||
if v is None:
|
||||
return ""
|
||||
s = str(v).strip()
|
||||
return s if s else ""
|
||||
sign_params = [(k, _param_val_for_signature(v)) for k, v in ws_params.items() if k != "signature"]
|
||||
query_string = urlencode(sorted(sign_params))
|
||||
if isinstance(v, (int, float)):
|
||||
return str(int(v)) if isinstance(v, float) and v == int(v) else str(v)
|
||||
return str(v).strip()
|
||||
to_sign = [(k, _val_for_sig(v)) for k, v in ws_params.items() if k != "signature"]
|
||||
query_string = urlencode(sorted(to_sign))
|
||||
signature = hmac.new(
|
||||
self.api_secret.encode('utf-8'),
|
||||
query_string.encode('utf-8'),
|
||||
self.api_secret.encode("utf-8"),
|
||||
query_string.encode("utf-8"),
|
||||
hashlib.sha256
|
||||
).hexdigest()
|
||||
ws_params["signature"] = signature
|
||||
|
|
@ -2357,7 +2368,7 @@ class BinanceClient:
|
|||
# 如果还是失败,记录详细参数用于调试
|
||||
logger.error(f"{symbol} ❌ 所有重试都失败,保护单挂单失败")
|
||||
logger.error(f" 参数: {params}")
|
||||
logger.error(f" 对冲模式: {dual}")
|
||||
logger.error(f" 对冲模式: {dual}(None 表示无法读取持仓模式,请检查网络或 API 权限)")
|
||||
return None
|
||||
|
||||
except BinanceAPIException as e:
|
||||
|
|
|
|||
|
|
@ -2383,7 +2383,8 @@ class PositionManager:
|
|||
continue
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"检查止损止盈失败: {e}")
|
||||
err_msg = str(e).strip() or repr(e) or type(e).__name__
|
||||
logger.error(f"检查止损止盈失败: {err_msg}")
|
||||
|
||||
return closed_positions
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user