import { ILogger, ILogExporter } from '@lenovo-software/lsa-clients-common'; import { LSAClient } from '@lenovo-software/lsa-clients-common'; const SEVERITY = { INFO: 'INFO', WARN: 'WARN', DEBUG: 'DEBUG', ERROR: 'ERROR' }; const severityLogFncMap = { [SEVERITY.INFO]: 'log', [SEVERITY.WARN]: 'warn', [SEVERITY.ERROR]: 'error', [SEVERITY.DEBUG]: 'debug' }; export class Logger implements ILogger { private static instance: Logger; //the background page will be the master logger. all other pages will send messages to this logger private isMaster: boolean = location.href.includes('background'); public static getInstance(isMaster = false) { if (!Logger.instance) { if (isMaster) { Logger.instance = new Logger(LSAClient.getInstance().logExporter); } else { Logger.instance = new Logger(); } } return Logger.instance; } private constructor(private exporter?: ILogExporter) { if (this.isMaster) { chrome.runtime.onMessage.addListener((request) => { if (request.message === 'WebViewLogMessage' && this.isMaster) { this.doLog(request.severity, `${this.addLogPrefix(request.fromPage)}${request.msg}`); } }); } } private sendLogToMaster(severity: any, msg: string) { chrome.runtime.sendMessage({ message: 'WebViewLogMessage', fromPage: location.pathname.substring(1, location.pathname.length - 5), severity, msg }); } public logInfo(msg: string) { this.logMessage(msg); } public logDebug(msg: string): void { this.exporter?.logDebug(msg); if (this.isMaster) { this.doLog(SEVERITY.DEBUG, this.addBackgroundPrefix(msg)); } else { this.sendLogToMaster(SEVERITY.DEBUG, msg); } } public logMessage(msg: string): void { this.exporter?.logMessage(msg); if (this.isMaster) { this.doLog(SEVERITY.INFO, this.addBackgroundPrefix(msg)); } else { this.sendLogToMaster(SEVERITY.INFO, msg); } } public logWarning(msg: string): void { this.exporter?.logWarning(msg); if (this.isMaster) { this.doLog(SEVERITY.WARN, this.addBackgroundPrefix(msg)); } else { this.sendLogToMaster(SEVERITY.WARN, msg); } } public logError(msg: string): void { this.exporter?.logError(msg); if (this.isMaster) { this.doLog(SEVERITY.ERROR, this.addBackgroundPrefix(msg)); } else { this.sendLogToMaster(SEVERITY.ERROR, msg); } } private doLog(severity: any, msg: string) { const consoleFnc = severityLogFncMap[severity]; //@ts-ignore if (console[consoleFnc]) { //@ts-ignore console[consoleFnc](msg); } } private addLogPrefix(page: string): string { return `[${page.toUpperCase()}][${this.timeStampMS(true)}]:`; } private addBackgroundPrefix(msg: string) { return this.addLogPrefix('background') + msg; } // Used by socketio_message.js public timeStampMS(doMS: boolean): string { // Create a date object with the current time const now = new Date(); const date = [now.getMonth() + 1, now.getDate(), now.getFullYear()]; const time: string[] = [now.getHours().toString(), now.getMinutes().toString(), now.getSeconds().toString()]; // tslint:disable-next-line: variable-name const time_ms = now.getMilliseconds(); // If seconds and minutes are less than 10, add a zero for (let i = 1; i < 3; i++) { if (Number(time[i]) < 10) { time[i] = '0' + time[i]; } } // Return the formatted string let dateTime = date.join('/') + ' ' + time.join(':'); if (doMS) { dateTime += '.' + time_ms; } return dateTime; } }