From 5da948d634ba18a01a46abcce45008379a74d4aa Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Dec 2015 15:16:20 -0800 Subject: [PATCH 01/12] Add proper shutdown and state handling to ProcessGroup --- console/modules/hf-process.js | 50 ++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/console/modules/hf-process.js b/console/modules/hf-process.js index bc018ed982..d906d3058b 100755 --- a/console/modules/hf-process.js +++ b/console/modules/hf-process.js @@ -5,6 +5,12 @@ var util = require('util'); var events = require('events'); var childProcess = require('child_process'); +const ProcessGroupStates = { + STOPPED: 'stopped', + STARTED: 'started', + STOPPING: 'stopping' +}; + const ProcessStates = { STOPPED: 'stopped', STARTED: 'started', @@ -12,23 +18,58 @@ const ProcessStates = { }; function ProcessGroup(name, processes) { + events.EventEmitter.call(this); + this.name = name; - this.processes = processes; + this.state = ProcessGroupStates.STOPPED; + this.processes = []; + + for (let process of processes) { + this.addProcess(process); + } }; util.inherits(ProcessGroup, events.EventEmitter); ProcessGroup.prototype = extend(ProcessGroup.prototype, { addProcess: function(process) { this.processes.push(process); + process.on('state-update', this.onProcessStateUpdate.bind(this)); }, start: function() { + if (this.state != ProcessGroupStates.STOPPED) { + console.warn("Can't start process group that is not stopped."); + return; + } + for (let process of this.processes) { process.start(); } + + this.state = ProcessGroupStates.STARTED; }, stop: function() { + if (this.state != ProcessGroupStates.STARTED) { + console.warn("Can't stop process group that is not started."); + return; + } for (let process of this.processes) { process.stop(); } + this.state = ProcessGroupStates.STOPPING; + }, + + // Event handlers + onProcessStateUpdate: function(process) { + var processesStillRunning = false; + for (let process of this.processes) { + if (process.state != ProcessStates.STOPPED) { + processesStillRunning = true; + break; + } + } + if (!processesStillRunning) { + this.state = ProcessGroupStates.STOPPED; + } + this.emit('state-update', this, process); } }); @@ -36,6 +77,7 @@ var ID = 0; function Process(name, command, commandArgs) { events.EventEmitter.call(this); + this.blah = 'adsf'; this.id = ++ID; this.name = name; this.command = command; @@ -67,7 +109,7 @@ Process.prototype = extend(Process.prototype, { this.state = ProcessStates.STOPPED; } - this.emit('state-update'); + this.emit('state-update', this); }, stop: function() { if (this.state != ProcessStates.STARTED) { @@ -82,12 +124,12 @@ Process.prototype = extend(Process.prototype, { onChildStartError: function(error) { console.log("Child process error ", error); this.state = ProcessStates.STOPPED; - this.emit('state-update'); + this.emit('state-update', this); }, onChildClose: function(code) { console.log("Child process closed with code ", code); this.state = ProcessStates.STOPPED; - this.emit('state-update'); + this.emit('state-update', this); } }); From 1a55cad1b0824d9998c0e6b638c187a1f1eb0b16 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Dec 2015 15:16:44 -0800 Subject: [PATCH 02/12] Add server start/stop --- console/index.html | 9 +++++++-- console/index.js | 27 +++++++++++++++++---------- console/main.js | 9 ++++++++- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/console/index.html b/console/index.html index cf73d09c05..a8684c0e6b 100644 --- a/console/index.html +++ b/console/index.html @@ -6,7 +6,7 @@ -

Console

+

High Fidelity

Interface

@@ -19,7 +19,12 @@

Home

-
+
+
+ unknown + + +
diff --git a/console/index.js b/console/index.js index 1960c35681..aa12a07370 100755 --- a/console/index.js +++ b/console/index.js @@ -6,16 +6,17 @@ ready = function() { function onProcessUpdate(event, arg) { // Update interface console.log("update", event, arg); - var state = arg.interface.state; - $('#process-interface .status').text(state); - var on = state != 'stopped'; - if (on) { - $('#process-interface .power-on').hide(); - $('#process-interface .power-off').show(); - } else { - $('#process-interface .power-on').show(); - $('#process-interface .power-off').hide(); - } + var interfaceState = arg.interface.state; + $('#process-interface .status').text(interfaceState); + var interfaceOn = interfaceState != 'stopped'; + $('#process-interface .power-on').prop('disabled', interfaceOn); + $('#process-interface .power-off').prop('disabled', !interfaceOn); + + var serverState = arg.home.state; + $('#server .status').text(serverState); + var serverOn = serverState != 'stopped'; + $('#server .power-on').prop('disabled', serverOn); + $('#server .power-off').prop('disabled', !serverOn); } $('#process-interface .power-on').click(function() { @@ -24,6 +25,12 @@ ready = function() { $('#process-interface .power-off').click(function() { ipcRenderer.send('stop-process', { name: 'interface' }); }); + $('#server .power-on').click(function() { + ipcRenderer.send('start-server', { name: 'home' }); + }); + $('#server .power-off').click(function() { + ipcRenderer.send('stop-server', { name: 'home' }); + }); ipcRenderer.on('process-update', onProcessUpdate); diff --git a/console/main.js b/console/main.js index 5922f78a1e..f1f4550d8e 100644 --- a/console/main.js +++ b/console/main.js @@ -87,6 +87,7 @@ app.on('ready', function() { }; pInterface.on('state-update', sendProcessUpdate); + homeServer.on('state-update', sendProcessUpdate); ipcMain.on('start-process', function(event, arg) { pInterface.start(); @@ -96,9 +97,15 @@ app.on('ready', function() { pInterface.stop(); sendProcessUpdate(); }); - ipcMain.on('update', function(event, arg) { + ipcMain.on('start-server', function(event, arg) { + homeServer.start(); sendProcessUpdate(); }); + ipcMain.on('stop-server', function(event, arg) { + homeServer.stop(); + sendProcessUpdate(); + }); + ipcMain.on('update', sendProcessUpdate); sendProcessUpdate(); }); From 5a7a35893f8b2514ce2a3d67343de6a67d33d77e Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Dec 2015 16:14:10 -0800 Subject: [PATCH 03/12] Add link to server settings --- console/index.html | 1 + console/main.js | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/console/index.html b/console/index.html index a8684c0e6b..1d088cf01d 100644 --- a/console/index.html +++ b/console/index.html @@ -24,6 +24,7 @@ unknown + Settings
diff --git a/console/main.js b/console/main.js index f1f4550d8e..e17c269a4b 100644 --- a/console/main.js +++ b/console/main.js @@ -5,6 +5,7 @@ var app = electron.app; // Module to control application life. var BrowserWindow = require('browser-window'); // Module to create native browser window. var Menu = require('menu'); var Tray = require('tray'); +var shell = require('shell'). var hfprocess = require('./modules/hf-process.js'); var Process = hfprocess.Process; @@ -61,6 +62,12 @@ app.on('ready', function() { mainWindow = null; }); + // When a link is clicked that has `_target="_blank"`, open it in the user's native browser + mainWindow.webContents.on('new-window', function(e, url) { + e.preventDefault(); + shell.openExternal(url); + }); + var pInterface = new Process('interface', 'C:\\Interface\\interface.exe'); var domainServerPath = 'C:\\Users\\Ryan\\AppData\\Local\\High Fidelity\\Stack Manager\\domain-server.exe'; From e0a9a2cca18853ad456a734e212a94ac04ad9ab1 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Dec 2015 16:14:29 -0800 Subject: [PATCH 04/12] Remove crash reporter --- console/main.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/console/main.js b/console/main.js index e17c269a4b..f9f317e7f7 100644 --- a/console/main.js +++ b/console/main.js @@ -13,9 +13,6 @@ var ProcessGroup = hfprocess.ProcessGroup; const ipcMain = electron.ipcMain; -// Report crashes to our server. -require('crash-reporter').start(); - // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garggbage collected. var mainWindow = null; From dce99579835876753e47415a92bdc5304a518f20 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Dec 2015 16:14:40 -0800 Subject: [PATCH 05/12] Fix typo --- console/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/main.js b/console/main.js index f9f317e7f7..ee79c434e0 100644 --- a/console/main.js +++ b/console/main.js @@ -14,7 +14,7 @@ var ProcessGroup = hfprocess.ProcessGroup; const ipcMain = electron.ipcMain; // Keep a global reference of the window object, if you don't, the window will -// be closed automatically when the JavaScript object is garggbage collected. +// be closed automatically when the JavaScript object is garbage collected. var mainWindow = null; var appIcon = null; var TRAY_ICON = 'resources/tray-icon.png'; From d1d68b7a268beb846bff6db3724586ad86c95d3d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Dec 2015 16:15:05 -0800 Subject: [PATCH 06/12] Add logging to console --- console/main.js | 13 +++++++------ console/modules/hf-process.js | 20 ++++++++++++++++++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/console/main.js b/console/main.js index ee79c434e0..95180736bc 100644 --- a/console/main.js +++ b/console/main.js @@ -71,12 +71,13 @@ app.on('ready', function() { var acPath = 'C:\\Users\\Ryan\\AppData\\Local\\High Fidelity\\Stack Manager\\assignment-client.exe'; var homeServer = new ProcessGroup('home', [ - new Process('Domain Server', domainServerPath), - new Process('AC - Audio', acPath, ['-t0']), - new Process('AC - Avatar', acPath, ['-t1']), - new Process('AC - Asset', acPath, ['-t3']), - new Process('AC - Messages', acPath, ['-t4']), - new Process('AC - Entity', acPath, ['-t6']) + new Process('domain_server', domainServerPath), + new Process('ac_audio', acPath, ['-t0']), + new Process('ac_avatar', acPath, ['-t1']), + new Process('ac_agent', acPath, ['-t2']), + new Process('ac_asset', acPath, ['-t3']), + new Process('ac_messages', acPath, ['-t4']), + new Process('ac_entity', acPath, ['-t6']) ]); homeServer.start(); diff --git a/console/modules/hf-process.js b/console/modules/hf-process.js index d906d3058b..638f61cb2a 100755 --- a/console/modules/hf-process.js +++ b/console/modules/hf-process.js @@ -4,6 +4,7 @@ var extend = require('extend'); var util = require('util'); var events = require('events'); var childProcess = require('child_process'); +var fs = require('fs'); const ProcessGroupStates = { STOPPED: 'stopped', @@ -95,10 +96,25 @@ Process.prototype = extend(Process.prototype, { } console.log("Starting " + this.command); try { + var time = (new Date).getTime(); + console.log('time', time); + var tmpLogStdout = './logs/' + this.name + "-" + time + "-stdout.txt"; + var tmpLogStderr = './logs/' + this.name + "-" + time + "-stderr.txt"; + + var logStdout = fs.openSync(tmpLogStdout, 'ax'); + var logStderr = fs.openSync(tmpLogStderr, 'ax'); + this.child = childProcess.spawn(this.command, this.commandArgs, { - detached: false + detached: false, + stdio: ['ignore', logStdout, logStderr] }); - //console.log("started ", this.child); + + var pidLogStdout = './logs/' + this.name + "-" + this.child.pid + "-stdout.txt"; + var pidLogStderr = './logs/' + this.name + "-" + this.child.pid + "-stderr.txt"; + + fs.rename(tmpLogStdout, pidLogStdout, function(e) { }); + fs.rename(tmpLogStderr, pidLogStderr, function(e) { }); + this.child.on('error', this.onChildStartError.bind(this)); this.child.on('close', this.onChildClose.bind(this)); this.state = ProcessStates.STARTED; From 7819d8faae6ac74dd02b670b37b05f3c27cbe881 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Dec 2015 16:46:15 -0800 Subject: [PATCH 07/12] Fix syntax error in console --- console/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/main.js b/console/main.js index 95180736bc..5bb0c5713c 100644 --- a/console/main.js +++ b/console/main.js @@ -5,7 +5,7 @@ var app = electron.app; // Module to control application life. var BrowserWindow = require('browser-window'); // Module to create native browser window. var Menu = require('menu'); var Tray = require('tray'); -var shell = require('shell'). +var shell = require('shell'); var hfprocess = require('./modules/hf-process.js'); var Process = hfprocess.Process; From df3e61c24dfa8788dc98d0ea188de29b4a784362 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 3 Dec 2015 16:46:32 -0800 Subject: [PATCH 08/12] Add error handling to process logging --- console/modules/hf-process.js | 72 +++++++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 16 deletions(-) diff --git a/console/modules/hf-process.js b/console/modules/hf-process.js index 638f61cb2a..2ee5f26aba 100755 --- a/console/modules/hf-process.js +++ b/console/modules/hf-process.js @@ -95,36 +95,76 @@ Process.prototype = extend(Process.prototype, { return; } console.log("Starting " + this.command); + + var logDirectoryCreated = false; try { + fs.mkdirSync('logs'); + logDirectoryCreated = true; + } catch (e) { + if (e.code == 'EEXIST') { + logDirectoryCreated = true; + } else { + console.error("Error creating log directory"); + } + } + + var logStdout = 'ignore', + logStderr = 'ignore'; + + if (logDirectoryCreated) { + // Create a temporary file with the current time var time = (new Date).getTime(); - console.log('time', time); - var tmpLogStdout = './logs/' + this.name + "-" + time + "-stdout.txt"; - var tmpLogStderr = './logs/' + this.name + "-" + time + "-stderr.txt"; + var tmpLogStdout = './logs/' + this.name + '-' + time + '-stdout.txt'; + var tmpLogStderr = './logs/' + this.name + '-' + time + '-stderr.txt'; - var logStdout = fs.openSync(tmpLogStdout, 'ax'); - var logStderr = fs.openSync(tmpLogStderr, 'ax'); + try { + logStdout = fs.openSync(tmpLogStdout, 'ax'); + } catch(e) { + console.log("Error creating stdout log file", e); + logStdout = 'ignore'; + } + try { + logStderr = fs.openSync(tmpLogStderr, 'ax'); + } catch(e) { + console.log("Error creating stderr log file", e); + logStderr = 'ignore'; + } + } + try { this.child = childProcess.spawn(this.command, this.commandArgs, { detached: false, stdio: ['ignore', logStdout, logStderr] }); - - var pidLogStdout = './logs/' + this.name + "-" + this.child.pid + "-stdout.txt"; - var pidLogStderr = './logs/' + this.name + "-" + this.child.pid + "-stderr.txt"; - - fs.rename(tmpLogStdout, pidLogStdout, function(e) { }); - fs.rename(tmpLogStderr, pidLogStderr, function(e) { }); - - this.child.on('error', this.onChildStartError.bind(this)); - this.child.on('close', this.onChildClose.bind(this)); - this.state = ProcessStates.STARTED; - console.log("Child process started"); } catch (e) { console.log("Got error starting child process for " + this.name, e); this.child = null; this.state = ProcessStates.STOPPED; } + if (logStdout != 'ignore') { + var pidLogStdout = './logs/' + this.name + "-" + this.child.pid + "-" + time + "-stdout.txt"; + fs.rename(tmpLogStdout, pidLogStdout, function(e) { + if (e !== null) { + console.log("Error renaming log file from " + tmpLogStdout + " to " + pidLogStdout, e); + } + }); + } + + if (logStderr != 'ignore') { + var pidLogStderr = './logs/' + this.name + "-" + this.child.pid + "-" + time + "-stderr.txt"; + fs.rename(tmpLogStderr, pidLogStderr, function(e) { + if (e !== null) { + console.log("Error renaming log file from " + tmpLogStdout + " to " + pidLogStdout, e); + } + }); + } + + this.child.on('error', this.onChildStartError.bind(this)); + this.child.on('close', this.onChildClose.bind(this)); + this.state = ProcessStates.STARTED; + console.log("Child process started"); + this.emit('state-update', this); }, stop: function() { From 195f58e130a93cffb5feb5907137b48e26bf348d Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Dec 2015 08:51:13 -0800 Subject: [PATCH 09/12] Add log-directory option to AC monitor --- assignment-client/src/AssignmentClientApp.cpp | 14 +++++++++++++- assignment-client/src/AssignmentClientApp.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/AssignmentClientApp.cpp b/assignment-client/src/AssignmentClientApp.cpp index cddce5de7d..9d5e8843d0 100644 --- a/assignment-client/src/AssignmentClientApp.cpp +++ b/assignment-client/src/AssignmentClientApp.cpp @@ -22,6 +22,8 @@ #include "AssignmentClient.h" #include "AssignmentClientMonitor.h" #include "AssignmentClientApp.h" +#include +#include AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : @@ -92,6 +94,9 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : const QCommandLineOption monitorPortOption(ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION, "assignment-client monitor port", "port"); parser.addOption(monitorPortOption); + const QCommandLineOption logDirectoryOption(ASSIGNMENT_LOG_DIRECTORY, "directory to store logs", "log-directory"); + parser.addOption(logDirectoryOption); + if (!parser.parse(QCoreApplication::arguments())) { qCritical() << parser.errorText() << endl; parser.showHelp(); @@ -130,6 +135,13 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : numForks = minForks; } + QDir logDirectory { "." }; + if (parser.isSet(logDirectoryOption)) { + logDirectory = parser.value(logDirectoryOption); + } else { + logDirectory = QStandardPaths::writableLocation(QStandardPaths::DataLocation); + } + Assignment::Type requestAssignmentType = Assignment::AllTypes; if (argumentVariantMap.contains(ASSIGNMENT_TYPE_OVERRIDE_OPTION)) { requestAssignmentType = (Assignment::Type) argumentVariantMap.value(ASSIGNMENT_TYPE_OVERRIDE_OPTION).toInt(); @@ -200,7 +212,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) : AssignmentClientMonitor* monitor = new AssignmentClientMonitor(numForks, minForks, maxForks, requestAssignmentType, assignmentPool, listenPort, walletUUID, assignmentServerHostname, - assignmentServerPort); + assignmentServerPort, logDirectory); monitor->setParent(this); connect(this, &QCoreApplication::aboutToQuit, monitor, &AssignmentClientMonitor::aboutToQuit); } else { diff --git a/assignment-client/src/AssignmentClientApp.h b/assignment-client/src/AssignmentClientApp.h index c4705e30eb..b99b442bbb 100644 --- a/assignment-client/src/AssignmentClientApp.h +++ b/assignment-client/src/AssignmentClientApp.h @@ -25,6 +25,7 @@ const QString ASSIGNMENT_NUM_FORKS_OPTION = "n"; const QString ASSIGNMENT_MIN_FORKS_OPTION = "min"; const QString ASSIGNMENT_MAX_FORKS_OPTION = "max"; const QString ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION = "monitor-port"; +const QString ASSIGNMENT_LOG_DIRECTORY = "log-directory"; class AssignmentClientApp : public QCoreApplication { Q_OBJECT From b907a04a3f1c7a931871623a8522cbf87986ae61 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Dec 2015 09:08:51 -0800 Subject: [PATCH 10/12] Add log directory to AssignmentClientMonitor --- .../src/AssignmentClientMonitor.cpp | 47 ++++++++++++++++++- .../src/AssignmentClientMonitor.h | 5 +- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/AssignmentClientMonitor.cpp b/assignment-client/src/AssignmentClientMonitor.cpp index 2d27962071..bb70c8464f 100644 --- a/assignment-client/src/AssignmentClientMonitor.cpp +++ b/assignment-client/src/AssignmentClientMonitor.cpp @@ -12,6 +12,9 @@ #include #include +#include +#include + #include #include #include @@ -29,7 +32,7 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen const unsigned int maxAssignmentClientForks, Assignment::Type requestAssignmentType, QString assignmentPool, quint16 listenPort, QUuid walletUUID, QString assignmentServerHostname, - quint16 assignmentServerPort) : + quint16 assignmentServerPort, QDir logDirectory) : _numAssignmentClientForks(numAssignmentClientForks), _minAssignmentClientForks(minAssignmentClientForks), _maxAssignmentClientForks(maxAssignmentClientForks), @@ -37,7 +40,8 @@ AssignmentClientMonitor::AssignmentClientMonitor(const unsigned int numAssignmen _assignmentPool(assignmentPool), _walletUUID(walletUUID), _assignmentServerHostname(assignmentServerHostname), - _assignmentServerPort(assignmentServerPort) + _assignmentServerPort(assignmentServerPort), + _logDirectory(logDirectory) { qDebug() << "_requestAssignmentType =" << _requestAssignmentType; @@ -155,11 +159,50 @@ void AssignmentClientMonitor::spawnChildClient() { _childArguments.append("--" + ASSIGNMENT_CLIENT_MONITOR_PORT_OPTION); _childArguments.append(QString::number(DependencyManager::get()->getLocalSockAddr().getPort())); + // Setup log files + const QString DATETIME_FORMAT = "yyyyMMdd.hh.mm.ss.zzz"; + + if (!_logDirectory.exists()) { + qDebug() << "Log directory (" << _logDirectory.absolutePath() << ") does not exist, creating."; + _logDirectory.mkpath(_logDirectory.absolutePath()); + } + + auto nowString = QDateTime::currentDateTime().toString(DATETIME_FORMAT); + auto stdoutFilenameTemp = QString("ac_stdout_%1.txt").arg(nowString); + auto stderrFilenameTemp = QString("ac_stderr_%1.txt").arg(nowString); + QString stdoutPathTemp = _logDirectory.absoluteFilePath(stdoutFilenameTemp); + QString stderrPathTemp = _logDirectory.absoluteFilePath(stderrFilenameTemp); + + // reset our output and error files + assignmentClient->setStandardOutputFile(stdoutPathTemp); + assignmentClient->setStandardErrorFile(stderrPathTemp); + // make sure that the output from the child process appears in our output assignmentClient->setProcessChannelMode(QProcess::ForwardedChannels); assignmentClient->start(QCoreApplication::applicationFilePath(), _childArguments); + + // Update log path to use PID in filename + auto stdoutFilename = QString("ac_stdout_%1_%2.txt").arg(nowString).arg(assignmentClient->processId()); + auto stderrFilename = QString("ac_stderr_%1_%2.txt").arg(nowString).arg(assignmentClient->processId()); + QString stdoutPath = _logDirectory.absoluteFilePath(stdoutFilename); + QString stderrPath = _logDirectory.absoluteFilePath(stderrFilename); + + qDebug() << "Renaming " << stdoutPathTemp << " to " << stdoutPath; + if (!_logDirectory.rename(stdoutFilenameTemp, stdoutFilename)) { + qDebug() << "Failed to rename " << stdoutFilenameTemp; + stdoutFilename = stdoutFilenameTemp; + } + + qDebug() << "Renaming " << stderrPathTemp << " to " << stderrPath; + if (!QFile::rename(stderrPathTemp, stderrPath)) { + qDebug() << "Failed to rename " << stderrFilenameTemp; + stderrFilename = stderrFilenameTemp; + } + qDebug() << "Child stdout being written to: " << stdoutPathTemp; + qDebug() << "Child stderr being written to: " << stderrPathTemp; + if (assignmentClient->processId() > 0) { // make sure we hear that this process has finished when it does connect(assignmentClient, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(childProcessFinished())); diff --git a/assignment-client/src/AssignmentClientMonitor.h b/assignment-client/src/AssignmentClientMonitor.h index 7ea7c3e274..27ef3e7cab 100644 --- a/assignment-client/src/AssignmentClientMonitor.h +++ b/assignment-client/src/AssignmentClientMonitor.h @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -29,7 +30,7 @@ public: AssignmentClientMonitor(const unsigned int numAssignmentClientForks, const unsigned int minAssignmentClientForks, const unsigned int maxAssignmentClientForks, Assignment::Type requestAssignmentType, QString assignmentPool, quint16 listenPort, QUuid walletUUID, QString assignmentServerHostname, - quint16 assignmentServerPort); + quint16 assignmentServerPort, QDir logDirectory); ~AssignmentClientMonitor(); void stopChildProcesses(); @@ -47,6 +48,8 @@ private: QTimer _checkSparesTimer; // every few seconds see if it need fewer or more spare children + QDir _logDirectory; + const unsigned int _numAssignmentClientForks; const unsigned int _minAssignmentClientForks; const unsigned int _maxAssignmentClientForks; From 5bdea485fc6c40a394a8a5f8db068142f9e45eca Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Dec 2015 09:11:24 -0800 Subject: [PATCH 11/12] Add log opening to console --- console/index.html | 1 + console/index.js | 3 +++ console/main.js | 26 ++++++++++++++++++++------ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/console/index.html b/console/index.html index 1d088cf01d..45205985ab 100644 --- a/console/index.html +++ b/console/index.html @@ -25,6 +25,7 @@ Settings + Open log directory diff --git a/console/index.js b/console/index.js index aa12a07370..8f6fa239f1 100755 --- a/console/index.js +++ b/console/index.js @@ -31,6 +31,9 @@ ready = function() { $('#server .power-off').click(function() { ipcRenderer.send('stop-server', { name: 'home' }); }); + $('#open-logs').click(function() { + ipcRenderer.send('open-logs'); + }); ipcRenderer.on('process-update', onProcessUpdate); diff --git a/console/main.js b/console/main.js index 6655f8a15f..7cc0e6090a 100644 --- a/console/main.js +++ b/console/main.js @@ -6,6 +6,9 @@ var BrowserWindow = require('browser-window'); // Module to create native brows var Menu = require('menu'); var Tray = require('tray'); var shell = require('shell'); +var os = require('os'); +var childProcess = require('child_process'); +var path = require('path'); var hfprocess = require('./modules/hf-process.js'); var Process = hfprocess.Process; @@ -43,6 +46,17 @@ if (argv.localDebugBuilds || argv.localReleaseBuilds) { acPath = pathFinder.discoveredPath("assignment-client", argv.localReleaseBuilds); } +function openFileBrowser(path) { + var type = os.type(); + if (type == "Windows_NT") { + childProcess.exec('start ' + path); + } else if (type == "Darwin") { + childProcess.exec('open ' + path); + } else if (type == "Linux") { + childProcess.exec('xdg-open ' + path); + } +} + // if at this point any of the paths are null, we're missing something we wanted to find // TODO: show an error for the binaries that couldn't be found @@ -82,17 +96,14 @@ app.on('ready', function() { shell.openExternal(url); }); + var logPath = path.join(app.getAppPath(), 'logs'); + if (interfacePath && dsPath && acPath) { var pInterface = new Process('interface', interfacePath); var homeServer = new ProcessGroup('home', [ new Process('domain_server', dsPath), - new Process('ac_audio', acPath, ['-t0']), - new Process('ac_avatar', acPath, ['-t1']), - new Process('ac_agent', acPath, ['-t2']), - new Process('ac_asset', acPath, ['-t3']), - new Process('ac_messages', acPath, ['-t4']), - new Process('ac_entity', acPath, ['-t6']) + new Process('ac_monitor', acPath, ['-n6', '--log-directory', logPath]) ]); homeServer.start(); @@ -125,6 +136,9 @@ app.on('ready', function() { homeServer.stop(); sendProcessUpdate(); }); + ipcMain.on('open-logs', function(event, arg) { + openFileBrowser(logPath); + }); ipcMain.on('update', sendProcessUpdate); sendProcessUpdate(); From b4bd75e497425fa276efd81232ae39b72fa49373 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 16 Dec 2015 09:21:00 -0800 Subject: [PATCH 12/12] Update console Process logging to be optional --- console/modules/hf-process.js | 58 +++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/console/modules/hf-process.js b/console/modules/hf-process.js index 2ee5f26aba..76d0aaff2e 100755 --- a/console/modules/hf-process.js +++ b/console/modules/hf-process.js @@ -75,7 +75,7 @@ ProcessGroup.prototype = extend(ProcessGroup.prototype, { }); var ID = 0; -function Process(name, command, commandArgs) { +function Process(name, command, commandArgs, logDirectory) { events.EventEmitter.call(this); this.blah = 'adsf'; @@ -84,6 +84,7 @@ function Process(name, command, commandArgs) { this.command = command; this.commandArgs = commandArgs ? commandArgs : []; this.child = null; + this.logDirectory = logDirectory; this.state = ProcessStates.STOPPED; }; @@ -96,38 +97,41 @@ Process.prototype = extend(Process.prototype, { } console.log("Starting " + this.command); - var logDirectoryCreated = false; - try { - fs.mkdirSync('logs'); - logDirectoryCreated = true; - } catch (e) { - if (e.code == 'EEXIST') { - logDirectoryCreated = true; - } else { - console.error("Error creating log directory"); - } - } - var logStdout = 'ignore', logStderr = 'ignore'; - if (logDirectoryCreated) { - // Create a temporary file with the current time - var time = (new Date).getTime(); - var tmpLogStdout = './logs/' + this.name + '-' + time + '-stdout.txt'; - var tmpLogStderr = './logs/' + this.name + '-' + time + '-stderr.txt'; + if (this.logDirectory) { + var logDirectoryCreated = false; try { - logStdout = fs.openSync(tmpLogStdout, 'ax'); - } catch(e) { - console.log("Error creating stdout log file", e); - logStdout = 'ignore'; + fs.mkdirSync('logs'); + logDirectoryCreated = true; + } catch (e) { + if (e.code == 'EEXIST') { + logDirectoryCreated = true; + } else { + console.error("Error creating log directory"); + } } - try { - logStderr = fs.openSync(tmpLogStderr, 'ax'); - } catch(e) { - console.log("Error creating stderr log file", e); - logStderr = 'ignore'; + + if (logDirectoryCreated) { + // Create a temporary file with the current time + var time = (new Date).getTime(); + var tmpLogStdout = this.logDirectory + '/' + this.name + '-' + time + '-stdout.txt'; + var tmpLogStderr = this.logDirectory + '/' + this.name + '-' + time + '-stderr.txt'; + + try { + logStdout = fs.openSync(tmpLogStdout, 'ax'); + } catch(e) { + console.log("Error creating stdout log file", e); + logStdout = 'ignore'; + } + try { + logStderr = fs.openSync(tmpLogStderr, 'ax'); + } catch(e) { + console.log("Error creating stderr log file", e); + logStderr = 'ignore'; + } } }