Add log window

This commit is contained in:
Ryan Huffman 2016-01-08 11:13:03 -08:00
parent 72f5320942
commit 8113c46df5
3 changed files with 329 additions and 39 deletions

28
console/src/log.html Normal file
View file

@ -0,0 +1,28 @@
<!DOCTYPE html>
<html>
<head>
<title>Log</title>
<script src="log.js"></script>
<link rel="stylesheet" type="text/css" href="log.css"></link>
</head>
<body onload="ready()">
<div class="search">
<input id="search-input" placeholder="filter" />
</div>
<ul class="tabs top">
<li class="tab-link current" data-tab="domain-server">Domain Server</li>
<li class="tab-link" data-tab="assignment-client">Assignment Clients</li>
</ul>
<div class="tab-content middle">
<div class="tab-pane" id="domain-server">
</div>
<div class="tab-pane" id="assignment-client">
<div>
</div>
</div>
</div>
</body>
</html>

265
console/src/log.js Normal file
View file

@ -0,0 +1,265 @@
var remote = require('electron').remote;
var os = require('os');
var Tail = require('always-tail');
function cleanPath(path) {
if (os.type() == "Windows_NT") {
// Fix path on Windows
while (path.indexOf('\\') >= 0) {
path = path.replace('\\', '/', 'g');
}
}
return path;
}
ready = function() {
window.$ = require('./vendor/jquery/jquery-2.1.4.min.js');
console.log(remote.debug);
var domainServer = remote.getGlobal('domainServer');
var acMonitor = remote.getGlobal('acMonitor');
var logFiles = {
'ds': {
},
'ac': {
}
};
function updateLogFiles() {
var dsLogs = domainServer.getLogs();
var acLogs = acMonitor.getLogs();
// Update ds logs
var dsLogFilePaths = [];
for (var pid in dsLogs) {
dsLogFilePaths.push(dsLogs[pid].stdout);
dsLogFilePaths.push(dsLogs[pid].stderr);
}
console.log(dsLogFilePaths);
console.log(dsLogs);
var dsFilePaths = Object.keys(logFiles.ds);
for (const filePath of dsFilePaths) {
if (dsLogFilePaths.indexOf(filePath) == -1) {
// This file is no longer being used, let's stop watching it
// and remove it from our list.
logFiles.ds[filePath].unwatch();
delete logFiles[filePath];
}
}
dsLogFilePaths.forEach(function(filePath) {
if (logFiles.ds[filePath] === undefined) {
var cleanFilePath = cleanPath(filePath);
var logTail = new Tail(cleanFilePath, '\n', { start: 0, interval: 500 });
logTail.on('line', function(msg) {
console.log('msg', msg, 'ds');
appendLogMessage(0, msg, 'ds');
});
logTail.on('error', function(error) {
console.log("ERROR:", error);
});
logTail.watch();
logFiles.ds[filePath] = logTail;
console.log("Watching", cleanFilePath);
}
});
// Update ac logs
var acLogFilePaths = [];
for (var pid in acLogs) {
acLogFilePaths.push(acLogs[pid].stdout);
acLogFilePaths.push(acLogs[pid].stderr);
}
console.log(acLogFilePaths);
console.log(acLogs);
var acFilePaths = Object.keys(logFiles.ac);
for (filePath of acFilePaths) {
if (acLogFilePaths.indexOf(filePath) == -1) {
// This file is no longer being used, let's stop watching it
// and remove it from our list.
logFiles.ac[filePath].unwatch();
delete logFiles[filePath];
}
}
acLogFilePaths.forEach(function(filePath) {
if (logFiles.ac[filePath] === undefined) {
var cleanFilePath = cleanPath(filePath);
var fs = require('fs');
var stats = fs.statSync(cleanFilePath);
var size = stats.size;
var start = Math.max(0, size - (2500 * 50));
console.log(cleanFilePath, size, start, maxLogLines);
var logTail = new Tail(cleanFilePath, '\n', { start: start, interval: 500 });
logTail.on('line', function(msg) {
console.log('msg', msg, 'ac');
appendLogMessage(0, msg, 'ac');
});
logTail.on('error', function(error) {
console.log("ERROR:", error);
});
logTail.watch();
logFiles.ac[filePath] = logTail;
console.log("Watching", cleanFilePath);
}
});
console.log(dsLogs, acLogs);
}
window.onbeforeunload = function(e) {
domainServer.removeListener('logs-updated', updateLogFiles);
acMonitor.removeListener('logs-updated', updateLogFiles);
};
domainServer.on('logs-updated', updateLogFiles);
acMonitor.on('logs-updated', updateLogFiles);
updateLogFiles();
const maxLogLines = 2500;
const ipcRenderer = require('electron').ipcRenderer;
var currentTab = 'domain-server';
var tabStates = {
'domain-server': {
atBottom: true,
size: 0
},
'assignment-client': {
atBottom: true,
size: 0
}
};
function setCurrentTab(tabId) {
if (currentTab == tabId) {
return;
}
var padding = 15;
$currentTab = $('#' + currentTab);
tabStates[currentTab].atBottom = $currentTab[0].scrollTop >= ($currentTab[0].scrollHeight - $currentTab.height() - (2 * padding));
currentTab = tabId;
$('ul.tabs li').removeClass('current');
$('.tab-pane').removeClass('current');
$('li[data-tab=' + tabId + ']').addClass('current');
var $pidLog = $("#" + tabId);
$pidLog.addClass('current');
if (tabStates[tabId].atBottom) {
$pidLog.scrollTop($pidLog[0].scrollHeight);
}
}
$('ul.tabs li').click(function(){
setCurrentTab($(this).attr('data-tab'));
});
setCurrentTab('domain-server');
setCurrentTab('assignment-client');
var filter = "";
var times = {};
var t = null;
function start() {
t = Date.now();
}
function stop(name) {
if (!(name in times)) times[name] = 0;
times[name] += (Date.now() - t);
}
function printTimes() {
for (var k in times) {
console.log(k, times[k] / 1000, 's');
}
}
// Register for log events
// Process added
function shouldDisplayLogMessage(message) {
return !filter || message.toLowerCase().indexOf(filter) >= 0;
}
function appendLogMessage(pid, msg, name) {
console.log(pid, msg, name);
start();
var id = "pid-" + pid;
id = name == "ds" ? "domain-server" : "assignment-client";
var $pidLog = $('#' + id);
stop('acquire');
start();
// var $logLines = $pidLog.children();
// var removed = false;
var size = ++tabStates[id].size;
stop('get size');
start();
if (size > maxLogLines) {
// $logLines.first().remove();
$pidLog.find('div.log-line:first').remove();
removed = true;
}
stop('remove first');
start();
var wasAtBottom = false;
if (currentTab == id) {
var padding = 15;
wasAtBottom = $pidLog[0].scrollTop >= ($pidLog[0].scrollHeight - $pidLog.height() - (2 * padding));
}
stop('scrollCheck');
start();
var $logLine = $('<div class="log-line">').text(msg);
stop('create');
if (!shouldDisplayLogMessage(msg)) {
$logLine.hide();
}
start();
$pidLog.append($logLine);
stop('append');
start();
if (wasAtBottom) {
$pidLog.scrollTop($pidLog[0].scrollHeight);
}
stop('scroll');
}
// handle filtering of table rows on input change
$('#search-input').on('input', function() {
filter = $(this).val().toLowerCase();
if (filter == "") {
$('.log-line').show();
} else {
$('.log-line').each(function(){
// decide to hide or show the row if it matches the filter
if (filter && $(this).text().toLowerCase().indexOf(filter) == -1) {
$(this).hide();
} else {
$(this).show();
}
});
}
});
setInterval(printTimes, 10000);
};

View file

@ -144,46 +144,41 @@ const RESTART_INDEX = 3;
const STOP_INDEX = 4;
const SETTINGS_INDEX = 5;
function buildMenuArray(serverState) {
var menuArray = [
{
label: 'Go Home',
click: function() { startInterface('hifi://localhost'); },
enabled: false
},
{
type: 'separator'
},
{
label: "Server - Stopped",
enabled: false
},
{
label: "Start",
click: function() { homeServer.restart(); }
},
{
label: "Stop",
visible: false,
click: function() { homeServer.stop(); }
},
{
label: "Settings",
click: function() { shell.openExternal('http://localhost:40100/settings'); },
enabled: false
},
{
label: "View Logs",
click: function() { openFileBrowser(logPath); }
},
{
type: 'separator'
},
{
label: 'Quit',
accelerator: 'Command+Q',
click: function() { app.quit(); }
var LogWindow = function(ac, ds) {
this.ac = ac;
this.ds = ds;
this.window = null;
this.acMonitor = null;
this.dsMonitor = null;
}
LogWindow.prototype = {
open: function() {
if (this.window) {
this.window.show();
this.window.restore();
return;
}
// Create the browser window.
this.window = new BrowserWindow({ width: 700, height: 500, icon: APP_ICON });
this.window.loadURL('file://' + __dirname + '/log.html');
if (!debug) {
logWindow.setMenu(null);
}
this.window.on('closed', function() {
this.window = null;
}.bind(this));
},
close: function() {
if (this.window) {
this.window.close();
}
}
};
var logWindow = null;
function buildMenuArray(serverState) {
var menuArray = null;
if (isShuttingDown) {
@ -312,6 +307,8 @@ app.on('ready', function() {
// make sure we stop child processes on app quit
app.on('quit', function(){
console.log('App quitting');
logWindow.close();
homeServer.stop();
});