feat: add cache_read/cache_write to request logs, fix display
This commit is contained in:
@@ -305,6 +305,7 @@ for sd in glob.glob(os.path.join(oc_dir,'agents','*','sessions')):
|
|||||||
reqs.append({'node_id':nid,'upstream':m.get('provider',''),
|
reqs.append({'node_id':nid,'upstream':m.get('provider',''),
|
||||||
'model':m.get('model',''),'status':200,
|
'model':m.get('model',''),'status':200,
|
||||||
'input_tokens':u.get('input',0),'output_tokens':u.get('output',0),
|
'input_tokens':u.get('input',0),'output_tokens':u.get('output',0),
|
||||||
|
'cache_read':u.get('cacheRead',0),'cache_write':u.get('cacheWrite',0),
|
||||||
'ttft_ms':0,'total_ms':0,'success':True,
|
'ttft_ms':0,'total_ms':0,'success':True,
|
||||||
'ts':ts_val})
|
'ts':ts_val})
|
||||||
except: pass
|
except: pass
|
||||||
|
|||||||
@@ -228,13 +228,13 @@ function renderLogs(){
|
|||||||
if(fR!==''&&String(r.success?1:0)!==fR)return false;
|
if(fR!==''&&String(r.success?1:0)!==fR)return false;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
let h='<thead><tr><th>时间</th><th>节点</th><th>供应商</th><th>模型</th><th>结果</th><th>状态</th><th>输入</th><th>输出</th><th>首字</th><th>总耗时</th></tr></thead><tbody>';
|
let h='<thead><tr><th>时间</th><th>节点</th><th>供应商</th><th>模型</th><th>结果</th><th>输入</th><th>输出</th><th>缓存读</th><th>缓存写</th></tr></thead><tbody>';
|
||||||
filtered.forEach(r=>{
|
filtered.forEach(r=>{
|
||||||
const t=new Date(r.ts*1000).toLocaleTimeString('zh-CN');
|
const t=new Date(r.ts*1000).toLocaleTimeString('zh-CN');
|
||||||
h+='<tr><td>'+t+'</td><td>'+(r.node_name||r.node_id)+'</td><td>'+r.upstream+'</td><td>'+r.model+'</td>';
|
h+='<tr><td>'+t+'</td><td>'+(r.node_name||r.node_id)+'</td><td>'+r.upstream+'</td><td>'+r.model+'</td>';
|
||||||
h+='<td class="'+(r.success?'ok':'er')+'">'+(r.success?'✓':'✗')+'</td><td>'+r.status+'</td>';
|
h+='<td class="'+(r.success?'ok':'er')+'">'+(r.success?'✓':'✗')+'</td>';
|
||||||
h+='<td>'+fmtTok(r.input_tokens)+'</td><td>'+r.output_tokens+'</td>';
|
h+='<td>'+fmtTok(r.input_tokens)+'</td><td>'+fmtTok(r.output_tokens)+'</td>';
|
||||||
h+='<td style="color:var(--warn)">'+r.ttft_ms+'ms</td><td>'+fmtUp(r.total_ms)+'</td></tr>';
|
h+='<td style="color:var(--purple)">'+fmtTok(r.cache_read||0)+'</td><td style="color:var(--peach)">'+fmtTok(r.cache_write||0)+'</td></tr>';
|
||||||
});
|
});
|
||||||
$('#logTable').innerHTML=h+'</tbody>';
|
$('#logTable').innerHTML=h+'</tbody>';
|
||||||
// pager
|
// pager
|
||||||
|
|||||||
@@ -41,7 +41,11 @@ CREATE TABLE IF NOT EXISTS requests (
|
|||||||
);
|
);
|
||||||
CREATE INDEX IF NOT EXISTS idx_req_ts ON requests(ts);
|
CREATE INDEX IF NOT EXISTS idx_req_ts ON requests(ts);
|
||||||
CREATE INDEX IF NOT EXISTS idx_req_node ON requests(node_id);
|
CREATE INDEX IF NOT EXISTS idx_req_node ON requests(node_id);
|
||||||
CREATE TABLE IF NOT EXISTS tokens (
|
`);
|
||||||
|
// Add cache columns if missing (migration)
|
||||||
|
try { db.exec('ALTER TABLE requests ADD COLUMN cache_read INTEGER DEFAULT 0'); } catch(e) {}
|
||||||
|
try { db.exec('ALTER TABLE requests ADD COLUMN cache_write INTEGER DEFAULT 0'); } catch(e) {}
|
||||||
|
db.exec(`CREATE TABLE IF NOT EXISTS tokens (
|
||||||
id TEXT PRIMARY KEY DEFAULT 'global',
|
id TEXT PRIMARY KEY DEFAULT 'global',
|
||||||
token TEXT UNIQUE
|
token TEXT UNIQUE
|
||||||
);
|
);
|
||||||
@@ -59,7 +63,7 @@ const upsertNode = db.prepare(`INSERT INTO nodes(id,name,host,os,oc_version,role
|
|||||||
swap=excluded.swap,sessions=excluded.sessions,gw_ok=excluded.gw_ok,daemon_ok=excluded.daemon_ok,
|
swap=excluded.swap,sessions=excluded.sessions,gw_ok=excluded.gw_ok,daemon_ok=excluded.daemon_ok,
|
||||||
uptime=excluded.uptime,tok_today=excluded.tok_today,tok_week=excluded.tok_week,tok_month=excluded.tok_month,
|
uptime=excluded.uptime,tok_today=excluded.tok_today,tok_week=excluded.tok_week,tok_month=excluded.tok_month,
|
||||||
last_seen=excluded.last_seen`);
|
last_seen=excluded.last_seen`);
|
||||||
const insertReq = db.prepare(`INSERT INTO requests(node_id,upstream,model,status,input_tokens,output_tokens,ttft_ms,total_ms,success,ts) VALUES(?,?,?,?,?,?,?,?,?,?)`);
|
const insertReq = db.prepare(`INSERT INTO requests(node_id,upstream,model,status,input_tokens,output_tokens,cache_read,cache_write,ttft_ms,total_ms,success,ts) VALUES(?,?,?,?,?,?,?,?,?,?,?,?)`);
|
||||||
const getNodes = db.prepare("SELECT * FROM nodes ORDER BY role='master' DESC, name");
|
const getNodes = db.prepare("SELECT * FROM nodes ORDER BY role='master' DESC, name");
|
||||||
const getReqs = db.prepare("SELECT r.*,n.name as node_name FROM requests r LEFT JOIN nodes n ON r.node_id=n.id ORDER BY r.ts DESC LIMIT ?");
|
const getReqs = db.prepare("SELECT r.*,n.name as node_name FROM requests r LEFT JOIN nodes n ON r.node_id=n.id ORDER BY r.ts DESC LIMIT ?");
|
||||||
const getReqsPage = db.prepare("SELECT r.*,n.name as node_name FROM requests r LEFT JOIN nodes n ON r.node_id=n.id ORDER BY r.ts DESC LIMIT ? OFFSET ?");
|
const getReqsPage = db.prepare("SELECT r.*,n.name as node_name FROM requests r LEFT JOIN nodes n ON r.node_id=n.id ORDER BY r.ts DESC LIMIT ? OFFSET ?");
|
||||||
@@ -161,7 +165,8 @@ const server = http.createServer((req, res) => {
|
|||||||
const items = Array.isArray(b) ? b : [b];
|
const items = Array.isArray(b) ? b : [b];
|
||||||
for (const r of items) {
|
for (const r of items) {
|
||||||
insertReq.run(r.node_id,r.upstream,r.model,r.status||200,
|
insertReq.run(r.node_id,r.upstream,r.model,r.status||200,
|
||||||
r.input_tokens||0,r.output_tokens||0,r.ttft_ms||0,r.total_ms||0,
|
r.input_tokens||0,r.output_tokens||0,r.cache_read||0,r.cache_write||0,
|
||||||
|
r.ttft_ms||0,r.total_ms||0,
|
||||||
r.success!==false?1:0, r.ts||now);
|
r.success!==false?1:0, r.ts||now);
|
||||||
}
|
}
|
||||||
if (items.length <= 5) items.forEach(r => broadcast({ type:'request', request: r }));
|
if (items.length <= 5) items.forEach(r => broadcast({ type:'request', request: r }));
|
||||||
|
|||||||
Reference in New Issue
Block a user