Load debug log dialog immediately, then populate log data (#1540)

An immediate response to the user request to see the log, and then we
show the real data as soon as we've loaded it from disk.

Changes:
  - the IPC exchange to get the log data is now async
  - the API to fetch the log on the client side now returns a Promise
  - in the main process, the only disk access done synchronoously is
    reading the contents of the log directory. The JSON parsing of the
    resultant log data is now split up into three chunks.
  - We only send three keys from each log item to the renderer process:
    msg, time, level. Previously we sent the entire log entry with extra
    keys: hostname, pid, name.

FREEBIE
pull/749/head
Scott Nonnenberg 8 years ago committed by GitHub
parent 670d2afa69
commit ffbcb4ecb5

@ -51,7 +51,11 @@ function initialize() {
}); });
ipc.on('fetch-log', function(event) { ipc.on('fetch-log', function(event) {
event.returnValue = fetch(logPath); fetch(logPath).then(function(data) {
event.sender.send('fetched-log', data);
}, function(error) {
logger.error('Problem loading log from disk: ' + error.stack);
});
}); });
} }
@ -63,23 +67,36 @@ function getLogger() {
return logger; return logger;
} }
function fetch(logPath) { function fetchLog(logFile) {
const files = fs.readdirSync(logPath); return new Promise(function(resolve, reject) {
let contents = ''; 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) {}
}));
files.forEach(function(file) { return resolve(data);
contents += fs.readFileSync(path.join(logPath, file), { encoding: 'utf8' }); });
}); });
}
const lines = _.compact(contents.split('\n')); function fetch(logPath) {
const data = _.compact(lines.map(function(line) { const files = fs.readdirSync(logPath);
try { const paths = files.map(function(file) {
return JSON.parse(line); return path.join(logPath, file)
} });
catch (e) {}
}));
return _.sortBy(data, 'time'); return Promise.all(paths.map(fetchLog)).then(function(results) {
const data = _.flatten(results);
return _.sortBy(data, 'time');
});
} }

@ -90,7 +90,14 @@ function format(entries) {
} }
function fetch() { function fetch() {
return getHeader() + '\n' + format(ipc.sendSync('fetch-log')); return new Promise(function(resolve) {
ipc.send('fetch-log');
ipc.on('fetched-log', function(event, text) {
var result = getHeader() + '\n' + format(text);
resolve(result);
});
});
} }
function publish(log) { function publish(log) {

@ -22,7 +22,11 @@
className: 'debug-log modal', className: 'debug-log modal',
initialize: function() { initialize: function() {
this.render(); this.render();
this.$('textarea').val(log.fetch()); this.$('textarea').val(i18n('loading'));
window.log.fetch().then(function(text) {
this.$('textarea').val(text);
}.bind(this));
}, },
events: { events: {
'click .submit': 'submit', 'click .submit': 'submit',

Loading…
Cancel
Save