diff --git a/server-console/package.json b/server-console/package.json index d97f72609b..f72ffc347f 100644 --- a/server-console/package.json +++ b/server-console/package.json @@ -1,6 +1,6 @@ { - "name": "hf-console", - "description": "High Fidelity Console", + "name": "HighFidelitySandbox", + "description": "High Fidelity Sandbox", "author": "High Fidelity", "license": "Apache-2.0", "version": "1.0.0", @@ -33,6 +33,7 @@ "request": "^2.67.0", "request-progress": "1.0.2", "tar-fs": "^1.12.0", - "yargs": "^3.30.0" + "yargs": "^3.30.0", + "electron-log": "1.1.1" } } diff --git a/server-console/src/main.js b/server-console/src/main.js index 72f4520020..6f26de1b84 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -5,6 +5,8 @@ const app = electron.app; // Module to control application life. const BrowserWindow = electron.BrowserWindow; const nativeImage = electron.nativeImage; +const log = require('electron-log'); + const notifier = require('node-notifier'); const util = require('util'); const dialog = electron.dialog; @@ -64,7 +66,7 @@ function getBuildInfo() { var buildInfo = DEFAULT_BUILD_INFO; if (buildInfoPath) { - console.log('Build info path:', buildInfoPath); + log.debug('Build info path:', buildInfoPath); try { buildInfo = JSON.parse(fs.readFileSync(buildInfoPath)); } catch (e) { @@ -77,7 +79,7 @@ function getBuildInfo() { const buildInfo = getBuildInfo(); -console.log("build info", buildInfo); +log.debug("build info", buildInfo); function getRootHifiDataDirectory() { var organization = "High Fidelity"; @@ -105,7 +107,7 @@ function getApplicationDataDirectory() { return path.join(getRootHifiDataDirectory(), '/Server Console'); } -console.log("Root hifi directory is: ", getRootHifiDataDirectory()); +log.debug("Root hifi directory is: ", getRootHifiDataDirectory()); const ipcMain = electron.ipcMain; @@ -167,36 +169,36 @@ function shutdownCallback(idx) { } function deleteOldFiles(directoryPath, maxAgeInSeconds, filenameRegex) { - console.log("Deleting old log files in " + directoryPath); + log.debug("Deleting old log files in " + directoryPath); var filenames = []; try { filenames = fs.readdirSync(directoryPath); } catch (e) { - console.warn("Error reading contents of log file directory", e); + log.warn("Error reading contents of log file directory", e); return; } for (const filename of filenames) { - console.log("Checking", filename); + log.debug("Checking", filename); const absolutePath = path.join(directoryPath, filename); var stat = null; try { stat = fs.statSync(absolutePath); } catch (e) { - console.log("Error stat'ing file", absolutePath, e); + log.debug("Error stat'ing file", absolutePath, e); continue; } const curTime = Date.now(); if (stat.isFile() && filename.search(filenameRegex) >= 0) { const ageInSeconds = (curTime - stat.mtime.getTime()) / 1000.0; if (ageInSeconds >= maxAgeInSeconds) { - console.log("\tDeleting:", filename, ageInSeconds); + log.debug("\tDeleting:", filename, ageInSeconds); try { fs.unlinkSync(absolutePath); } catch (e) { if (e.code != 'EBUSY') { - console.warn("\tError deleting:", e); + log.warn("\tError deleting:", e); } } } @@ -206,8 +208,8 @@ function deleteOldFiles(directoryPath, maxAgeInSeconds, filenameRegex) { var logPath = path.join(getApplicationDataDirectory(), '/logs'); -console.log("Log directory:", logPath); -console.log("Data directory:", getRootHifiDataDirectory()); +log.debug("Log directory:", logPath); +log.debug("Data directory:", getRootHifiDataDirectory()); const configPath = path.join(getApplicationDataDirectory(), 'config.json'); var userConfig = new Config(); @@ -215,8 +217,8 @@ userConfig.load(configPath); // print out uncaught exceptions in the console process.on('uncaughtException', function(err) { - console.error(err); - console.error(err.stack); + log.error(err); + log.error(err.stack); }); var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) { @@ -225,7 +227,7 @@ var shouldQuit = app.makeSingleInstance(function(commandLine, workingDirectory) }); if (shouldQuit) { - console.warn("Another instance of the Sandbox is already running - this instance will quit."); + log.warn("Another instance of the Sandbox is already running - this instance will quit."); app.quit(); return; } @@ -506,7 +508,7 @@ const httpStatusPort = 60332; function backupResourceDirectories(folder) { try { fs.mkdirSync(folder); - console.log("Created directory " + folder); + log.debug("Created directory " + folder); var dsBackup = path.join(folder, '/domain-server'); var acBackup = path.join(folder, '/assignment-client'); @@ -519,7 +521,7 @@ function backupResourceDirectories(folder) { return true; } catch (e) { - console.log(e); + log.debug(e); return false; } } @@ -541,7 +543,7 @@ function openBackupInstructions(folder) { window.setSize(obj.width, obj.height); }); electron.ipcMain.on('ready', function() { - console.log("got ready"); + log.debug("got ready"); window.webContents.send('update', folder); }); } @@ -575,9 +577,9 @@ function checkNewContent() { var wantDebug = false; if (wantDebug) { - console.log('Last Modified: ' + response.headers['last-modified']); - console.log(localContent + " " + remoteContent + " " + shouldUpdate + " " + new Date()); - console.log("Remote content is " + (shouldUpdate ? "newer" : "older") + " that local content."); + log.debug('Last Modified: ' + response.headers['last-modified']); + log.debug(localContent + " " + remoteContent + " " + shouldUpdate + " " + new Date()); + log.debug("Remote content is " + (shouldUpdate ? "newer" : "older") + " that local content."); } if (shouldUpdate) { @@ -619,46 +621,46 @@ function maybeInstallDefaultContentSet(onComplete) { // Check for existing data const acResourceDirectory = getAssignmentClientResourcesDirectory(); - console.log("Checking for existence of " + acResourceDirectory); + log.debug("Checking for existence of " + acResourceDirectory); var userHasExistingACData = true; try { fs.accessSync(acResourceDirectory); - console.log("Found directory " + acResourceDirectory); + log.debug("Found directory " + acResourceDirectory); } catch (e) { - console.log(e); + log.debug(e); userHasExistingACData = false; } const dsResourceDirectory = getDomainServerClientResourcesDirectory(); - console.log("checking for existence of " + dsResourceDirectory); + log.debug("checking for existence of " + dsResourceDirectory); var userHasExistingDSData = true; try { fs.accessSync(dsResourceDirectory); - console.log("Found directory " + dsResourceDirectory); + log.debug("Found directory " + dsResourceDirectory); } catch (e) { - console.log(e); + log.debug(e); userHasExistingDSData = false; } if (userHasExistingACData || userHasExistingDSData) { - console.log("User has existing data, suppressing downloader"); + log.debug("User has existing data, suppressing downloader"); onComplete(); checkNewContent(); return; } - console.log("Found contentPath:" + argv.contentPath); + log.debug("Found contentPath:" + argv.contentPath); if (argv.contentPath) { fs.copy(argv.contentPath, getRootHifiDataDirectory(), function (err) { if (err) { - console.log('Could not copy home content: ' + err); - return console.error(err) + log.debug('Could not copy home content: ' + err); + return log.error(err) } - console.log('Copied home content over to: ' + getRootHifiDataDirectory()); + log.debug('Copied home content over to: ' + getRootHifiDataDirectory()); userConfig.set('homeContentLastModified', new Date()); onComplete(); }); @@ -685,11 +687,11 @@ function maybeInstallDefaultContentSet(onComplete) { window.on('closed', onComplete); electron.ipcMain.on('ready', function() { - console.log("got ready"); + log.debug("got ready"); var currentState = ''; function sendStateUpdate(state, args) { - // console.log(state, window, args); + // log.debug(state, window, args); window.webContents.send('update', { state: state, args: args }); currentState = state; } @@ -723,10 +725,10 @@ function maybeInstallDefaultContentSet(onComplete) { }); function extractError(err) { - console.log("Aborting request because gunzip/untar failed"); + log.debug("Aborting request because gunzip/untar failed"); aborted = true; req.abort(); - console.log("ERROR" + err); + log.debug("ERROR" + err); sendStateUpdate('error', { message: "Error installing resources." @@ -738,7 +740,7 @@ function maybeInstallDefaultContentSet(onComplete) { req.pipe(gunzip).pipe(tar.extract(getRootHifiDataDirectory())).on('error', extractError).on('finish', function(){ // response and decompression complete, return - console.log("Finished unarchiving home content set"); + log.debug("Finished unarchiving home content set"); userConfig.set('homeContentLastModified', new Date()); sendStateUpdate('complete'); }); @@ -824,7 +826,7 @@ function onContentLoaded() { } }); notifier.on('click', function(notifierObject, options) { - console.log("Got click", options.url); + log.debug("Got click", options.url); shell.openExternal(options.url); }); } @@ -855,7 +857,7 @@ function onContentLoaded() { // shutting down. The interface app will regularly update a running state file which we will check. // If the file doesn't exist or stops updating for a significant amount of time, we will shut down. if (argv.shutdownWatcher) { - console.log("Shutdown watcher requested... argv.shutdownWatcher:", argv.shutdownWatcher); + log.debug("Shutdown watcher requested... argv.shutdownWatcher:", argv.shutdownWatcher); var MAX_TIME_SINCE_EDIT = 5000; // 5 seconds between updates var firstAttemptToCheck = new Date().getTime(); var shutdownWatchInterval = setInterval(function(){ @@ -863,14 +865,14 @@ function onContentLoaded() { if (err) { var sinceFirstCheck = new Date().getTime() - firstAttemptToCheck; if (sinceFirstCheck > MAX_TIME_SINCE_EDIT) { - console.log("Running state file is missing, assume interface has shutdown... shutting down snadbox."); + log.debug("Running state file is missing, assume interface has shutdown... shutting down snadbox."); forcedShutdown(); clearTimeout(shutdownWatchInterval); } } else { var sinceEdit = new Date().getTime() - stats.mtime.getTime(); if (sinceEdit > MAX_TIME_SINCE_EDIT) { - console.log("Running state of interface hasn't updated in MAX time... shutting down."); + log.debug("Running state of interface hasn't updated in MAX time... shutting down."); forcedShutdown(); clearTimeout(shutdownWatchInterval); } diff --git a/server-console/src/modules/config.js b/server-console/src/modules/config.js index df44dcfafe..3853de1567 100644 --- a/server-console/src/modules/config.js +++ b/server-console/src/modules/config.js @@ -1,5 +1,6 @@ var fs = require('fs'); var extend = require('extend'); +var log = require('electron-log'); function Config() { this.data = {}; @@ -10,7 +11,7 @@ Config.prototype = { try { rawData = fs.readFileSync(filePath); } catch(e) { - console.log("Config file not found"); + log.debug("Config file not found"); } var configData = {}; @@ -21,7 +22,7 @@ Config.prototype = { configData = {}; } } catch(e) { - console.error("Error parsing config file", filePath) + log.error("Error parsing config file", filePath) } this.data = {}; @@ -37,7 +38,7 @@ Config.prototype = { return defaultValue; }, set: function(key, value) { - console.log("Setting", key, "to", value); + log.debug("Setting", key, "to", value); this.data[key] = value; } }; diff --git a/server-console/src/modules/hf-process.js b/server-console/src/modules/hf-process.js index ce20e385f3..9e8fb47ccd 100755 --- a/server-console/src/modules/hf-process.js +++ b/server-console/src/modules/hf-process.js @@ -8,6 +8,7 @@ const childProcess = require('child_process'); const fs = require('fs-extra'); const os = require('os'); const path = require('path'); +const log = require('electron-log'); const ProcessGroupStates = { STOPPED: 'stopped', @@ -43,7 +44,7 @@ ProcessGroup.prototype = extend(ProcessGroup.prototype, { }, start: function() { if (this.state != ProcessGroupStates.STOPPED) { - console.warn("Can't start process group that is not stopped."); + log.warn("Can't start process group that is not stopped."); return; } @@ -56,7 +57,7 @@ ProcessGroup.prototype = extend(ProcessGroup.prototype, { }, stop: function() { if (this.state != ProcessGroupStates.STARTED) { - console.warn("Can't stop process group that is not started."); + log.warn("Can't stop process group that is not started."); return; } for (let process of this.processes) { @@ -120,10 +121,10 @@ util.inherits(Process, events.EventEmitter); Process.prototype = extend(Process.prototype, { start: function() { if (this.state != ProcessStates.STOPPED) { - console.warn("Can't start process that is not stopped."); + log.warn("Can't start process that is not stopped."); return; } - console.log("Starting " + this.command + " " + this.commandArgs.join(' ')); + log.debug("Starting " + this.command + " " + this.commandArgs.join(' ')); var logStdout = 'ignore', logStderr = 'ignore'; @@ -138,7 +139,7 @@ Process.prototype = extend(Process.prototype, { if (e.code == 'EEXIST') { logDirectoryCreated = true; } else { - console.error("Error creating log directory"); + log.error("Error creating log directory"); } } @@ -151,13 +152,13 @@ Process.prototype = extend(Process.prototype, { try { logStdout = fs.openSync(tmpLogStdout, 'ax'); } catch(e) { - console.log("Error creating stdout log file", e); + log.debug("Error creating stdout log file", e); logStdout = 'ignore'; } try { logStderr = fs.openSync(tmpLogStderr, 'ax'); } catch(e) { - console.log("Error creating stderr log file", e); + log.debug("Error creating stderr log file", e); logStderr = 'ignore'; } } @@ -169,7 +170,7 @@ Process.prototype = extend(Process.prototype, { stdio: ['ignore', logStdout, logStderr] }); } catch (e) { - console.log("Got error starting child process for " + this.name, e); + log.debug("Got error starting child process for " + this.name, e); this.child = null; this.updateState(ProcessStates.STOPPED); return; @@ -179,7 +180,7 @@ Process.prototype = extend(Process.prototype, { var pidLogStdout = path.resolve(this.logDirectory + '/' + 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); + log.debug("Error renaming log file from " + tmpLogStdout + " to " + pidLogStdout, e); } }); this.logStdout = pidLogStdout; @@ -190,7 +191,7 @@ Process.prototype = extend(Process.prototype, { var pidLogStderr = path.resolve(this.logDirectory + '/' + 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); + log.debug("Error renaming log file from " + tmpLogStdout + " to " + pidLogStdout, e); } }); this.logStderr = pidLogStderr; @@ -201,13 +202,13 @@ Process.prototype = extend(Process.prototype, { this.child.on('error', this.onChildStartError.bind(this)); this.child.on('close', this.onChildClose.bind(this)); - console.log("Child process started"); + log.debug("Child process started"); this.updateState(ProcessStates.STARTED); this.emit('logs-updated'); }, stop: function(force) { if (this.state == ProcessStates.STOPPED) { - console.warn("Can't stop process that is not started or stopping."); + log.warn("Can't stop process that is not started or stopping."); return; } if (os.type() == "Windows_NT") { @@ -217,7 +218,7 @@ Process.prototype = extend(Process.prototype, { } childProcess.exec(command, {}, function(error) { if (error) { - console.error('Error executing taskkill:', error); + log.error('Error executing taskkill:', error); } }); } else { @@ -225,12 +226,12 @@ Process.prototype = extend(Process.prototype, { this.child.kill(signal); } - console.log("Stopping child process:", this.child.pid, this.name); + log.debug("Stopping child process:", this.child.pid, this.name); if (!force) { this.stoppingTimeoutID = setTimeout(function() { if (this.state == ProcessStates.STOPPING) { - console.log("Force killling", this.name, this.child.pid); + log.debug("Force killling", this.name, this.child.pid); this.stop(true); } }.bind(this), 2500); @@ -257,11 +258,11 @@ Process.prototype = extend(Process.prototype, { // Events onChildStartError: function(error) { - console.log("Child process error ", error); + log.debug("Child process error ", error); this.updateState(ProcessStates.STOPPED); }, onChildClose: function(code) { - console.log("Child process closed with code ", code, this.name); + log.debug("Child process closed with code ", code, this.name); if (this.stoppingTimeoutID) { clearTimeout(this.stoppingTimeoutID); this.stoppingTimeoutID = null; @@ -332,7 +333,7 @@ ACMonitorProcess.prototype = extend(ACMonitorProcess.prototype, { this.pendingRequest = null; if (error) { - console.error('ERROR Getting AC Monitor status', error); + log.error('ERROR Getting AC Monitor status', error); } else { this.childServers = body.servers; } diff --git a/server-console/src/modules/hf-updater.js b/server-console/src/modules/hf-updater.js index 38e409b3a2..750e5d6a95 100644 --- a/server-console/src/modules/hf-updater.js +++ b/server-console/src/modules/hf-updater.js @@ -4,6 +4,7 @@ const util = require('util'); const events = require('events'); const cheerio = require('cheerio'); const os = require('os'); +const log = require('electron-log'); const platform = os.type() == 'Windows_NT' ? 'windows' : 'mac'; @@ -11,7 +12,7 @@ const BUILDS_URL = 'https://highfidelity.com/builds.xml'; function UpdateChecker(currentVersion, checkForUpdatesEveryXSeconds) { this.currentVersion = currentVersion; - console.log('cur', currentVersion); + log.debug('cur', currentVersion); setInterval(this.checkForUpdates.bind(this), checkForUpdatesEveryXSeconds * 1000); this.checkForUpdates(); @@ -19,10 +20,10 @@ function UpdateChecker(currentVersion, checkForUpdatesEveryXSeconds) { util.inherits(UpdateChecker, events.EventEmitter); UpdateChecker.prototype = extend(UpdateChecker.prototype, { checkForUpdates: function() { - console.log("Checking for updates"); + log.debug("Checking for updates"); request(BUILDS_URL, (error, response, body) => { if (error) { - console.log("Error", error); + log.debug("Error", error); return; } if (response.statusCode == 200) { @@ -30,13 +31,13 @@ UpdateChecker.prototype = extend(UpdateChecker.prototype, { var $ = cheerio.load(body, { xmlMode: true }); const latestBuild = $('project[name="interface"] platform[name="' + platform + '"]').children().first(); const latestVersion = parseInt(latestBuild.find('version').text()); - console.log("Latest version is:", latestVersion, this.currentVersion); + log.debug("Latest version is:", latestVersion, this.currentVersion); if (latestVersion > this.currentVersion) { const url = latestBuild.find('url').text(); this.emit('update-available', latestVersion, url); } } catch (e) { - console.warn("Error when checking for updates", e); + log.warn("Error when checking for updates", e); } } }); diff --git a/server-console/src/modules/path-finder.js b/server-console/src/modules/path-finder.js index d0e4639e4a..5e2af8c900 100644 --- a/server-console/src/modules/path-finder.js +++ b/server-console/src/modules/path-finder.js @@ -1,5 +1,6 @@ var fs = require('fs'); var path = require('path'); +var log = require('electron-log'); function platformExtension(name) { if (name == "Interface") { @@ -72,11 +73,11 @@ exports.discoveredPath = function (name, binaryType, releaseType) { var extension = platformExtension(name); if (stats.isFile() || (stats.isDirectory() && extension == ".app")) { - console.log("Found " + name + " at " + testPath); + log.debug("Found " + name + " at " + testPath); return testPath; } } catch (e) { - console.log("Executable with name " + name + " not found at path " + testPath); + log.debug("Executable with name " + name + " not found at path " + testPath); } }