MCPcopy Create free account
hub / github.com/Tele-AI/Fluxon / _handle_log

Method _handle_log

fluxon_test_stack/gitops/gitops_lib.py:1453–1617  ·  view source on GitHub ↗
(self, parsed)

Source from the content-addressed store, hash-verified

1451
1452 rid_html = _html_escape(rid)
1453
1454 # Log viewer: tail-first, auto-refresh, lazy-load older chunks on scroll.
1455 # We keep HTML as a static template so it can be copied into a standalone file.
1456 html = """<!doctype html>
1457<html><head><meta charset='utf-8'/>
1458<meta name='viewport' content='width=device-width, initial-scale=1'/>
1459<title>Log @@RID@@</title>
1460<style>
1461body{font-family:ui-sans-serif,system-ui,Segoe UI,Roboto,Helvetica,Arial;max-width:1400px;margin:16px auto;padding:0 12px;}
1462code,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;}
1463#log{white-space:pre;background:#0b1020;color:#e5e7eb;padding:12px;border-radius:8px;height:78vh;overflow:auto;font-size:12px;line-height:1.35;tab-size:4;}
1464.small{color:#6b7280;font-size:12px;}
1465.btn{padding:4px 8px;border:1px solid #e5e7eb;border-radius:6px;background:#fff;cursor:pointer;}
1466.row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;}
1467</style>
1468</head><body>
1469<a href='/run?id=@@RID@@'>back</a>
1470<h2>run.log tail</h2>
1471<div class='row'>
1472 <div class='small'>run_id: <code>@@RID@@</code></div>
1473 <button class='btn' id='btnFollow'>follow: on</button>
1474 <button class='btn' id='btnReload'>reload tail</button>
1475 <div class='small' id='status'></div>
1476</div>
1477<div id='log'></div>
1478<script>
1479(function(){
1480 const runId = "@@RID@@";
1481 const logEl = document.getElementById('log');
1482 const statusEl = document.getElementById('status');
1483 const btnFollow = document.getElementById('btnFollow');
1484 const btnReload = document.getElementById('btnReload');
1485
1486 let follow = true;
1487 let loading = false;
1488 let loadedStart = null;
1489 let loadedEnd = null;
1490
1491 const MAX_BYTES = 65536;
1492 const POLL_MS = 800;
1493
1494 function setStatus(s){ statusEl.textContent = s; }
1495 function nearBottom(){ return (logEl.scrollHeight - (logEl.scrollTop + logEl.clientHeight)) < 40; }
1496 function scrollToBottom(){ logEl.scrollTop = logEl.scrollHeight; }
1497
1498 async function fetchChunk(params){
1499 const url = new URL('/api/log_chunk', window.location.origin);
1500 url.searchParams.set('id', runId);
1501 url.searchParams.set('kind', 'run');
1502 url.searchParams.set('max_bytes', String(MAX_BYTES));
1503 for (const [k,v] of Object.entries(params || {})) {
1504 url.searchParams.set(k, String(v));
1505 }
1506 const resp = await fetch(url.toString());
1507 if (!resp.ok) {
1508 const t = await resp.text();
1509 throw new Error('http ' + resp.status + ' ' + t);
1510 }

Callers 1

do_GETMethod · 0.95

Calls 3

_send_htmlMethod · 0.95
_html_escapeFunction · 0.70
getMethod · 0.45

Tested by

no test coverage detected