UNPKG

web_plsql

Version:

The Express Middleware for Oracle PL/SQL

517 lines (503 loc) 21.5 kB
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>web_plsql Admin Console</title> <link rel="icon" type="image/svg+xml" href="/admin/assets/favicon-mQAM4tVu.svg" /> <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200" /> <script type="module" crossorigin src="/admin/assets/main-C8GKnEhz.js"></script> <link rel="stylesheet" crossorigin href="/admin/assets/main-bU4x_yEW.css"> </head> <body class="dark"> <div class="app-container"> <aside class="sidebar"> <div class="logo"> <span class="material-symbols-rounded">database</span> <div style="display: flex; flex-direction: column; line-height: 1"> <span>web_plsql</span> <small id="sidebar-version" style="font-size: 0.65rem; opacity: 0.7; margin-top: 2px"></small> </div> </div> <nav> <button data-view="overview" class="active"> <span class="material-symbols-rounded">dashboard</span> Overview </button> <button data-view="trace"> <span class="material-symbols-rounded">bolt</span> Requests </button> <button data-view="errors"> <span class="material-symbols-rounded">error</span> Errors </button> <button data-view="access"> <span class="material-symbols-rounded">list_alt</span> Access Log </button> <button data-view="pools"> <span class="material-symbols-rounded">database</span> Pools </button> <button data-view="stats"> <span class="material-symbols-rounded">query_stats</span> Stats </button> <button data-view="config"> <span class="material-symbols-rounded">settings</span> Configuration </button> <button data-view="system"> <span class="material-symbols-rounded">terminal</span> System </button> </nav> <div class="status-indicator"> <span id="server-status-dot" class="dot"></span> <span id="server-status-text">Checking...</span> </div> </aside> <main class="content"> <header class="main-header"> <h1 id="view-title"><span class="material-symbols-rounded">dashboard</span>Overview</h1> <div class="header-toolbar"> <div class="auto-refresh-group"> <label for="auto-refresh-toggle">Auto-refresh</label> <input type="checkbox" id="auto-refresh-toggle" checked /> <select id="refresh-interval"> <option value="1000">1s</option> <option value="5000">5s</option> <option value="10000" selected>10s</option> <option value="30000">30s</option> <option value="60000">1m</option> </select> <button id="manual-refresh" class="icon-btn icon-sm" title="Refresh Now" style="border: none; background: none; padding: 0; min-width: auto; min-height: auto; margin-left: 4px" > <span class="material-symbols-rounded" style="font-size: 20px">refresh</span> </button> </div> <button id="theme-toggle-btn" class="icon-btn" title="Toggle Theme"> <span class="material-symbols-rounded">dark_mode</span> </button> </div> </header> <section id="view-overview" class="view"> <div class="metrics-grid"> <div class="card" title="Time since the server started"> <div class="card-header"> <span class="material-symbols-rounded">schedule</span> <h3 title="Time since the server started">Uptime</h3> </div> <p id="uptime-val" title="Total uptime duration">0s</p> <small id="start-time-val" title="Exact server start time">-</small> </div> <div class="card" title="Request throughput and response times"> <div class="card-header"> <span class="material-symbols-rounded">swap_vert</span> <h3 title="Request throughput and response times">Requests</h3> </div> <div class="flex items-baseline gap-1 mb-2" title="Current and maximum requests per second"> <span id="req-per-sec" class="text-2xl font-bold text-bright">0.00</span> <span class="text-xs text-main font-medium uppercase mr-2">cur /s</span> <span class="text-main opacity-30 mr-2">/</span> <span id="max-req-per-sec" class="text-2xl font-bold text-bright">0.00</span> <span class="text-xs text-main font-medium uppercase">max /s</span> </div> <div class="flex gap-4"> <small class="text-main" title="Average response time">Avg: <span id="avg-resp-time" class="font-bold">0ms</span></small> <small class="text-main" title="Maximum response time">Max: <span id="max-resp-time" class="font-bold">0ms</span></small> </div> </div> <div class="card" title="Total number of requests that resulted in an error"> <div class="card-header"> <span class="material-symbols-rounded">report</span> <h3 title="Total number of requests that resulted in an error">Errors</h3> </div> <p id="err-count" title="Total error count">0</p> </div> <div class="card" title="Efficiency of the internal cache"> <div class="card-header"> <span class="material-symbols-rounded">cached</span> <h3 title="Efficiency of the internal cache">Cache Hit Rate</h3> </div> <p id="cache-hit-rate-val" title="Percentage of requests served from cache">0%</p> <small ><span id="cache-hits-val" title="Total cache hits">0</span> hits, <span id="cache-misses-val" title="Total cache misses">0</span> misses</small > </div> </div> <div class="card" style="grid-column: span 2"> <div class="card-header"> <span class="material-symbols-rounded">monitoring</span> <h3>TRAFFIC</h3> <div class="header-toolbar ml-auto"> <select id="chart-history-points" class="btn-sm" style=" background: var(--bg-hover); border: 1px solid var(--border); border-radius: 4px; color: var(--text-main); font-size: 0.75rem; padding: 2px 4px; " > <option value="60">Last 1 min</option> <option value="300">Last 5 min</option> <option value="600" selected>Last 10 min</option> <option value="1800">Last 30 min</option> <option value="3600">Last 1 hour</option> <option value="7200">Last 2 hours</option> <option value="43200">Last 12 hours</option> <option value="86400">Last 24 hours</option> </select> </div> </div> <div class="chart-container"> <canvas id="traffic-chart"></canvas> </div> </div> </section> <section id="view-pools" class="view" style="display: none"> <div id="pools-container" class="pools-grid"></div> <div class="card"> <div class="card-header"> <span class="material-symbols-rounded">analytics</span> <h3>Pool Usage History</h3> </div> <div class="chart-container"> <canvas id="pool-chart"></canvas> </div> </div> </section> <section id="view-errors" class="view" style="display: none"> <div class="header-toolbar mb-4" style="justify-content: flex-start; gap: 12px"> <div class="search-group" style="flex: 1; max-width: 400px"> <span class="material-symbols-rounded" style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0.5" >search</span > <input type="text" id="error-filter" placeholder="Filter errors (URL, message, method)..." class="input-sm" style="width: 100%; padding-left: 32px" /> </div> <div class="flex items-center gap-2"> <label for="error-limit" class="text-xs text-main">Max entries:</label> <input type="number" id="error-limit" value="100" min="1" max="5000" class="input-sm" style="width: 100px" /> </div> <button id="error-load-btn" class="btn btn-sm btn-primary"> <span class="material-symbols-rounded" style="font-size: 18px">refresh</span> Load Errors </button> </div> <div class="table-container"> <table id="errors-table"> <thead></thead> <tbody></tbody> </table> </div> </section> <section id="view-trace" class="view" style="display: none"> <div class="header-toolbar mb-4" style="justify-content: flex-start; gap: 12px"> <div class="search-group" style="flex: 1; max-width: 300px"> <span class="material-symbols-rounded" style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0.5" >search</span > <input type="text" id="trace-filter" placeholder="Filter traces..." class="input-sm" style="width: 100%; padding-left: 32px" /> </div> <div class="flex items-center gap-2"> <label for="trace-limit" class="text-xs text-main">Max entries:</label> <input type="number" id="trace-limit" value="100" min="1" max="5000" class="input-sm" style="width: 80px" /> </div> <button id="trace-load-btn" class="btn btn-sm btn-primary"> <span class="material-symbols-rounded" style="font-size: 18px">refresh</span> Refresh </button> <button id="trace-clear-btn" class="btn btn-sm btn-danger"> <span class="material-symbols-rounded" style="font-size: 18px">delete</span> Clear </button> <button id="trace-status-toggle" class="btn btn-sm px-4 py-2 rounded-lg text-sm font-bold transition-colors bg-white/10 text-white hover:bg-white/20" > Tracing: OFF </button> </div> <div class="table-container"> <table id="trace-table"> <thead></thead> <tbody></tbody> </table> </div> </section> <section id="view-access" class="view" style="display: none"> <div class="header-toolbar mb-4" style="justify-content: flex-start; gap: 12px"> <div class="search-group" style="flex: 1; max-width: 400px"> <span class="material-symbols-rounded" style="position: absolute; left: 8px; top: 50%; transform: translateY(-50%); font-size: 18px; opacity: 0.5" >search</span > <input type="text" id="access-filter" placeholder="Filter logs..." class="input-sm" style="width: 100%; padding-left: 32px" /> </div> <div class="flex items-center gap-2"> <label for="access-limit" class="text-xs text-main">Max entries:</label> <input type="number" id="access-limit" value="100" min="1" max="5000" class="input-sm" style="width: 100px" /> </div> <button id="access-load-btn" class="btn btn-sm btn-primary"> <span class="material-symbols-rounded" style="font-size: 18px">refresh</span> Load Logs </button> <small id="access-log-range" class="text-main" style="margin-left: auto">No logs loaded</small> </div> <div class="terminal-container"> <pre id="access-log-view" class="terminal" title="Real-time access logs from the server"></pre> </div> </section> <section id="view-stats" class="view" style="display: none"> <div class="header-toolbar mb-4" style="justify-content: flex-start; gap: 12px"> <div class="flex items-center gap-2"> <label for="stats-limit" class="text-xs text-main">Max entries:</label> <input type="number" id="stats-limit" value="50" min="1" max="1000" class="input-sm" style="width: 80px" /> </div> <button id="stats-load-btn" class="btn btn-sm btn-primary"> <span class="material-symbols-rounded" style="font-size: 18px">refresh</span> Load Stats </button> <small id="stats-history-info" class="text-main" style="margin-left: auto">No stats loaded</small> </div> <div class="table-container"> <table id="stats-table"> <thead> <tr> <th title="Timestamp of the interval">Timestamp</th> <th title="Requests in this interval" class="text-center">Req</th> <th title="Errors in this interval" class="text-center">Err</th> <th title="Min Latency (ms)" class="text-right">Min</th> <th title="Avg Latency (ms)" class="text-right">Avg</th> <th title="95th Percentile Latency (ms)" class="text-right">P95</th> <th title="99th Percentile Latency (ms)" class="text-right">P99</th> <th title="Max Latency (ms)" class="text-right">Max</th> <th title="CPU Usage (%)" class="text-right">CPU %</th> <th title="Resident Set Size (MB)" class="text-right">RSS</th> <th title="Heap Used (MB)" class="text-right">Heap</th> </tr> </thead> <tbody></tbody> </table> </div> </section> <section id="view-config" class="view" style="display: none"> <div id="config-view"></div> </section> <section id="view-system" class="view view-system-compact" style="display: none"> <div class="metrics-grid mb-4"> <div class="card"> <div class="card-header"> <span class="material-symbols-rounded">info</span> <h3>Server Information</h3> </div> <div class="text-sm text-main"> <div class="stat-row"> <span>Middleware Version</span> <span id="middleware-version" class="font-mono text-accent font-bold">-</span> </div> <div class="stat-row"> <span>Node.js Version</span> <span id="node-version" class="font-mono text-accent font-bold">-</span> </div> <div class="stat-row"> <span>Platform</span> <span id="platform-info" class="text-accent font-bold">-</span> </div> </div> </div> <div class="card"> <div class="card-header"> <span class="material-symbols-rounded">schedule</span> <h3>Runtime</h3> </div> <div class="text-sm text-main"> <div class="stat-row"> <span>Server Uptime</span> <span id="system-uptime" class="text-accent font-bold">-</span> </div> <div class="stat-row"> <span>Start Time</span> <span id="system-start-time" class="text-accent font-bold">-</span> </div> <div class="stat-row"> <span>Status</span> <span id="system-status" class="status-dot"> <span class="dot running"></span> <span id="system-status-text" class="text-accent font-bold">-</span> </span> </div> </div> </div> <div class="card"> <div class="card-header"> <span class="material-symbols-rounded">insights</span> <h3>Activity</h3> </div> <div class="text-sm text-main"> <div class="stat-row"> <span>Total Requests</span> <span id="total-requests" class="font-mono text-accent font-bold">-</span> </div> <div class="stat-row"> <span>Total Errors</span> <span id="total-errors" class="font-mono text-danger font-bold">-</span> </div> <div class="stat-row"> <span>Active Pools</span> <span id="active-pools" class="font-mono text-accent font-bold">-</span> </div> </div> </div> </div> <div class="metrics-grid"> <div class="card resource-card" title="Memory usage statistics for the Node.js process"> <div class="card-header"> <span class="material-symbols-rounded">memory</span> <h3 title="Memory usage statistics for the Node.js process">Memory Usage</h3> </div> <div class="stat-container-wrapper text-sm text-main"> <div class="stat-container"> <div class="stat-row"> <span>Memory Usage (%)</span> <span id="memory-percent" class="font-mono text-accent font-bold">-</span> </div> <div class="stat-row" title="Memory currently used by Node.js objects"> <span>Heap Used</span> <div class="stat-values"> <span id="memory-heap-used" class="font-mono text-accent font-bold">-</span> <small class="min-max">max: <span id="memory-heap-used-max">-</span></small> </div> </div> <div class="stat-row" title="Total memory allocated for the heap"> <span>Heap Total</span> <div class="stat-values"> <span id="memory-heap-total" class="font-mono text-accent font-bold">-</span> <small class="min-max">max: <span id="memory-heap-total-max">-</span></small> </div> </div> <div class="stat-row" title="Resident Set Size - total memory used by the process"> <span>RSS</span> <div class="stat-values"> <span id="memory-rss" class="font-mono text-accent font-bold">-</span> <small class="min-max">max: <span id="memory-rss-max">-</span></small> </div> </div> </div> </div> <div class="chart-container-mini"> <canvas id="memory-chart"></canvas> </div> </div> <div class="card resource-card" title="CPU time consumed by the process"> <div class="card-header"> <span class="material-symbols-rounded">speed</span> <h3 title="CPU time consumed by the process">CPU Usage</h3> </div> <div class="stat-container-wrapper text-sm text-main"> <div class="stat-container"> <div class="stat-row"> <span>CPU Usage (%)</span> <span id="cpu-percent" class="font-mono text-accent font-bold">-</span> </div> <div class="stat-row" title="Time spent in user code"> <span>User</span> <div class="stat-values"> <span id="cpu-user" class="font-mono text-accent font-bold">-</span> <small class="min-max">max: <span id="cpu-user-max">-</span></small> </div> </div> <div class="stat-row" title="Time spent in system (kernel) code"> <span>System</span> <div class="stat-values"> <span id="cpu-system" class="font-mono text-accent font-bold">-</span> <small class="min-max">max: <span id="cpu-system-max">-</span></small> </div> </div> <div class="stat-row"> <span>Hardware</span> <span id="cpu-cores-info" class="text-accent font-bold">-</span> </div> </div> </div> <div class="chart-container-mini"> <canvas id="cpu-chart"></canvas> </div> </div> </div> <div class="card danger-zone"> <h3 class="danger-zone-title">Danger Zone</h3> <div style="display: flex; gap: 12px; margin-top: 16px"> <button id="btn-clear-all-cache" class="btn btn-sm btn-warning">Clear All Caches</button> <button id="btn-pause" class="btn btn-sm btn-warning">Pause Server</button> <button id="btn-resume" class="btn btn-sm btn-success" style="display: none">Resume Server</button> <button id="btn-stop" class="btn btn-sm btn-danger">Stop Server</button> </div> </div> </section> </main> </div> <div id="error-modal" class="modal" style="display: none"> <div class="modal-content"> <div class="modal-header"> <h3>Error Details</h3> <button class="icon-btn" onclick="document.getElementById('error-modal').style.display = 'none'"> <span class="material-symbols-rounded">close</span> </button> </div> <div class="modal-body"> <pre id="error-detail-content" class="terminal" style="max-height: 70vh; overflow: auto"></pre> </div> </div> </div> <div id="trace-modal" class="modal" style="display: none"> <div class="modal-content"> <div class="modal-header"> <h3>Trace Details</h3> <button class="icon-btn" onclick="document.getElementById('trace-modal').style.display = 'none'"> <span class="material-symbols-rounded">close</span> </button> </div> <div class="modal-body"> <pre id="trace-detail-content" class="terminal" style="max-height: 70vh; overflow: auto"></pre> </div> </div> </div> <div id="offline-modal" class="modal" style="display: none"> <div class="modal-content" style="max-width: 400px; text-align: center"> <div class="modal-body" style="display: flex; flex-direction: column; align-items: center; gap: 16px; padding: 32px"> <span class="material-symbols-rounded" style="font-size: 48px; color: var(--danger)">wifi_off</span> <h3 style="margin: 0; font-size: 1.25rem; color: var(--text-bright)">Connection Lost</h3> <p style="margin: 0; color: var(--text-main)">The server is unreachable. Please check your connection or server status.</p> <p id="offline-countdown" style="margin: 0; color: var(--text-main); font-size: 0.875rem"></p> <button id="btn-reconnect" class="btn btn-primary btn-lg w-full justify-center"> <span id="reconnect-icon" class="material-symbols-rounded">refresh</span> <span id="reconnect-spinner" class="material-symbols-rounded animate-spin" style="display: none">sync</span> <span id="reconnect-text">Try Reconnect</span> </button> </div> </div> </div> </body> </html>