fix: api_services cross-platform health URLs + frontend isHealthy() accepts online/remote

This commit is contained in:
hmo
2026-07-18 11:52:35 +08:00
parent 944ce33ac4
commit e4a9b7ff55
2 changed files with 12 additions and 8 deletions
+7 -5
View File
@@ -762,15 +762,17 @@ def api_services():
"""服务功能树 + watchdog 覆盖矩阵"""
try:
services = []
# xmpp_bot
svc1 = {"name": "xmpp_bot", "port": 5802, "health": _health_status("http://127.0.0.1:5802/health"),
# xmpp_bot (跨平台:通过 XMPP_BRIDGE_URL 检测 Windows .16)
xmpp_url = f"{XMPP_BRIDGE_URL}/health"
svc1 = {"name": "xmpp_bot", "port": 5802, "health": _health_status(xmpp_url),
"watchdog": True, "pid_lock": True, "type": "core", "depends_on": ["ejabberd"]}
services.append(svc1)
# article_processor
svc2 = {"name": "article_processor", "port": 5810, "health": _health_status("http://127.0.0.1:5810/health"),
# article_processor (跨平台:通过 PLATFORM_SERVICES 中的 health_url)
ap_url = "http://192.168.1.16:5810/health"
svc2 = {"name": "article_processor", "port": 5810, "health": _health_status(ap_url),
"watchdog": True, "pid_lock": False, "type": "bridge", "depends_on": []}
services.append(svc2)
# dashboard
# dashboard (本地)
svc3 = {"name": "dashboard", "port": 5803, "health": _health_status("http://127.0.0.1:5803/api/health"),
"watchdog": False, "pid_lock": True, "type": "mgmt", "depends_on": ["xmpp_bot"]}
services.append(svc3)
+5 -3
View File
@@ -156,6 +156,8 @@ async function doAct(id,act){try{var r=await fetch('/api/agents/'+id+'/'+act,{me
function tgL(id){if(L.has(id))L.delete(id);else L.add(id);var lp=qs('lp-'+id);if(lp)lp.className='lp'+(L.has(id)?' open':'');if(L.has(id))fL(id)}
async function fL(id){var el=qs('lc-'+id);if(!el||!L.has(id))return;try{var r=await fetch('/api/agents/'+id+'/logs?lines=50'),d=await r.json();el.innerHTML=(d.lines||[]).map(function(l){return'<div>'+esc(l)+'</div>'}).join('')||'<span class="dim">no log data</span>';el.scrollTop=el.scrollHeight}catch(e){el.innerHTML='<span class="red">Failed</span>'}}
async function fHealth(){try{
// Helpers
function isHealthy(st){return st==='running'||st==='online'||(st&&st.indexOf('remote')===0);}
// Service metadata: label / layer / impact
var M={};
M.ejabberd={n:'XMPP服务器',l:'通信层',i:'所有XMPP连接不可用'};
@@ -181,7 +183,7 @@ async function fHealth(){try{
// --- Layer 1: 系统概览 ---
var hCount=svcs.filter(function(s){return s.health&&s.health.ok}).length;
var cDown=exp.filter(function(e){return e.critical&&e.expected.indexOf('running')===0&&act[e.name]!=='running'}).length;
var cDown=exp.filter(function(e){return e.critical&&e.expected.indexOf('running')===0&&!isHealthy(act[e.name])}).length;
var st=cDown>0?'critical':hCount<svcs.length?'degraded':'good';
var stL={good:'正常',degraded:'部分异常',critical:'严重异常'};
var stC={good:'var(--green)',degraded:'var(--yellow)',critical:'var(--red)'};
@@ -195,7 +197,7 @@ async function fHealth(){try{
// --- Layer 2: 异常服务 ---
var issues=[];
for(var i=0;i<exp.length;i++){var e=exp[i];
if(e.critical&&e.expected.indexOf('running')===0&&act[e.name]!=='running'){
if(e.critical&&e.expected.indexOf('running')===0&&!isHealthy(act[e.name])){
var ma=M[e.key||e.name]||{n:e.name,i:'未知影响'};
issues.push({name:e.name,label:ma.n,impact:ma.i,status:act[e.name]||'stopped'});}}
for(var i=0;i<svcs.length;i++){var s=svcs[i];
@@ -218,7 +220,7 @@ async function fHealth(){try{
var ma=M[e.key||e.name]||{n:e.name,l:'辅助服务',i:''};
var ly=ma.l||'其他';
if(!layers[ly])layers[ly]=[];added[e.name]=true;
layers[ly].push({name:e.name,label:ma.n,port:e.port,status:act[e.name]==='running'?'running':act[e.name],critical:e.critical});}
layers[ly].push({name:e.name,label:ma.n,port:e.port,status:isHealthy(act[e.name])?'running':act[e.name],critical:e.critical});}
for(var i=0;i<svcs.length;i++){var s=svcs[i];
if(!added[s.name]){
var rawL=(M[s.name]||{}).l||(s.type==='infra'?'通信层':s.type==='gateway'?'AI网关':'辅助服务');