<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <title>-</title> <link rel="stylesheet" href="css/bootstrap.min.css"> <style> .button-expand { margin-right: 1em; } h1, .h1 { margin-top: 20px; } </style> </head> <body> <div class="container"> <div class="row"> <div class="col"> <h1 id="hostname">-</h1> <p style="margin-bottom: 0;"><small>refreshed every <span id="status_refresh_interval">-</span> seconds</small></p> </div> <div class="col h1 text-right"> <div class="btn-group align-middle" role="group"> <a role="button" class="btn btn-sm btn-warning" href="#" onclick="reboot();">Reboot</a> <a role="button" class="btn btn-sm btn-danger" href="#" onclick="shutdown();">Shutdown</a> </div> </div> </div> <div class="row"> <div class="col"> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_top">+</button><a href="#collapse_top" data-toggle="collapse"><code>top</code></a> <span class="float-right"><small>refreshed every <span id="top_refresh_interval">-</span> seconds</small></span></p> <div class="collapse show" id="collapse_top"> <pre class="pre-scrollable" id="top"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_failed_system">+</button><a href="#collapse_failed_system" data-toggle="collapse"><code>systemctl --system list-units --failed</code></a></p> <div class="collapse show" id="collapse_failed_system"> <pre class="pre-scrollable" id="failed_system"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_overview_system">+</button><a href="#collapse_overview_system" data-toggle="collapse"><code>systemctl --system status</code></a></p> <div class="collapse" id="collapse_overview_system"> <pre class="pre-scrollable" id="overview_system"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_timers_system">+</button><a href="#collapse_timers_system" data-toggle="collapse"><code>systemctl --system list-timers --all</code></a></p> <div class="collapse" id="collapse_timers_system"> <pre class="pre-scrollable" id="timers_system"></pre> </div> <hr> <p><button type="button" class="btn btn-outline-primary btn-sm button-expand" data-toggle="collapse" data-target="#collapse_journal_system">+</button><a href="#collapse_journal_system" data-toggle="collapse"><code>journalctl --system -b --lines=20</code></a></p> <div class="collapse" id="collapse_journal_system"> <pre class="pre-scrollable" id="journal_system"></pre> </div> <hr> </div> </div> <div id="users"> </div> </div> <script src="js/jquery-3.3.1.min.js"></script> <script src="js/bootstrap.bundle.min.js"></script> <script> function dump_fail(data) { console.log('Response code was: ' + data.status + ' ' + data.statusText); console.log('Response was:\n' + data.responseText); } function get(url, success_callback) { $.get(url, success_callback).fail(dump_fail); } function reboot() { get('reboot'); } function shutdown() { get('poweroff'); } function set_hostname(data) { $('#hostname').text(data); $('title').text(data); } function set_top(data) { $('#top').text(data); } function refresh_top() { get('top', function(data) { set_top(JSON.parse(data)); }); } var top_refresh_interval_seconds = 5; function loop_top() { setInterval(function() { refresh_top(); }, top_refresh_interval_seconds * 1000); $('#top_refresh_interval').text(top_refresh_interval_seconds); } function set_system(data) { if ('failed' in data) { $('#failed_system').text(data['failed']); } if ('overview' in data) { $('#overview_system').text(data['overview']); } if ('timers' in data) { $('#timers_system').text(data['timers']); } if ('journal' in data) { $('#journal_system').text(data['journal']); } } var users = []; function create_user_block(name, lbl, cmd) { let pre_id = `${lbl}_user_${name}`; let collapse_id = `collapse_${pre_id}`; let button_params = { 'class': 'btn btn-outline-primary btn-sm button-expand', 'data-toggle': 'collapse', 'data-target': '#' + collapse_id }; let a_params = { href: '#' + collapse_id, 'data-toggle': 'collapse' }; return $('<div/>') .append($('<p/>') .append($('<button/>', button_params).text('+')) .append($('<a/>', a_params) .append($('<code/>').text(cmd)))) .append($('<div/>', {'class': 'collapse', id: collapse_id}) .append($('<pre/>', {'class': 'pre-scrollable', id: pre_id}))) .append($('<hr/>')); } function add_user(name) { if (users.includes(name)) { return; } let container = $('<div/>', {'class': 'row', id: 'user_' + name}) .append($('<div/>', {'class': 'col'}) .append($('<h2/>').text(name)) .append($('<hr/>')) .append(create_user_block(name, 'failed', 'systemctl --user list-units --failed')) .append(create_user_block(name, 'overview', 'systemctl --user status')) .append(create_user_block(name, 'timers', 'systemctl --user list-timers --all')) .append(create_user_block(name, 'journal', 'journalctl --user -b --lines=20'))); $('#users').append(container); $('#collapse_failed_user_' + name).addClass('show'); users.push(name); } function set_user(name, data) { add_user(name); if ('failed' in data) { $('#failed_user_' + name).text(data['failed']); } if ('overview' in data) { $('#overview_user_' + name).text(data['overview']); } if ('timers' in data) { $('#timers_user_' + name).text(data['timers']); } if ('journal' in data) { $('#journal_user_' + name).text(data['journal']); } } function set_users(data) { users.forEach(function(name) { if (!(name in data)) { $('#user_' + name).remove(); let i = users.indexOf(name); if (i > -1) { users.splice(i, 1); } } }); Object.keys(data).forEach(function(name) { set_user(name, data[name]); }); } function refresh_status() { get('status', function(data) { data = JSON.parse(data); set_hostname(data['hostname']); set_system(data['system']); set_users(data['user']); }); } var status_refresh_interval_seconds = 30; function loop_status() { setInterval(function() { refresh_status(); }, status_refresh_interval_seconds * 1000); $('#status_refresh_interval').text(status_refresh_interval_seconds); } function main() { refresh_top(); refresh_status(); loop_top(); loop_status(); } $(function() { main(); }); </script> </body> </html>