Addressed PR comments
*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`.
This commit is contained in:
parent
0760965bda
commit
d4d7e3b8ac
|
@ -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");
|
||||
|
|
|
@ -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 <CommandResult key={index} result={command.result}/>;
|
||||
})
|
||||
|
@ -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 => (
|
||||
|
|
|
@ -52,5 +52,8 @@
|
|||
},
|
||||
"codeGenerator": {
|
||||
"gasLimit": 6000000
|
||||
},
|
||||
"logs": {
|
||||
"logPath": ".embark/logs/"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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 = /\[(?<date>\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d:\d\d\d)\] (?:\[(?<logLevel>\w*)\]:?)?\s?\s?(?<msg>.*)/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 = /\[(?<date>\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d:\d\d\d)\] (?:\[(?<logLevel>\w*)\]:?)?\s?\s?(?<msg>.*)/gmi;
|
||||
|
||||
// Use a default logFile if none is specified in the cli,
|
||||
// in the format .embark/logs/embark_<context>.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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
|
@ -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;
|
|
@ -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;
|
Loading…
Reference in New Issue