log_viewer.html 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <title>R2R Log Viewer</title>
  5. <style>
  6. body {
  7. margin: 20px;
  8. font-family: monospace;
  9. background: #f8f9fa;
  10. }
  11. #logs {
  12. white-space: pre-wrap;
  13. background: white;
  14. padding: 20px;
  15. border-radius: 4px;
  16. height: 80vh;
  17. overflow-y: auto;
  18. border: 1px solid #e9ecef;
  19. box-shadow: 0 2px 4px rgba(0,0,0,0.05);
  20. }
  21. .log-entry {
  22. margin: 2px 0;
  23. border-bottom: 1px solid #f0f0f0;
  24. }
  25. .status {
  26. color: #666;
  27. font-style: italic;
  28. }
  29. </style>
  30. </head>
  31. <body>
  32. <h2>R2R Log Viewer</h2>
  33. <div id="logs"><span class="status">Connecting to log stream...</span></div>
  34. <!-- Include ansi_up via a CDN -->
  35. <script src="https://cdn.jsdelivr.net/npm/ansi_up@5.0.0/ansi_up.min.js"></script>
  36. <script>
  37. let ws = null;
  38. let ansi_up = new AnsiUp();
  39. function connect() {
  40. if (ws) {
  41. ws.close();
  42. }
  43. ws = new WebSocket(`ws://${window.location.host}/v3/logs/stream`);
  44. ws.onmessage = function(event) {
  45. const logsDiv = document.getElementById("logs");
  46. const newEntry = document.createElement('div');
  47. newEntry.className = 'log-entry';
  48. // Convert ANSI to HTML
  49. const htmlContent = ansi_up.ansi_to_html(event.data);
  50. newEntry.innerHTML = htmlContent;
  51. logsDiv.appendChild(newEntry);
  52. // Keep only the last 1000 entries
  53. while (logsDiv.children.length > 1000) {
  54. logsDiv.removeChild(logsDiv.firstChild);
  55. }
  56. logsDiv.scrollTop = logsDiv.scrollHeight;
  57. };
  58. ws.onclose = function() {
  59. const logsDiv = document.getElementById("logs");
  60. const msg = document.createElement('div');
  61. msg.className = 'status';
  62. msg.textContent = 'Connection lost. Reconnecting...';
  63. logsDiv.appendChild(msg);
  64. setTimeout(connect, 1000);
  65. };
  66. ws.onerror = function(err) {
  67. console.error('WebSocket error:', err);
  68. };
  69. }
  70. connect();
  71. window.onbeforeunload = function() {
  72. if (ws) {
  73. ws.close();
  74. }
  75. };
  76. </script>
  77. </body>
  78. </html>