UNPKG

electron-log

Version:

Just a simple logging module for your Electron application

215 lines (182 loc) 5.47 kB
'use strict'; const scopeFactory = require('./scope'); const Buffering = require('./Buffering'); /** * @property {Function} error * @property {Function} warn * @property {Function} info * @property {Function} verbose * @property {Function} debug * @property {Function} silly */ class Logger { static instances = {}; dependencies = {}; errorHandler = null; eventLogger = null; functions = {}; hooks = []; isDev = false; levels = null; logId = null; scope = null; transports = {}; variables = {}; constructor({ allowUnknownLevel = false, dependencies = {}, errorHandler, eventLogger, initializeFn, isDev = false, levels = ['error', 'warn', 'info', 'verbose', 'debug', 'silly'], logId, transportFactories = {}, variables, } = {}) { this.addLevel = this.addLevel.bind(this); this.create = this.create.bind(this); this.initialize = this.initialize.bind(this); this.logData = this.logData.bind(this); this.processMessage = this.processMessage.bind(this); this.allowUnknownLevel = allowUnknownLevel; this.buffering = new Buffering(this); this.dependencies = dependencies; this.initializeFn = initializeFn; this.isDev = isDev; this.levels = levels; this.logId = logId; this.scope = scopeFactory(this); this.transportFactories = transportFactories; this.variables = variables || {}; for (const name of this.levels) { this.addLevel(name, false); } this.log = this.info; this.functions.log = this.log; this.errorHandler = errorHandler; errorHandler?.setOptions({ ...dependencies, logFn: this.error }); this.eventLogger = eventLogger; eventLogger?.setOptions({ ...dependencies, logger: this }); for (const [name, factory] of Object.entries(transportFactories)) { this.transports[name] = factory(this, dependencies); } Logger.instances[logId] = this; } static getInstance({ logId }) { return this.instances[logId] || this.instances.default; } addLevel(level, index = this.levels.length) { if (index !== false) { this.levels.splice(index, 0, level); } this[level] = (...args) => this.logData(args, { level }); this.functions[level] = this[level]; } catchErrors(options) { this.processMessage( { data: ['log.catchErrors is deprecated. Use log.errorHandler instead'], level: 'warn', }, { transports: ['console'] }, ); return this.errorHandler.startCatching(options); } create(options) { if (typeof options === 'string') { options = { logId: options }; } return new Logger({ dependencies: this.dependencies, errorHandler: this.errorHandler, initializeFn: this.initializeFn, isDev: this.isDev, transportFactories: this.transportFactories, variables: { ...this.variables }, ...options, }); } compareLevels(passLevel, checkLevel, levels = this.levels) { const pass = levels.indexOf(passLevel); const check = levels.indexOf(checkLevel); if (check === -1 || pass === -1) { return true; } return check <= pass; } initialize(options = {}) { this.initializeFn({ logger: this, ...this.dependencies, ...options }); } logData(data, options = {}) { if (this.buffering.enabled) { this.buffering.addMessage({ data, date: new Date(), ...options }); } else { this.processMessage({ data, ...options }); } } processMessage(message, { transports = this.transports } = {}) { if (message.cmd === 'errorHandler') { this.errorHandler.handle(message.error, { errorName: message.errorName, processType: 'renderer', showDialog: Boolean(message.showDialog), }); return; } let level = message.level; if (!this.allowUnknownLevel) { level = this.levels.includes(message.level) ? message.level : 'info'; } const normalizedMessage = { date: new Date(), logId: this.logId, ...message, level, variables: { ...this.variables, ...message.variables, }, }; for (const [transName, transFn] of this.transportEntries(transports)) { if (typeof transFn !== 'function' || transFn.level === false) { continue; } if (!this.compareLevels(transFn.level, message.level)) { continue; } try { // eslint-disable-next-line arrow-body-style const transformedMsg = this.hooks.reduce((msg, hook) => { return msg ? hook(msg, transFn, transName) : msg; }, normalizedMessage); if (transformedMsg) { transFn({ ...transformedMsg, data: [...transformedMsg.data] }); } } catch (e) { this.processInternalErrorFn(e); } } } processInternalErrorFn(_e) { // Do nothing by default } transportEntries(transports = this.transports) { const transportArray = Array.isArray(transports) ? transports : Object.entries(transports); return transportArray .map((item) => { switch (typeof item) { case 'string': return this.transports[item] ? [item, this.transports[item]] : null; case 'function': return [item.name, item]; default: return Array.isArray(item) ? item : null; } }) .filter(Boolean); } } module.exports = Logger;