fix(station): real monitoring for Vercel/GitHub via proxy, fix ok logic, health content check

Made-with: Cursor
This commit is contained in:
posimai 2026-04-12 13:07:23 +09:00
parent 65c358c58d
commit 4110de7239
3 changed files with 9 additions and 7 deletions

View File

@ -255,7 +255,7 @@ app.get('/api/check', async (req, res) => {
const timer = setTimeout(() => ctrl.abort(), 5000); const timer = setTimeout(() => ctrl.abort(), 5000);
const r = await fetch(url, { method: 'HEAD', signal: ctrl.signal }); const r = await fetch(url, { method: 'HEAD', signal: ctrl.signal });
clearTimeout(timer); clearTimeout(timer);
res.json({ ok: true, status: r.status, latency_ms: Date.now() - t0 }); res.json({ ok: r.status < 500, status: r.status, latency_ms: Date.now() - t0 });
} catch (e) { } catch (e) {
res.json({ ok: false, error: e.message, latency_ms: Date.now() - t0 }); res.json({ ok: false, error: e.message, latency_ms: Date.now() - t0 });
} }

View File

@ -352,8 +352,8 @@ const SERVICES = [
{id:'posimai-api',name:'Posimai API', desc:'Node.js / Express — VPS 本番', url:'/api/vps-health', isHealth:false, proxy:true}, {id:'posimai-api',name:'Posimai API', desc:'Node.js / Express — VPS 本番', url:'/api/vps-health', isHealth:false, proxy:true},
{id:'gitea', name:'Gitea', desc:'ローカル Git バックアップ (NAS)', url:'/api/check?url=http://100.76.7.3:3000', isHealth:false, proxy:true}, {id:'gitea', name:'Gitea', desc:'ローカル Git バックアップ (NAS)', url:'/api/check?url=http://100.76.7.3:3000', isHealth:false, proxy:true},
{id:'uptime-kuma',name:'Uptime Kuma', desc:'死活監視 — NAS Docker', url:'/api/check?url=http://100.76.7.3:3002', isHealth:false, proxy:true}, {id:'uptime-kuma',name:'Uptime Kuma', desc:'死活監視 — NAS Docker', url:'/api/check?url=http://100.76.7.3:3002', isHealth:false, proxy:true},
{id:'vercel', name:'Vercel', desc:'PWA ホスティング (27本)', url:'https://vercel.com', isHealth:false}, {id:'vercel', name:'Vercel', desc:'PWA ホスティング (27本)', url:'/api/check?url=https://vercel.com', isHealth:false, proxy:true},
{id:'github', name:'GitHub', desc:'ソースコード管理', url:'https://github.com/posimai', isHealth:false}, {id:'github', name:'GitHub', desc:'ソースコード管理', url:'/api/check?url=https://github.com', isHealth:false, proxy:true},
]; ];
const hist = {cpu:[], load:[]}; const hist = {cpu:[], load:[]};
const svcHist = {}; const svcHist = {};
@ -418,6 +418,7 @@ async function fetchHealth(){
try{ try{
const res=await fetch(HEALTH_URL); if(!res.ok)throw new Error(); const res=await fetch(HEALTH_URL); if(!res.ok)throw new Error();
const data=await res.json(); const data=await res.json();
if(data.status!=='ok')throw new Error('invalid health response');
const cpuPct=data.cpu_pct||0; const cpuPct=data.cpu_pct||0;
const memPct=data.mem_total_mb?Math.round((data.mem_used_mb/data.mem_total_mb)*100):0; const memPct=data.mem_total_mb?Math.round((data.mem_used_mb/data.mem_total_mb)*100):0;
const diskPct=data.disk?.use_pct??0; const diskPct=data.disk?.use_pct??0;
@ -573,7 +574,7 @@ async function checkService(svc){
const r=await fetch(svc.url,{signal:ctrl.signal}); const r=await fetch(svc.url,{signal:ctrl.signal});
clearTimeout(timer); clearTimeout(timer);
const data=await r.json(); const data=await r.json();
const ok=data.ok||(data.status&&data.status<500); const ok=data.ok && data.status < 500;
const ms=data.latency_ms||0; const ms=data.latency_ms||0;
badge.className='service-badge '+(ok?'ok':'crit'); badge.className='service-badge '+(ok?'ok':'crit');
badge.textContent=ok?'OK':'DOWN'; badge.textContent=ok?'OK':'DOWN';

View File

@ -336,8 +336,8 @@ const SERVICES = [
{id:'posimai-api',name:'Posimai API',desc:'Node.js / Express — VPS 本番', url:'/api/vps-health', isHealth:false, proxy:true}, {id:'posimai-api',name:'Posimai API',desc:'Node.js / Express — VPS 本番', url:'/api/vps-health', isHealth:false, proxy:true},
{id:'gitea', name:'Gitea', desc:'ローカル Git バックアップ', url:'/api/check?url=http://100.76.7.3:3000', isHealth:false, proxy:true}, {id:'gitea', name:'Gitea', desc:'ローカル Git バックアップ', url:'/api/check?url=http://100.76.7.3:3000', isHealth:false, proxy:true},
{id:'uptime-kuma',name:'Uptime Kuma', desc:'死活監視 — NAS Docker', url:'/api/check?url=http://100.76.7.3:3002', isHealth:false, proxy:true}, {id:'uptime-kuma',name:'Uptime Kuma', desc:'死活監視 — NAS Docker', url:'/api/check?url=http://100.76.7.3:3002', isHealth:false, proxy:true},
{id:'vercel', name:'Vercel', desc:'PWA ホスティング (27本)', url:'https://vercel.com', isHealth:false}, {id:'vercel', name:'Vercel', desc:'PWA ホスティング (27本)', url:'/api/check?url=https://vercel.com', isHealth:false, proxy:true},
{id:'github', name:'GitHub', desc:'ソースコード管理', url:'https://github.com/posimai', isHealth:false}, {id:'github', name:'GitHub', desc:'ソースコード管理', url:'/api/check?url=https://github.com', isHealth:false, proxy:true},
]; ];
const hist = {cpu:[], load:[]}; const hist = {cpu:[], load:[]};
const svcHist = {}; const svcHist = {};
@ -402,6 +402,7 @@ async function fetchHealth(){
try{ try{
const res=await fetch(HEALTH_URL); if(!res.ok)throw new Error(); const res=await fetch(HEALTH_URL); if(!res.ok)throw new Error();
const data=await res.json(); const data=await res.json();
if(data.status!=='ok')throw new Error('invalid health response');
const cpuPct=data.cpu_pct||0; const cpuPct=data.cpu_pct||0;
const memPct=data.mem_total_mb?Math.round((data.mem_used_mb/data.mem_total_mb)*100):0; const memPct=data.mem_total_mb?Math.round((data.mem_used_mb/data.mem_total_mb)*100):0;
const diskPct=data.disk?.use_pct??0; const diskPct=data.disk?.use_pct??0;
@ -552,7 +553,7 @@ async function checkService(svc){
const r=await fetch(svc.url,{signal:ctrl.signal}); const r=await fetch(svc.url,{signal:ctrl.signal});
clearTimeout(timer); clearTimeout(timer);
const data=await r.json(); const data=await r.json();
const ok=data.ok||(data.status&&data.status<500); const ok=data.ok && data.status < 500;
const ms=data.latency_ms||0; const ms=data.latency_ms||0;
badge.className='service-badge '+(ok?'ok':'crit'); badge.className='service-badge '+(ok?'ok':'crit');
badge.textContent=ok?'OK':'DOWN'; badge.textContent=ok?'OK':'DOWN';