From d4d7e3b8acb6bcca0feb4e5ffea84cb73f778cbb Mon Sep 17 00:00:00 2001 From: emizzle Date: Wed, 10 Oct 2018 10:15:39 +1100 Subject: [PATCH] Addressed PR comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit *Console.js* - Moved `DEFAULT_PROCESS` const to outside of the `Console` class (but inside the module). - Removed `(` and `)` from `.filter` in `getProcessLogs()`. - Updated comments *logger.js* - Moved `dateFormat` and `logRegex` to constants outside of `Logger` class - Moved the `parseLogFile` method inside of the `Logger` class (ES6 style) - Added a log limit to the `parseLogFile` method - Added the log path to the constants file and used inside of `Logger` *cmd_controller.js* - Defaulted `this.context` to `[constants.context.any]` in the constructor. - Changed `’embark’` to split modules`coreProcess` and `loggerApi`. *engine.js* - Changed `’embark’` to split modules`coreProcess` and `loggerApi`. --- cmd/cmd_controller.js | 7 ++- embark-ui/src/components/Console.js | 12 ++-- lib/constants.json | 3 + lib/core/engine.js | 14 +++-- lib/core/logger.js | 88 +++++++++++++++-------------- lib/modules/core_process/index.js | 20 +++++++ lib/modules/embark/index.js | 29 ---------- lib/modules/logger_api/index.js | 20 +++++++ 8 files changed, 113 insertions(+), 80 deletions(-) create mode 100644 lib/modules/core_process/index.js delete mode 100644 lib/modules/embark/index.js create mode 100644 lib/modules/logger_api/index.js diff --git a/cmd/cmd_controller.js b/cmd/cmd_controller.js index 47da1639a..2d4e21e8c 100644 --- a/cmd/cmd_controller.js +++ b/cmd/cmd_controller.js @@ -11,6 +11,10 @@ class EmbarkController { constructor(options) { this.version = version; this.options = options || {}; + + // set a default context. should be overwritten by an action + // method before being used + this.context = [constants.contexts.any]; } initConfig(env, options) { @@ -126,7 +130,8 @@ class EmbarkController { } engine.startService("processManager"); - engine.startService("embark"); + engine.startService("coreProcess"); + engine.startService("loggerApi"); engine.startService("serviceMonitor"); engine.startService("libraryManager"); engine.startService("codeRunner"); diff --git a/embark-ui/src/components/Console.js b/embark-ui/src/components/Console.js index ce012b6b6..eb6574cfd 100644 --- a/embark-ui/src/components/Console.js +++ b/embark-ui/src/components/Console.js @@ -34,17 +34,19 @@ class Console extends Component { getProcessLogs(processName){ const log = this.props.processLogs .reverse() - .filter((item) => item.process === processName); + .filter(item => item.process === processName); if(!log.length) return []; - //should be only one item in the array + // the selector should have reduced `processLogs` down to one + // record per process, and therefore after filtering, the array + // should have only one item return log[0].logs; } renderCommandsResult(){ const {commands} = this.props; return ( - this.state.selectedProcess === this.DEFAULT_PROCESS && + this.state.selectedProcess === DEFAULT_PROCESS && commands.map((command, index) => { return ; }) @@ -55,8 +57,8 @@ class Console extends Component { const {processes} = this.props; return processes .sort((a, b) => { // ensure the "Embark" tab is displayed first - if (a.name === this.DEFAULT_PROCESS) return -1; - if (b.name === this.DEFAULT_PROCESS) return 1; + if (a.name === DEFAULT_PROCESS) return -1; + if (b.name === DEFAULT_PROCESS) return 1; return 0; }) .map(process => ( diff --git a/lib/constants.json b/lib/constants.json index 3bbe63ac3..26b7491e9 100644 --- a/lib/constants.json +++ b/lib/constants.json @@ -52,5 +52,8 @@ }, "codeGenerator": { "gasLimit": 6000000 + }, + "logs": { + "logPath": ".embark/logs/" } } diff --git a/lib/core/engine.js b/lib/core/engine.js index 6bf9684cc..f35a3ba07 100644 --- a/lib/core/engine.js +++ b/lib/core/engine.js @@ -79,7 +79,8 @@ class Engine { "testRunner": this.testRunnerService, "codeCoverage": this.codeCoverageService, "scaffolding": this.scaffoldingService, - "embark": this.embarkService + "coreProcess": this.coreProcessService, + "loggerApi": this.loggerApiService }; let service = services[serviceName]; @@ -93,9 +94,14 @@ class Engine { return service.apply(this, [options]); } - embarkService(_options){ - this.registerModule('embark', { - events: this.events, + coreProcessService(_options){ + this.registerModule('core_process', { + events: this.events + }); + } + + loggerApiService(_options){ + this.registerModule('logger_api', { logger: this.logger }); } diff --git a/lib/core/logger.js b/lib/core/logger.js index 7e45f0067..d8ad9216e 100644 --- a/lib/core/logger.js +++ b/lib/core/logger.js @@ -1,6 +1,10 @@ require('colors'); let fs = require('./fs.js'); const date = require('date-and-time'); +const constants = require('../constants'); + +const DATE_FORMAT = 'YYYY-MM-DD HH:mm:ss:SSS'; +const LOG_REGEX = /\[(?\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d:\d\d\d)\] (?:\[(?\w*)\]:?)?\s?\s?(?.*)/gmi; class Logger { constructor(options) { @@ -10,17 +14,52 @@ class Logger { this.logFunction = options.logFunction || console.log; this.logFile = options.logFile; this.context = options.context; - this.dateFormat = 'YYYY-MM-DD HH:mm:ss:SSS'; - this.logRegex = /\[(?\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d:\d\d\d)\] (?:\[(?\w*)\]:?)?\s?\s?(?.*)/gmi; - // Use a default logFile if none is specified in the cli, // in the format .embark/logs/embark_.log. if (!this.logFile) { - this.logFile = fs.dappPath(`.embark/logs/embark_${this.context}.log`); + this.logFile = fs.dappPath(`${constants.logs.logPath}embark_${this.context}.log`); // creates log dir if it doesn't exist, and overwrites existing log file if it exists fs.outputFileSync(this.logFile, ''); } } + + /** + * Parses the logFile, returning an array of JSON objects containing the + * log messages. + * @param {Number} limit specifies how many log messages to return from the + * end of the log file + * @returns {Array} array containing + * - msg: the log message + * - logLevel: log level (ie 'info', 'debug') + * - name: process name (always "embark") + * - timestamp: timestamp of log message (milliseconds since 1/1/1970) + */ + parseLogFile(limit) { + let matches; + let logs = []; + const logFile = fs.readFileSync(this.logFile, 'utf8'); + while ((matches = LOG_REGEX.exec(logFile)) !== null) { + // This is necessary to avoid infinite loops with zero-width matches + if (matches.index === LOG_REGEX.lastIndex) { + LOG_REGEX.lastIndex++; + } + + if (matches && matches.groups) { + logs.push({ + msg: [matches.groups.msg], + logLevel: matches.groups.logLevel, + name: 'embark', + timestamp: date.parse(matches.groups.date, DATE_FORMAT).getTime() + }); + } + } + + // if 'limit' is specified, get log lines from the end of the log file + if(limit && logs.length > limit){ + logs.slice(limit * -1); + } + return logs; + }; } Logger.logLevels = { @@ -46,41 +85,8 @@ Logger.prototype.registerAPICall = function (plugins) { ); }; -/** - * Parses the logFile, returning an array of JSON objects containing the - * log messages. - * - * @returns {Array} array containing - * - msg: the log message - * - logLevel: log level (ie 'info', 'debug') - * - name: process name (always "embark") - * - timestamp: timestamp of log message (milliseconds since 1/1/1970) - */ -Logger.prototype.parseLogFile = function () { - let matches; - let logs = []; - const logFile = fs.readFileSync(this.logFile, 'utf8'); - while ((matches = this.logRegex.exec(logFile)) !== null) { - // This is necessary to avoid infinite loops with zero-width matches - if (matches.index === this.logRegex.lastIndex) { - this.logRegex.lastIndex++; - } - - if(matches && matches.groups){ - logs.push({ - msg: [matches.groups.msg], - logLevel: matches.groups.logLevel, - name: 'embark', - timestamp: date.parse(matches.groups.date, this.dateFormat).getTime() - }); - } - } - - return logs; -}; - Logger.prototype.writeToFile = function (_txt) { - const formattedDate = [`[${date.format(new Date(), this.dateFormat)}]`]; // adds a timestamp to the logs in the logFile + const formattedDate = [`[${date.format(new Date(), DATE_FORMAT)}]`]; // adds a timestamp to the logs in the logFile fs.appendFileSync(this.logFile, "\n" + formattedDate.concat(Array.from(arguments)).join(' ')); }; @@ -89,7 +95,7 @@ Logger.prototype.error = function () { return; } this.events.emit("log", "error", ...arguments); - this.logFunction(...Array.from(arguments).map(t => { return t ? t.red : t; })); + this.logFunction(...Array.from(arguments).map(t => {return t ? t.red : t;})); this.writeToFile("[error]: ", ...arguments); }; @@ -98,7 +104,7 @@ Logger.prototype.warn = function () { return; } this.events.emit("log", "warn", ...arguments); - this.logFunction(...Array.from(arguments).map(t => { return t ? t.yellow : t; })); + this.logFunction(...Array.from(arguments).map(t => {return t ? t.yellow : t;})); this.writeToFile("[warning]: ", ...arguments); }; @@ -107,7 +113,7 @@ Logger.prototype.info = function () { return; } this.events.emit("log", "info", ...arguments); - this.logFunction(...Array.from(arguments).map(t => { return t ? t.green : t; })); + this.logFunction(...Array.from(arguments).map(t => {return t ? t.green : t;})); this.writeToFile("[info]: ", ...arguments); }; diff --git a/lib/modules/core_process/index.js b/lib/modules/core_process/index.js new file mode 100644 index 000000000..70f0a3b02 --- /dev/null +++ b/lib/modules/core_process/index.js @@ -0,0 +1,20 @@ +class CoreProcess { + constructor(embark) { + this.embark = embark; + this.events = embark.events; + + this.registerProcess(); + } + + // Register 'embark' as a process + registerProcess() { + this.events.request('processes:register', 'embark', (setRunning) => { + // on 'outputDone', set 'embark' process to 'running' + this.events.on('outputDone', setRunning); + }); + // set 'embark' process to 'starting' + this.events.request('processes:launch', 'embark', () => {}); + } +} + +module.exports = CoreProcess; diff --git a/lib/modules/embark/index.js b/lib/modules/embark/index.js deleted file mode 100644 index 1f5a96cca..000000000 --- a/lib/modules/embark/index.js +++ /dev/null @@ -1,29 +0,0 @@ -class Embark { - constructor(embark) { - this.embark = embark; - this.logger = embark.logger; - this.events = embark.events; - - this.registerProcess(); - this.registerAPICalls(); - } - - registerProcess() { - this.events.request('processes:register', 'embark', (setRunning) => { - this.events.on('outputDone', setRunning); - }); - this.events.request('processes:launch', 'embark', () => {}); - } - - registerAPICalls(){ - this.embark.registerAPICall( - 'get', - '/embark-api/process-logs/embark', - (req, res) => { - res.send(this.logger.parseLogFile()); - } - ); - } -} - -module.exports = Embark; diff --git a/lib/modules/logger_api/index.js b/lib/modules/logger_api/index.js new file mode 100644 index 000000000..238fd7aba --- /dev/null +++ b/lib/modules/logger_api/index.js @@ -0,0 +1,20 @@ +class LoggerApi { + constructor(embark) { + this.embark = embark; + this.logger = embark.logger; + + this.registerAPICalls(); + } + + registerAPICalls(){ + this.embark.registerAPICall( + 'get', + '/embark-api/process-logs/embark', + (req, res) => { + res.send(this.logger.parseLogFile(req.query.limit)); + } + ); + } +} + +module.exports = LoggerApi;