| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879 |
- <!DOCTYPE html><html><head>
- <meta charset='UTF-8'>
- <meta name='viewport' content='width=device-width,initial-scale=1'>
- <title>System Logs</title>
- <style>
- *{box-sizing:border-box;margin:0;padding:0}
- body{font-family:-apple-system,system-ui,sans-serif;background:#0d1117;color:#c9d1d9;min-height:100vh;display:flex;flex-direction:column}
- .toolbar{background:#161b22;padding:10px 16px;display:flex;align-items:center;gap:12px;border-bottom:1px solid #30363d}
- .toolbar h1{font-size:16px;font-weight:600;flex:1}
- .toolbar a{color:#58a6ff;text-decoration:none;font-size:13px}
- .dot{width:10px;height:10px;border-radius:50%;background:#f85149}
- .dot.ok{background:#3fb950}
- .btn-sm{padding:6px 12px;border:1px solid #30363d;border-radius:6px;background:#21262d;color:#c9d1d9;font-size:12px;cursor:pointer}
- .btn-sm:hover{background:#30363d}
- #log{flex:1;overflow-y:auto;padding:12px 16px;font-family:'SF Mono',Consolas,monospace;font-size:12px;line-height:1.6;white-space:pre-wrap;word-break:break-all}
- .a30{color:#484f58}.a31{color:#f85149}.a32{color:#3fb950}.a33{color:#d29922}.a34{color:#58a6ff}.a35{color:#bc8cff}.a36{color:#39c5cf}.a37{color:#c9d1d9}
- .a90{color:#6e7681}.a91{color:#ff7b72}.a92{color:#56d364}.a93{color:#e3b341}.a94{color:#79c0ff}.a95{color:#d2a8ff}.a96{color:#56d4dd}.a97{color:#f0f6fc}
- </style></head><body>
- <div class='toolbar'>
- <a href='/'>← Back</a>
- <h1>System Logs</h1>
- <span id='dot' class='dot'></span>
- <button class='btn-sm' onclick='clear_log()'>Clear</button>
- <button class='btn-sm' id='scroll-btn' onclick='toggle_scroll()'>Auto-scroll: ON</button>
- </div>
- <div id='log'><div id='anchor'></div></div>
- <script>
- var log=document.getElementById('log'),dot=document.getElementById('dot'),anchor=document.getElementById('anchor'),autoScroll=true,maxLines=2000;
- function toggle_scroll(){autoScroll=!autoScroll;document.getElementById('scroll-btn').textContent='Auto-scroll: '+(autoScroll?'ON':'OFF');}
- function clear_log(){log.innerHTML='';anchor=document.createElement('div');anchor.id='anchor';log.appendChild(anchor);}
- var ansiRe=/\x1b\[([0-9;]*)m/g;
- var ansiCls={'30':1,'31':1,'32':1,'33':1,'34':1,'35':1,'36':1,'37':1,'90':1,'91':1,'92':1,'93':1,'94':1,'95':1,'96':1,'97':1};
- var letterCls={'E':'a31','W':'a33','I':'a32','D':'a30','V':'a30'};
- function colorize(text){
- var frag=document.createDocumentFragment();
- text.split('\n').forEach(function(line){
- if(!line)return;
- var wrap=document.createElement('span');
- var hasAnsi=ansiRe.test(line);
- ansiRe.lastIndex=0;
- if(hasAnsi){
- var last=0,cls=null,m;
- while((m=ansiRe.exec(line))!==null){
- if(m.index>last){
- var s=document.createElement('span');
- if(cls)s.className=cls;
- s.textContent=line.substring(last,m.index);
- wrap.appendChild(s);
- }
- var p=m[1].split(';');cls=null;
- for(var i=0;i<p.length;i++){if(ansiCls[p[i]])cls='a'+p[i];}
- last=ansiRe.lastIndex;
- }
- if(last<line.length){
- var s=document.createElement('span');
- if(cls)s.className=cls;
- s.textContent=line.substring(last);
- wrap.appendChild(s);
- }
- }else{
- var ch=line.charAt(0);
- if(letterCls[ch])wrap.className=letterCls[ch];
- wrap.textContent=line;
- }
- wrap.appendChild(document.createTextNode('\n'));
- frag.appendChild(wrap);
- });
- log.insertBefore(frag,anchor);
- while(log.childNodes.length>maxLines+1)log.removeChild(log.firstChild);
- if(autoScroll)anchor.scrollIntoView();
- }
- function connect(){
- var ws=new WebSocket('ws://'+location.host+'/ws/logs');
- ws.onopen=function(){dot.classList.add('ok');};
- ws.onclose=function(){dot.classList.remove('ok');setTimeout(connect,2000);};
- ws.onmessage=function(e){colorize(e.data);};
- }
- connect();
- </script></body></html>
|