From b2e68a1075a685d98daf5c44f73d6ed7a619675d Mon Sep 17 00:00:00 2001
From: Atlante45 <clement.brisset@gmail.com>
Date: Fri, 21 Oct 2016 17:04:37 -0700
Subject: [PATCH] Print log to file as well

---
 server-console/package.json               |  7 +-
 server-console/src/main.js                | 82 ++++++++++++-----------
 server-console/src/modules/config.js      |  7 +-
 server-console/src/modules/hf-process.js  | 37 +++++-----
 server-console/src/modules/hf-updater.js  | 11 +--
 server-console/src/modules/path-finder.js |  5 +-
 6 files changed, 78 insertions(+), 71 deletions(-)

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);
             }
         }