mirror of
https://github.com/systemd/systemd.git
synced 2024-11-08 11:27:32 +03:00
283 lines
12 KiB
HTML
283 lines
12 KiB
HTML
|
<!DOCTYPE html>
|
||
|
<html>
|
||
|
<head>
|
||
|
<title>Journal</title>
|
||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
||
|
<style type="text/css">
|
||
|
div#logs {
|
||
|
font-family: monospace;
|
||
|
font-size: 8pt;
|
||
|
background-color: #ffffff;
|
||
|
padding: 1em;
|
||
|
margin: 2em 0em;
|
||
|
border-radius: 10px 10px 10px 10px;
|
||
|
border: 1px solid threedshadow;
|
||
|
white-space: nowrap;
|
||
|
overflow-x: scroll;
|
||
|
}
|
||
|
body {
|
||
|
background-color: #ededed;
|
||
|
color: #313739;
|
||
|
font: message-box;
|
||
|
margin: 5em;
|
||
|
}
|
||
|
|
||
|
.log-error {
|
||
|
color: red;
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
.log-highlight {
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
</style>
|
||
|
</head>
|
||
|
|
||
|
<body>
|
||
|
<!-- TODO:
|
||
|
|
||
|
- seek to back properly
|
||
|
- handle seek before front properly
|
||
|
- show red lines for reboots
|
||
|
- show contents of entries -->
|
||
|
|
||
|
<h1 id="title"></h1>
|
||
|
|
||
|
<div id="os"></div>
|
||
|
<div id="virtualization"></div>
|
||
|
<div id="cutoff"></div>
|
||
|
<div id="machine"></div>
|
||
|
<div id="usage"></div>
|
||
|
<div id="showing"></div>
|
||
|
|
||
|
<div id="logs"></div>
|
||
|
|
||
|
<form>
|
||
|
<input id="head" type="button" value="|<" onclick="entriesLoadHead();"/>
|
||
|
<input id="previous" type="button" value="<<" onclick="entriesLoadPrevious();"/>
|
||
|
<input id="next" type="button" value=">>" onclick="entriesLoadNext();"/>
|
||
|
<input id="tail" type="button" value=">|" onclick="entriesLoadTail();"/>
|
||
|
|
||
|
<input id="more" type="button" value="More" onclick="entriesMore();"/>
|
||
|
<input id="less" type="button" value="Less" onclick="entriesLess();"/>
|
||
|
</form>
|
||
|
|
||
|
<script type="text/javascript">
|
||
|
var first_cursor = null;
|
||
|
var last_cursor = null;
|
||
|
|
||
|
function setCookie(name, value, msec) {
|
||
|
var d = new Date();
|
||
|
d.setMilliseconds(d.getMilliseconds() + msec);
|
||
|
var v = escape(value) + "; expires=" + d.toUTCString();
|
||
|
document.cookie = name + "=" + value;
|
||
|
}
|
||
|
|
||
|
function getCookie(name) {
|
||
|
var i, l;
|
||
|
l = document.cookie.split(";");
|
||
|
for (i in l) {
|
||
|
var x, y, j;
|
||
|
j = l[i].indexOf("=");
|
||
|
x = l[i].substr(0, j);
|
||
|
y = l[i].substr(j+1);
|
||
|
if (x == name)
|
||
|
return unescape(y);
|
||
|
}
|
||
|
return null;
|
||
|
}
|
||
|
|
||
|
function getNEntries() {
|
||
|
var n;
|
||
|
n = getCookie("n_entries");
|
||
|
if (n == null)
|
||
|
return 50;
|
||
|
return parseInt(n);
|
||
|
}
|
||
|
|
||
|
function showNEntries(n) {
|
||
|
var showing = document.getElementById("showing");
|
||
|
showing.innerHTML = "Showing <b>" + n.toString() + "</b> entries.";
|
||
|
}
|
||
|
|
||
|
function setNEntries(n) {
|
||
|
if (n < 10)
|
||
|
n = 10;
|
||
|
else if (n > 1000)
|
||
|
n = 1000;
|
||
|
|
||
|
setCookie("n_entries", n.toString(), 30*24*60*60*1000);
|
||
|
showNEntries(n);
|
||
|
}
|
||
|
|
||
|
function machineLoad() {
|
||
|
var request = new XMLHttpRequest();
|
||
|
request.open("GET", "/machine");
|
||
|
request.onreadystatechange = machineOnResult;
|
||
|
request.setRequestHeader("Accept", "application/json");
|
||
|
request.send(null);
|
||
|
}
|
||
|
|
||
|
function formatBytes(u) {
|
||
|
if (u >= 1024*1024*1024*1024)
|
||
|
return (u/1024/1024/1024/1024).toFixed(1) + " TiB";
|
||
|
else if (u >= 1024*1024*1024)
|
||
|
return (u/1024/1024/1024).toFixed(1) + " GiB";
|
||
|
else if (u >= 1024*1024)
|
||
|
return (u/1024/1024).toFixed(1) + " MiB";
|
||
|
else if (u >= 1024)
|
||
|
return (u/1024).toFixed(1) + " KiB";
|
||
|
else
|
||
|
return u.toString() + " B";
|
||
|
}
|
||
|
|
||
|
function machineOnResult(event) {
|
||
|
if ((event.currentTarget.readyState != 4) ||
|
||
|
(event.currentTarget.status != 200 && event.currentTarget.status != 0))
|
||
|
return;
|
||
|
|
||
|
var d = JSON.parse(event.currentTarget.responseText);
|
||
|
|
||
|
var title = document.getElementById("title");
|
||
|
title.innerHTML = 'Journal of ' + d.hostname;
|
||
|
document.title = 'Journal of ' + d.hostname;
|
||
|
|
||
|
var machine = document.getElementById("machine");
|
||
|
machine.innerHTML = 'Machine ID is <b>' + d.machine_id + '</b>, current boot ID is <b>' + d.boot_id + '</b>.';
|
||
|
|
||
|
var cutoff = document.getElementById("cutoff");
|
||
|
var from = new Date(parseInt(d.cutoff_from_realtime) / 1000);
|
||
|
var to = new Date(parseInt(d.cutoff_to_realtime) / 1000);
|
||
|
cutoff.innerHTML = 'Journal begins at <b>' + from.toLocaleString() + '</b> and ends at <b>' + to.toLocaleString() + '</b>.';
|
||
|
|
||
|
var usage = document.getElementById("usage");
|
||
|
usage.innerHTML = 'Disk usage is <b>' + formatBytes(parseInt(d.usage)) + '</b>.';
|
||
|
|
||
|
var os = document.getElementById("os");
|
||
|
os.innerHTML = 'Operating system is <b>' + d.os_pretty_name + '</b>.';
|
||
|
|
||
|
var virtualization = document.getElementById("virtualization");
|
||
|
virtualization.innerHTML = d.virtualization == "bare" ? "Running on <b>bare metal</b>." : "Running on virtualization <b>" + d.virtualization + "</b>.";
|
||
|
}
|
||
|
|
||
|
function entriesLoad(range) {
|
||
|
var request = new XMLHttpRequest();
|
||
|
request.open("GET", "/entries");
|
||
|
request.onreadystatechange = entriesOnResult;
|
||
|
request.setRequestHeader("Accept", "application/json");
|
||
|
request.setRequestHeader("Range", "entries=" + range + ":" + getNEntries().toString());
|
||
|
request.send(null);
|
||
|
}
|
||
|
|
||
|
function entriesLoadNext() {
|
||
|
if (last_cursor == null)
|
||
|
entriesLoad("");
|
||
|
else
|
||
|
entriesLoad(last_cursor + ":1");
|
||
|
}
|
||
|
|
||
|
function entriesLoadPrevious() {
|
||
|
if (first_cursor == null)
|
||
|
entriesLoad("");
|
||
|
else
|
||
|
entriesLoad(first_cursor + ":-" + getNEntries().toString());
|
||
|
}
|
||
|
|
||
|
function entriesLoadHead() {
|
||
|
entriesLoad("");
|
||
|
}
|
||
|
|
||
|
function entriesLoadTail() {
|
||
|
entriesLoad(":-" + getNEntries().toString());
|
||
|
}
|
||
|
|
||
|
function entriesOnResult(event) {
|
||
|
|
||
|
if ((event.currentTarget.readyState != 4) ||
|
||
|
(event.currentTarget.status != 200 && event.currentTarget.status != 0))
|
||
|
return;
|
||
|
|
||
|
var logs = document.getElementById("logs");
|
||
|
logs.innerHTML = "";
|
||
|
|
||
|
var lc = null;
|
||
|
var fc = null;
|
||
|
|
||
|
var i;
|
||
|
var l = event.currentTarget.responseText.split('\n');
|
||
|
|
||
|
if (l.length <= 1) {
|
||
|
logs.innerHTML = "<i>No further entries...</i>";
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (i in l) {
|
||
|
|
||
|
if (l[i] == '')
|
||
|
continue;
|
||
|
|
||
|
var d = JSON.parse(l[i]);
|
||
|
if (d.MESSAGE == undefined || d.__CURSOR == undefined)
|
||
|
continue;
|
||
|
|
||
|
if (fc == null)
|
||
|
fc = d.__CURSOR;
|
||
|
lc = d.__CURSOR;
|
||
|
|
||
|
var priority;
|
||
|
if (d.PRIORITY != undefined)
|
||
|
priority = parseInt(d.PRIORITY);
|
||
|
else
|
||
|
priority = 6;
|
||
|
|
||
|
if (priority <= 3)
|
||
|
clazz = "log-error";
|
||
|
else if (priority <= 5)
|
||
|
clazz = "log-highlight";
|
||
|
else
|
||
|
clazz = "log-normal";
|
||
|
|
||
|
var line = '<div class="' + clazz + '">';
|
||
|
|
||
|
if (d.SYSLOG_IDENTIFIER != undefined)
|
||
|
line += d.SYSLOG_IDENTIFIER;
|
||
|
else if (d._COMM != undefined)
|
||
|
line += d._COMM;
|
||
|
|
||
|
if (d._PID != undefined)
|
||
|
line += "[" + d._PID + "]";
|
||
|
else if (d.SYSLOG_PID != undefined)
|
||
|
line += "[" + d.SYSLOG_PID + "]";
|
||
|
|
||
|
if (d.MESSAGE == null)
|
||
|
line += ": [blob data]</div>";
|
||
|
else if (d.MESSAGE instanceof Array)
|
||
|
line += ": [" + formatBytes(d.MESSAGE.length) + " blob data]</div>";
|
||
|
else
|
||
|
line += ": " + d.MESSAGE + "</div>";
|
||
|
|
||
|
logs.innerHTML += line;
|
||
|
}
|
||
|
|
||
|
if (fc != null)
|
||
|
first_cursor = fc;
|
||
|
if (lc != null)
|
||
|
last_cursor = lc;
|
||
|
}
|
||
|
|
||
|
function entriesMore() {
|
||
|
setNEntries(getNEntries() + 10);
|
||
|
entriesLoad("");
|
||
|
}
|
||
|
|
||
|
function entriesLess() {
|
||
|
setNEntries(getNEntries() - 10);
|
||
|
entriesLoad("");
|
||
|
}
|
||
|
|
||
|
machineLoad();
|
||
|
entriesLoad("");
|
||
|
showNEntries(getNEntries());
|
||
|
</script>
|
||
|
</body>
|
||
|
</html>
|