<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>LogViewer</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css"
rel="stylesheet"
integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl"
crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0"
crossorigin="anonymous"></script>
<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"
integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI="
crossorigin="anonymous"></script>
</head>
<body>
<div class="modal fade" id="loading" tabindex="-1" role="dialog" aria-labelledby="loading"
aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="loadingLongTitle">Looking for log files</h5>
</div>
<div class="modal-body">
<div class="progress">
<div class="progress-bar progress-bar-striped progress-bar-animated" role="progressbar"
aria-valuenow="100" aria-valuemin="0" aria-valuemax="100" style="width: 100%"></div>
</div>
</div>
</div>
</div>
</div>
<select id="selectLog" name: "selectLog">
<option name="0" value="none" selected="selected">Select log</option>
</select>
<select id="filterLog" name: "filterLog">
<option name="0" value="none" selected="selected">No filter</option>
<option name="1" value="info">INFO</option>
<option name="2" value="warn">WARN</option>
<option name="3" value="error">ERROR</option>
<option name="4" value="warnerror">WARN+ERROR</option>
<option name="5" value="debug">DEBUG</option>
<option name="6" value="other">OTHER</option>
</select>
<table id="logs" class="table">
<thead>
<tr>
<th scope="col">Line #</td>
<th scope="col">Type</td>
<th scope="col">Text</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script type="text/javascript">
var DATA = [{
filename: "Log001.log",
log_entries: [{
line: 1,
entry: { Info: "INFO: If you see this" }
},
{
line: 2,
entry: { Error: "ERROR: This has been an error loading the log files" }
}
]
},
{
filename: "Log002.log",
log_entries: [{
line: 1,
entry: { Info: "INFO: Try again once more" }
},
{
line: 2,
entry: { Error: "ERROR: and take a look at the log output in the console" }
},
{
line: 3,
entry: { Debug: "DEBUG: If you encounter the same problem again" }
},
{
line: 4,
entry: { Warn: "WARN: try running the program from a different folder" }
},
{
line: 5,
entry: { Other: "OTHER: or create an issue at https://github.com/cfsamson/rust-logviewer" }
}
]
}
];
async function wait(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
window.onload = async function () {
let document = window.document;
$("#loading").modal({
backdrop: "static",
show: true,
});
$("#loading").modal('show');
let sleep = wait(1000);
let response = await fetch("/logs");
let data = await response.json();
if (data.response === "ok") {
DATA = data.data;
} else {
console.log(`ERROR: ${data.message}`);
}
await sleep;
$("#loading").modal('hide');
dataLoaded();
let filterSelect = document.getElementById("filterLog");
filterSelect.onchange = filterLog;
}
function dataLoaded() {
let files = [...new Set(DATA.map((d) => d.filename))];
let select = document.getElementById("selectLog");
var i = 1;
for (f of files) {
let opt = document.createElement("option");
opt.name = i;
opt.value = f;
let txt = document.createTextNode(f);
opt.appendChild(txt);
select.appendChild(opt);
i++;
}
select.onchange = getLog;
}
function getLog(e) {
console.log(`Getting logs from: ${e.target.value}`);
let val = e.target.value;
if (val === "none") {
return;
}
let log = DATA.find((n) => n.filename === val);
drawData(log.log_entries);
document.getElementById("filterLog").value = "none";
}
function filterLog(e) {
let current_file = document.getElementById("selectLog").value;
if (current_file == "none") {
return;
}
let current_log = DATA.find((n) => n.filename === current_file);
let currentData = current_log.log_entries;
let filter = e.target.value;
console.log(filter);
var filteredData;
switch (filter) {
case "none":
filteredData = currentData;
break;
case "info":
filteredData = filterData("INFO", currentData);
break;
case "warn":
filteredData = filterData("WARN", currentData);
break;
case "error":
filteredData = filterData("ERROR", currentData);
break;
case "debug":
filteredData = filterData("DEBUG", currentData);
break;
case "other":
filteredData = filterData("OTHER", currentData);
break;
case "warnerror":
filteredData = filterData("WARN+ERROR", currentData);
break;
default:
throw new Error("Invalid filter option")
}
drawData(filteredData)
}
function filterData(filter, c_data) {
console.log(`filterData: ${filter}`);
switch (filter) {
case "INFO":
return c_data.filter((n) => n.entry.Info ? true : false)
case "WARN":
return c_data.filter((n) => n.entry.Warn ? true : false)
case "ERROR":
return c_data.filter((n) => n.entry.Error ? true : false)
case "DEBUG":
return c_data.filter((n) => n.entry.Debug ? true : false)
case "OTHER":
return c_data.filter((n) => n.entry.Other ? true : false)
case "WARN+ERROR":
return c_data.filter((n) => {
let is_warn = n.entry.Warn ? true : false;
let is_err = n.entry.Error ? true : false;
return is_warn || is_err;
})
default:
console.log("ERROR: Invalid filter")
return []
}
}
function drawData(data) {
let table = document.getElementById("logs");
let tbody = table.getElementsByTagName("tbody")[0];
let c_nodescount = tbody.childElementCount;
for (i = 0; i < c_nodescount; i++) {
tbody.removeChild(tbody.lastChild);
}
for (d of data) {
var row_class = "";
var str_content = "";
var type = "";
if (d.entry.Info) {
row_class = "";
str_content = d.entry.Info;
type = "INFO";
} else if (d.entry.Error) {
row_class = "table-danger";
str_content = d.entry.Error;
type = "ERROR";
} else if (d.entry.Warn) {
row_class = "table-warning";
str_content = d.entry.Warn;
type = "WARN";
} else if (d.entry.Debug) {
row_class = "";
str_content = d.entry.Debug;
type = "DEBUG";
} else if (d.entry.Other) {
row_class = "";
str_content = d.entry.Other;
type = "OTHER";
} else {
console.log(`"ERROR: Unspecified type: ${d.entry}`)
continue;
}
let tr = document.createElement("tr");
tr.className = row_class;
var td = document.createElement("td");
var td_txt = document.createTextNode(d.line);
td.appendChild(td_txt);
tr.appendChild(td);
var td = document.createElement("td");
var td_txt = document.createTextNode(type);
td.appendChild(td_txt);
tr.appendChild(td);
var td = document.createElement("td");
var td_txt = document.createTextNode(str_content);
td.appendChild(td_txt);
tr.appendChild(td);
tbody.appendChild(tr);
}
}
</script>
</body>
</html>