Frontend global loggers (#192)

* frontend logging added
This commit is contained in:
kylezs 2020-09-23 08:58:03 +10:00 committed by GitHub
parent 9d55072a99
commit 9fb4ab3646
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 109 additions and 4 deletions

1
.prettierrc.js Normal file
View File

@ -0,0 +1 @@
// intentionally blank

View File

@ -26,7 +26,11 @@ let installUpdate = false;
const title = `${productName} v${version}`;
const selectionMenu = Menu.buildFromTemplate([{ role: "copy" }, { type: "separator" }, { role: "selectall" }]);
const selectionMenu = Menu.buildFromTemplate([
{ role: "copy" },
{ type: "separator" },
{ role: "selectall" }
]);
const inputMenu = Menu.buildFromTemplate([
{ role: "cut" },
@ -54,7 +58,13 @@ function createWindow() {
minWidth: 640,
minHeight: 480,
icon: require("path").join(__statics, "icon_512x512.png"),
title
title,
webPreferences: {
nodeIntegration: true,
nodeIntegrationInWorker: true,
// anything we want preloaded, e.g. global vars
preload: path.resolve(__dirname, "electron-preload.js")
}
});
mainWindow.on("close", e => {

View File

@ -0,0 +1,3 @@
const path = require("upath");
require(path.resolve(__dirname, "logging.js"));

View File

@ -0,0 +1,78 @@
// This allows for logging (to a file) from the frontend by creating global logging functions
// That send ipc calls (from renderer) to the electron main process
// create global logging functions for the frontend. It sends messages to the main
// process which then log to file
const electron = require("electron");
const _ = require("lodash");
const ipc = electron.ipcRenderer;
function log(...args) {
logAtLevel("info", "INFO ", ...args);
}
if (window.console) {
console._log = console.log;
console.log = log;
console._trace = console.trace;
console._debug = console.debug;
console._info = console.info;
console._warn = console.warn;
console._error = console.error;
console._fatal = console.error;
}
// To avoid [Object object] in our log since console.log handles non-strings
// smoothly
function cleanArgsForIPC(args) {
const str = args.map(item => {
if (typeof item !== "string") {
try {
return JSON.stringify(item);
} catch (error) {
return item;
}
}
return item;
});
return str.join(" ");
}
// Backwards-compatible logging, simple strings and no level (defaulted to INFO)
function now() {
const date = new Date();
return date.toJSON();
}
// The Bunyan API: https://github.com/trentm/node-bunyan#log-method-api
function logAtLevel(level, prefix, ...args) {
const fn = `_${level}`;
console[fn](prefix, now(), ...args);
const logText = cleanArgsForIPC(args);
ipc.send(`log-${level}`, logText);
}
window.log = {
fatal: _.partial(logAtLevel, "fatal", "FATAL"),
error: _.partial(logAtLevel, "error", "ERROR"),
warn: _.partial(logAtLevel, "warn", "WARN "),
info: _.partial(logAtLevel, "info", "INFO "),
debug: _.partial(logAtLevel, "debug", "DEBUG"),
trace: _.partial(logAtLevel, "trace", "TRACE")
};
window.onerror = (message, script, line, col, error) => {
const errorInfo = error && error.stack ? error.stack : JSON.stringify(error);
window.log.error(`Top-level unhandled error: ${errorInfo}`);
};
window.addEventListener("unhandledrejection", rejectionEvent => {
const error = rejectionEvent.reason;
const errorInfo = error && error.stack ? error.stack : error;
window.log.error("Top-level unhandled promise rejection:", errorInfo);
});

View File

@ -8,11 +8,16 @@ import { version } from "../../../package.json";
const bunyan = require("bunyan");
const WebSocket = require("ws");
const electron = require("electron");
const os = require("os");
const fs = require("fs-extra");
const path = require("upath");
const objectAssignDeep = require("object-assign-deep");
const { ipcMain: ipc } = electron;
const LOG_LEVELS = ["fatal", "error", "warn", "info", "debug", "trace"];
export class Backend {
constructor(mainWindow) {
this.mainWindow = mainWindow;
@ -355,12 +360,20 @@ export class Backend {
name: "log",
streams: [
{
level: "debug",
path: path.join(logPath, "electron.log")
type: "rotating-file",
path: path.join(logPath, "electron.log"),
period: "1d", // daily rotation
count: 4 // keep 4 days of logs
}
]
});
LOG_LEVELS.forEach(level => {
ipc.on(`log-${level}`, (first, ...rest) => {
log[level](...rest);
});
});
this.log = log;
process.on("uncaughtException", error => {