2017-09-25 22:00:19 +00:00
|
|
|
const path = require('path');
|
|
|
|
const fs = require('fs');
|
|
|
|
|
|
|
|
const electron = require('electron')
|
|
|
|
const bunyan = require('bunyan');
|
|
|
|
const mkdirp = require('mkdirp');
|
|
|
|
const _ = require('lodash');
|
|
|
|
|
|
|
|
|
|
|
|
const app = electron.app;
|
|
|
|
const ipc = electron.ipcMain;
|
|
|
|
const LEVELS = ['fatal', 'error', 'warn', 'info', 'debug', 'trace'];
|
|
|
|
|
|
|
|
let logger;
|
|
|
|
|
|
|
|
|
|
|
|
function dropFirst(args) {
|
|
|
|
return Array.prototype.slice.call(args, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
function initialize() {
|
|
|
|
if (logger) {
|
|
|
|
throw new Error('Already called initialize!');
|
|
|
|
}
|
|
|
|
|
|
|
|
const basePath = app.getPath('userData');
|
|
|
|
const logPath = path.join(basePath, 'logs');
|
|
|
|
mkdirp.sync(logPath);
|
|
|
|
|
|
|
|
const logFile = path.join(logPath, 'log.log');
|
|
|
|
|
|
|
|
logger = bunyan.createLogger({
|
|
|
|
name: 'log',
|
|
|
|
streams: [{
|
|
|
|
level: 'debug',
|
|
|
|
stream: process.stdout
|
|
|
|
}, {
|
|
|
|
type: 'rotating-file',
|
|
|
|
path: logFile,
|
|
|
|
period: '1d',
|
|
|
|
count: 3
|
|
|
|
}]
|
|
|
|
});
|
|
|
|
|
|
|
|
LEVELS.forEach(function(level) {
|
|
|
|
ipc.on('log-' + level, function() {
|
|
|
|
// first parameter is the event, rest are provided arguments
|
|
|
|
var args = dropFirst(arguments);
|
|
|
|
logger[level].apply(logger, args);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
ipc.on('fetch-log', function(event) {
|
2017-10-04 21:40:35 +00:00
|
|
|
fetch(logPath).then(function(data) {
|
|
|
|
event.sender.send('fetched-log', data);
|
|
|
|
}, function(error) {
|
|
|
|
logger.error('Problem loading log from disk: ' + error.stack);
|
|
|
|
});
|
2017-09-25 22:00:19 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function getLogger() {
|
|
|
|
if (!logger) {
|
|
|
|
throw new Error('Logger hasn\'t been initialized yet!');
|
|
|
|
}
|
|
|
|
|
|
|
|
return logger;
|
|
|
|
}
|
|
|
|
|
2017-10-04 21:40:35 +00:00
|
|
|
function fetchLog(logFile) {
|
|
|
|
return new Promise(function(resolve, reject) {
|
|
|
|
fs.readFile(logFile, { encoding: 'utf8' }, function(err, text) {
|
|
|
|
if (err) {
|
|
|
|
return reject(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
const lines = _.compact(text.split('\n'));
|
|
|
|
const data = _.compact(lines.map(function(line) {
|
|
|
|
try {
|
|
|
|
return _.pick(JSON.parse(line), ['level', 'time', 'msg']);
|
|
|
|
}
|
|
|
|
catch (e) {}
|
|
|
|
}));
|
2017-09-25 22:00:19 +00:00
|
|
|
|
2017-10-04 21:40:35 +00:00
|
|
|
return resolve(data);
|
|
|
|
});
|
2017-09-25 22:00:19 +00:00
|
|
|
});
|
2017-10-04 21:40:35 +00:00
|
|
|
}
|
2017-09-25 22:00:19 +00:00
|
|
|
|
2017-10-04 21:40:35 +00:00
|
|
|
function fetch(logPath) {
|
|
|
|
const files = fs.readdirSync(logPath);
|
|
|
|
const paths = files.map(function(file) {
|
|
|
|
return path.join(logPath, file)
|
|
|
|
});
|
2017-09-25 22:00:19 +00:00
|
|
|
|
2017-11-30 19:56:46 +00:00
|
|
|
// creating a manual log entry for the final log result
|
|
|
|
var now = new Date();
|
|
|
|
const fileListEntry = {
|
|
|
|
level: 30, // INFO
|
|
|
|
time: now.toJSON(),
|
|
|
|
msg: 'Loaded this list of log files from logPath: ' + files.join(', '),
|
|
|
|
};
|
|
|
|
|
2017-10-04 21:40:35 +00:00
|
|
|
return Promise.all(paths.map(fetchLog)).then(function(results) {
|
|
|
|
const data = _.flatten(results);
|
2017-11-30 19:56:46 +00:00
|
|
|
|
|
|
|
data.push(fileListEntry);
|
|
|
|
|
2017-10-04 21:40:35 +00:00
|
|
|
return _.sortBy(data, 'time');
|
|
|
|
});
|
2017-09-25 22:00:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-04 21:03:59 +00:00
|
|
|
function logAtLevel() {
|
|
|
|
const level = arguments[0];
|
|
|
|
const args = Array.prototype.slice.call(arguments, 1);
|
|
|
|
|
|
|
|
if (logger) {
|
|
|
|
// To avoid [Object object] in our log since console.log handles non-strings smoothly
|
|
|
|
const str = args.map(function(item) {
|
|
|
|
if (typeof item !== 'string') {
|
|
|
|
try {
|
|
|
|
return JSON.stringify(item);
|
|
|
|
}
|
|
|
|
catch (e) {
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return item;
|
|
|
|
});
|
|
|
|
logger[level](str.join(' '));
|
|
|
|
} else {
|
|
|
|
console._log.apply(console, consoleArgs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
console._log = console.log;
|
|
|
|
console.log = _.partial(logAtLevel, 'info');
|
|
|
|
console._error = console.error;
|
|
|
|
console.error = _.partial(logAtLevel, 'error');
|
|
|
|
console._warn = console.warn;
|
|
|
|
console.warn = _.partial(logAtLevel, 'warn');
|
|
|
|
|
|
|
|
|
2017-09-25 22:00:19 +00:00
|
|
|
module.exports = {
|
|
|
|
initialize,
|
|
|
|
getLogger,
|
|
|
|
};
|