mirror of
https://github.com/finos/SymphonyElectron.git
synced 2024-11-21 16:38:41 -06:00
SDA-4408: Experimental Build for logger
This commit is contained in:
parent
f3380b06aa
commit
d1171056db
@ -22,8 +22,6 @@ jest.mock('fs', () => ({
|
|||||||
readFileSync: jest.fn(() => '{"configVersion": "4.0.0"}'),
|
readFileSync: jest.fn(() => '{"configVersion": "4.0.0"}'),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
jest.mock('electron-log');
|
|
||||||
|
|
||||||
jest.mock('../src/common/env', () => {
|
jest.mock('../src/common/env', () => {
|
||||||
return {
|
return {
|
||||||
isWindowsOS: true,
|
isWindowsOS: true,
|
||||||
@ -58,20 +56,6 @@ jest.mock('../src/app/window-actions', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('../src/common/logger', () => {
|
|
||||||
return {
|
|
||||||
logger: {
|
|
||||||
setLoggerWindow: jest.fn(),
|
|
||||||
error: jest.fn(),
|
|
||||||
warn: jest.fn(),
|
|
||||||
info: jest.fn(),
|
|
||||||
verbose: jest.fn(),
|
|
||||||
debug: jest.fn(),
|
|
||||||
silly: jest.fn(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
jest.mock('../src/app/auto-update-handler', () => {
|
jest.mock('../src/app/auto-update-handler', () => {
|
||||||
return {};
|
return {};
|
||||||
});
|
});
|
||||||
|
@ -12,8 +12,6 @@ jest.mock('../src/common/env', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
jest.mock('electron-log');
|
|
||||||
|
|
||||||
describe('logger', () => {
|
describe('logger', () => {
|
||||||
let instance;
|
let instance;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { WebContents } from 'electron';
|
import { WebContents } from 'electron';
|
||||||
import { createConnection, Socket } from 'net';
|
import { createConnection, Socket } from 'net';
|
||||||
import { logger } from '../common/logger';
|
import { logger } from '../common/c9-logger';
|
||||||
|
|
||||||
class C9PipeHandler {
|
class C9PipeHandler {
|
||||||
private _socket: Socket | undefined;
|
private _socket: Socket | undefined;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { app, powerMonitor, WebContents } from 'electron';
|
import { app, powerMonitor, WebContents } from 'electron';
|
||||||
|
import { logger } from '../common/c9-logger';
|
||||||
import { isDevEnv, isWindowsOS } from '../common/env';
|
import { isDevEnv, isWindowsOS } from '../common/env';
|
||||||
import { logger } from '../common/logger';
|
|
||||||
|
|
||||||
import { ChildProcess, spawn } from 'child_process';
|
import { ChildProcess, spawn } from 'child_process';
|
||||||
import * as path from 'path';
|
import * as path from 'path';
|
||||||
|
5
src/common/c9-logger.ts
Normal file
5
src/common/c9-logger.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { Logger } from './loggerBase';
|
||||||
|
|
||||||
|
const logger = new Logger('iv');
|
||||||
|
|
||||||
|
export { logger };
|
@ -1,292 +1,5 @@
|
|||||||
import { app, WebContents } from 'electron';
|
import { Logger } from './loggerBase';
|
||||||
import electronLog, { LogLevel, transports } from 'electron-log';
|
|
||||||
import * as fs from 'fs';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as util from 'util';
|
|
||||||
|
|
||||||
import { isElectronQA, isWindowsOS } from './env';
|
const logger = new Logger('sda');
|
||||||
import { getCommandLineArgs } from './utils';
|
|
||||||
|
|
||||||
export interface ILogMsg {
|
|
||||||
level: LogLevel;
|
|
||||||
details: any;
|
|
||||||
showInConsole: boolean;
|
|
||||||
startTime: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IClientLogMsg {
|
|
||||||
msgs?: ILogMsg[];
|
|
||||||
logLevel?: LogLevel;
|
|
||||||
showInConsole?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const MAX_LOG_QUEUE_LENGTH = 100;
|
|
||||||
|
|
||||||
// Force log path to local path in Windows rather than roaming
|
|
||||||
if (isWindowsOS && process.env.LOCALAPPDATA) {
|
|
||||||
app.setPath('appData', process.env.LOCALAPPDATA);
|
|
||||||
app.setPath('userData', path.join(app.getPath('appData'), app.getName()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Electron wants this to be called initially before calling
|
|
||||||
// app.getPath('logs')
|
|
||||||
app.setAppLogsPath();
|
|
||||||
|
|
||||||
class Logger {
|
|
||||||
private readonly showInConsole: boolean = false;
|
|
||||||
private readonly desiredLogLevel?: LogLevel;
|
|
||||||
private readonly logQueue: ILogMsg[];
|
|
||||||
private readonly logPath: string;
|
|
||||||
private loggerWindow: WebContents | null;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.loggerWindow = null;
|
|
||||||
this.logQueue = [];
|
|
||||||
// If the user has specified a custom log path use it.
|
|
||||||
const customLogPathArg = getCommandLineArgs(
|
|
||||||
process.argv,
|
|
||||||
'--logPath=',
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
const customLogsFolder =
|
|
||||||
customLogPathArg &&
|
|
||||||
customLogPathArg.substring(customLogPathArg.indexOf('=') + 1);
|
|
||||||
if (customLogsFolder) {
|
|
||||||
if (!fs.existsSync(customLogsFolder)) {
|
|
||||||
fs.mkdirSync(customLogsFolder, { recursive: true });
|
|
||||||
}
|
|
||||||
app.setPath('logs', customLogsFolder);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logPath = app.getPath('logs');
|
|
||||||
|
|
||||||
if (app.isPackaged) {
|
|
||||||
transports.file.file = path.join(this.logPath, `app_${Date.now()}.log`);
|
|
||||||
transports.file.level = 'debug';
|
|
||||||
transports.file.format =
|
|
||||||
'{y}-{m}-{d} {h}:{i}:{s}:{ms} {z} | {level} | {text}';
|
|
||||||
transports.file.appName = 'Symphony';
|
|
||||||
}
|
|
||||||
|
|
||||||
const logLevel = getCommandLineArgs(process.argv, '--logLevel=', false);
|
|
||||||
if (logLevel) {
|
|
||||||
const level = logLevel.split('=')[1];
|
|
||||||
if (level) {
|
|
||||||
this.desiredLogLevel = level as LogLevel;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getCommandLineArgs(process.argv, '--enableConsoleLogging', false)) {
|
|
||||||
this.showInConsole = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// cleans up old logs if there are any
|
|
||||||
if (app.isPackaged) {
|
|
||||||
this.cleanupOldLogs();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* get instance of logQueue
|
|
||||||
*/
|
|
||||||
public getLogQueue(): ILogMsg[] {
|
|
||||||
return this.logQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log error
|
|
||||||
*
|
|
||||||
* @param message {string} - message to be logged
|
|
||||||
* @param data {any} - extra data that needs to be logged
|
|
||||||
*/
|
|
||||||
public error(message: string, ...data: any[]): void {
|
|
||||||
this.log('error', message, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log warn
|
|
||||||
*
|
|
||||||
* @param message {string} - message to be logged
|
|
||||||
* @param data {any} - extra data that needs to be logged
|
|
||||||
*/
|
|
||||||
public warn(message: string, ...data: any[]): void {
|
|
||||||
this.log('warn', message, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log info
|
|
||||||
*
|
|
||||||
* @param message {string} - message to be logged
|
|
||||||
* @param data {any} - extra data that needs to be logged
|
|
||||||
*/
|
|
||||||
public info(message: string, ...data: any[]): void {
|
|
||||||
this.log('info', message, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log verbose
|
|
||||||
*
|
|
||||||
* @param message {string} - message to be logged
|
|
||||||
* @param data {array} - extra data that needs to be logged
|
|
||||||
*/
|
|
||||||
public verbose(message: string, ...data: any[]): void {
|
|
||||||
this.log('verbose', message, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log debug
|
|
||||||
*
|
|
||||||
* @param message {string} - message to be logged
|
|
||||||
* @param data {any} - extra data that needs to be logged
|
|
||||||
*/
|
|
||||||
public debug(message: string, ...data: any[]): void {
|
|
||||||
this.log('debug', message, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log silly
|
|
||||||
*
|
|
||||||
* @param message {string} - message to be logged
|
|
||||||
* @param data {any} - extra data that needs to be logged
|
|
||||||
*/
|
|
||||||
public silly(message: string, ...data: any[]): void {
|
|
||||||
this.log('silly', message, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the renderer window for sending logs to the client
|
|
||||||
*
|
|
||||||
* @param window {WebContents} - renderer window
|
|
||||||
*/
|
|
||||||
public setLoggerWindow(window: WebContents): void {
|
|
||||||
this.loggerWindow = window;
|
|
||||||
|
|
||||||
if (this.loggerWindow) {
|
|
||||||
const logMsgs: IClientLogMsg = {};
|
|
||||||
if (this.logQueue.length) {
|
|
||||||
logMsgs.msgs = this.logQueue;
|
|
||||||
}
|
|
||||||
if (this.desiredLogLevel) {
|
|
||||||
logMsgs.logLevel = this.desiredLogLevel;
|
|
||||||
}
|
|
||||||
if (Object.keys(logMsgs).length) {
|
|
||||||
this.loggerWindow.send('log', logMsgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main instance of the logger method
|
|
||||||
*
|
|
||||||
* @param logLevel {LogLevel} - Different type of log levels
|
|
||||||
* @param message {string} - Log message
|
|
||||||
* @param data {array} - extra data to be logged
|
|
||||||
* @param sendToCloud {boolean} - wehether to send the logs on to cloud
|
|
||||||
*/
|
|
||||||
public log(
|
|
||||||
logLevel: LogLevel,
|
|
||||||
message: string,
|
|
||||||
data: any[] = [],
|
|
||||||
sendToCloud: boolean = true,
|
|
||||||
): void {
|
|
||||||
if (data && data.length > 0) {
|
|
||||||
data.forEach((param) => {
|
|
||||||
message += `, '${param && typeof param}': ${JSON.stringify(param)}`;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!isElectronQA) {
|
|
||||||
switch (logLevel) {
|
|
||||||
case 'error':
|
|
||||||
electronLog.error(message);
|
|
||||||
break;
|
|
||||||
case 'warn':
|
|
||||||
electronLog.warn(message);
|
|
||||||
break;
|
|
||||||
case 'info':
|
|
||||||
electronLog.info(message);
|
|
||||||
break;
|
|
||||||
case 'verbose':
|
|
||||||
electronLog.verbose(message);
|
|
||||||
break;
|
|
||||||
case 'debug':
|
|
||||||
electronLog.debug(message);
|
|
||||||
break;
|
|
||||||
case 'silly':
|
|
||||||
electronLog.silly(message);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
electronLog.info(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (sendToCloud) {
|
|
||||||
this.sendToCloud(this.formatLogMsg(logLevel, message));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Formats the logs in the format that required
|
|
||||||
* to send to the client
|
|
||||||
*
|
|
||||||
* @param level {LogLevel} - Different type of log levels
|
|
||||||
* @param details {any} - log format that required to send to client
|
|
||||||
*/
|
|
||||||
private formatLogMsg(level: LogLevel, details: any): ILogMsg {
|
|
||||||
return {
|
|
||||||
details,
|
|
||||||
level,
|
|
||||||
showInConsole: this.showInConsole,
|
|
||||||
startTime: Date.now(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This will send the logs to the client if loggerWindow
|
|
||||||
* else adds the logs to a Queue
|
|
||||||
*
|
|
||||||
* @param logMsg {ILogMsg}
|
|
||||||
*/
|
|
||||||
private sendToCloud(logMsg: ILogMsg): void {
|
|
||||||
// don't send logs if it is not desired by the user
|
|
||||||
if (this.desiredLogLevel && this.desiredLogLevel !== logMsg.level) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.loggerWindow && !this.loggerWindow.isDestroyed()) {
|
|
||||||
this.loggerWindow.send('log', {
|
|
||||||
msgs: [logMsg],
|
|
||||||
logLevel: this.desiredLogLevel,
|
|
||||||
showInConsole: this.showInConsole,
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logQueue.push(logMsg);
|
|
||||||
// don't store more than 100 msgs. keep most recent log msgs.
|
|
||||||
if (this.logQueue.length > MAX_LOG_QUEUE_LENGTH) {
|
|
||||||
this.logQueue.shift();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cleans up logs older than a day
|
|
||||||
*/
|
|
||||||
private cleanupOldLogs(): void {
|
|
||||||
const files = fs.readdirSync(this.logPath);
|
|
||||||
const deleteTimeStamp = new Date().getTime() - 5 * 24 * 60 * 60 * 1000;
|
|
||||||
files.forEach((file) => {
|
|
||||||
// nosemgrep
|
|
||||||
const filePath = path.join(this.logPath, file);
|
|
||||||
if (fs.existsSync(filePath)) {
|
|
||||||
const stat = fs.statSync(filePath);
|
|
||||||
const fileTimestamp = new Date(util.inspect(stat.mtime)).getTime();
|
|
||||||
if (fileTimestamp < deleteTimeStamp) {
|
|
||||||
fs.unlinkSync(filePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const logger = new Logger();
|
|
||||||
|
|
||||||
export { logger };
|
export { logger };
|
||||||
|
295
src/common/loggerBase.ts
Normal file
295
src/common/loggerBase.ts
Normal file
@ -0,0 +1,295 @@
|
|||||||
|
import { app, WebContents } from 'electron';
|
||||||
|
import { create, ElectronLog, LogLevel } from 'electron-log';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as util from 'util';
|
||||||
|
|
||||||
|
import { isElectronQA, isWindowsOS } from './env';
|
||||||
|
import { getCommandLineArgs } from './utils';
|
||||||
|
|
||||||
|
export interface ILogMsg {
|
||||||
|
level: LogLevel;
|
||||||
|
details: any;
|
||||||
|
showInConsole: boolean;
|
||||||
|
startTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IClientLogMsg {
|
||||||
|
msgs?: ILogMsg[];
|
||||||
|
logLevel?: LogLevel;
|
||||||
|
showInConsole?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const MAX_LOG_QUEUE_LENGTH = 100;
|
||||||
|
|
||||||
|
// Force log path to local path in Windows rather than roaming
|
||||||
|
if (isWindowsOS && process.env.LOCALAPPDATA) {
|
||||||
|
app.setPath('appData', process.env.LOCALAPPDATA);
|
||||||
|
app.setPath('userData', path.join(app.getPath('appData'), app.getName()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Electron wants this to be called initially before calling
|
||||||
|
// app.getPath('logs')
|
||||||
|
app.setAppLogsPath();
|
||||||
|
|
||||||
|
export class Logger {
|
||||||
|
private readonly showInConsole: boolean = false;
|
||||||
|
private readonly desiredLogLevel?: LogLevel;
|
||||||
|
private readonly logQueue: ILogMsg[];
|
||||||
|
private readonly logPath: string;
|
||||||
|
private loggerWindow: WebContents | null;
|
||||||
|
private electronLog: ElectronLog;
|
||||||
|
private logName: string;
|
||||||
|
|
||||||
|
constructor(logName: string) {
|
||||||
|
this.logName = logName;
|
||||||
|
this.electronLog = create(logName);
|
||||||
|
this.loggerWindow = null;
|
||||||
|
this.logQueue = [];
|
||||||
|
// If the user has specified a custom log path use it.
|
||||||
|
const customLogPathArg = getCommandLineArgs(
|
||||||
|
process.argv,
|
||||||
|
'--logPath=',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
const customLogsFolder =
|
||||||
|
customLogPathArg &&
|
||||||
|
customLogPathArg.substring(customLogPathArg.indexOf('=') + 1);
|
||||||
|
if (customLogsFolder) {
|
||||||
|
if (!fs.existsSync(customLogsFolder)) {
|
||||||
|
fs.mkdirSync(customLogsFolder, { recursive: true });
|
||||||
|
}
|
||||||
|
app.setPath('logs', customLogsFolder);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logPath = app.getPath('logs');
|
||||||
|
|
||||||
|
if (app.isPackaged) {
|
||||||
|
this.electronLog.transports.file.file = path.join(
|
||||||
|
this.logPath,
|
||||||
|
`${this.logName}_${Date.now()}.log`,
|
||||||
|
);
|
||||||
|
this.electronLog.transports.file.level = 'debug';
|
||||||
|
this.electronLog.transports.file.format =
|
||||||
|
'{y}-{m}-{d} {h}:{i}:{s}:{ms} {z} | {level} | {text}';
|
||||||
|
this.electronLog.transports.file.appName = 'Symphony';
|
||||||
|
}
|
||||||
|
|
||||||
|
const logLevel = getCommandLineArgs(process.argv, '--logLevel=', false);
|
||||||
|
if (logLevel) {
|
||||||
|
const level = logLevel.split('=')[1];
|
||||||
|
if (level) {
|
||||||
|
this.desiredLogLevel = level as LogLevel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getCommandLineArgs(process.argv, '--enableConsoleLogging', false)) {
|
||||||
|
this.showInConsole = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// cleans up old logs if there are any
|
||||||
|
if (app.isPackaged) {
|
||||||
|
this.cleanupOldLogs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get instance of logQueue
|
||||||
|
*/
|
||||||
|
public getLogQueue(): ILogMsg[] {
|
||||||
|
return this.logQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log error
|
||||||
|
*
|
||||||
|
* @param message {string} - message to be logged
|
||||||
|
* @param data {any} - extra data that needs to be logged
|
||||||
|
*/
|
||||||
|
public error(message: string, ...data: any[]): void {
|
||||||
|
this.log('error', message, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log warn
|
||||||
|
*
|
||||||
|
* @param message {string} - message to be logged
|
||||||
|
* @param data {any} - extra data that needs to be logged
|
||||||
|
*/
|
||||||
|
public warn(message: string, ...data: any[]): void {
|
||||||
|
this.log('warn', message, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log info
|
||||||
|
*
|
||||||
|
* @param message {string} - message to be logged
|
||||||
|
* @param data {any} - extra data that needs to be logged
|
||||||
|
*/
|
||||||
|
public info(message: string, ...data: any[]): void {
|
||||||
|
this.log('info', message, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log verbose
|
||||||
|
*
|
||||||
|
* @param message {string} - message to be logged
|
||||||
|
* @param data {array} - extra data that needs to be logged
|
||||||
|
*/
|
||||||
|
public verbose(message: string, ...data: any[]): void {
|
||||||
|
this.log('verbose', message, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log debug
|
||||||
|
*
|
||||||
|
* @param message {string} - message to be logged
|
||||||
|
* @param data {any} - extra data that needs to be logged
|
||||||
|
*/
|
||||||
|
public debug(message: string, ...data: any[]): void {
|
||||||
|
this.log('debug', message, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log silly
|
||||||
|
*
|
||||||
|
* @param message {string} - message to be logged
|
||||||
|
* @param data {any} - extra data that needs to be logged
|
||||||
|
*/
|
||||||
|
public silly(message: string, ...data: any[]): void {
|
||||||
|
this.log('silly', message, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the renderer window for sending logs to the client
|
||||||
|
*
|
||||||
|
* @param window {WebContents} - renderer window
|
||||||
|
*/
|
||||||
|
public setLoggerWindow(window: WebContents): void {
|
||||||
|
this.loggerWindow = window;
|
||||||
|
|
||||||
|
if (this.loggerWindow) {
|
||||||
|
const logMsgs: IClientLogMsg = {};
|
||||||
|
if (this.logQueue.length) {
|
||||||
|
logMsgs.msgs = this.logQueue;
|
||||||
|
}
|
||||||
|
if (this.desiredLogLevel) {
|
||||||
|
logMsgs.logLevel = this.desiredLogLevel;
|
||||||
|
}
|
||||||
|
if (Object.keys(logMsgs).length) {
|
||||||
|
this.loggerWindow.send('log', logMsgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main instance of the logger method
|
||||||
|
*
|
||||||
|
* @param logLevel {LogLevel} - Different type of log levels
|
||||||
|
* @param message {string} - Log message
|
||||||
|
* @param data {array} - extra data to be logged
|
||||||
|
* @param sendToCloud {boolean} - wehether to send the logs on to cloud
|
||||||
|
*/
|
||||||
|
public log(
|
||||||
|
logLevel: LogLevel,
|
||||||
|
message: string,
|
||||||
|
data: any[] = [],
|
||||||
|
sendToCloud: boolean = true,
|
||||||
|
): void {
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
data.forEach((param) => {
|
||||||
|
message += `, '${param && typeof param}': ${JSON.stringify(param)}`;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!isElectronQA) {
|
||||||
|
switch (logLevel) {
|
||||||
|
case 'error':
|
||||||
|
this.electronLog.error(message);
|
||||||
|
break;
|
||||||
|
case 'warn':
|
||||||
|
this.electronLog.warn(message);
|
||||||
|
break;
|
||||||
|
case 'info':
|
||||||
|
this.electronLog.info(message);
|
||||||
|
break;
|
||||||
|
case 'verbose':
|
||||||
|
this.electronLog.verbose(message);
|
||||||
|
break;
|
||||||
|
case 'debug':
|
||||||
|
this.electronLog.debug(message);
|
||||||
|
break;
|
||||||
|
case 'silly':
|
||||||
|
this.electronLog.silly(message);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.electronLog.info(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sendToCloud) {
|
||||||
|
this.sendToCloud(this.formatLogMsg(logLevel, message));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the logs in the format that required
|
||||||
|
* to send to the client
|
||||||
|
*
|
||||||
|
* @param level {LogLevel} - Different type of log levels
|
||||||
|
* @param details {any} - log format that required to send to client
|
||||||
|
*/
|
||||||
|
private formatLogMsg(level: LogLevel, details: any): ILogMsg {
|
||||||
|
return {
|
||||||
|
details,
|
||||||
|
level,
|
||||||
|
showInConsole: this.showInConsole,
|
||||||
|
startTime: Date.now(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will send the logs to the client if loggerWindow
|
||||||
|
* else adds the logs to a Queue
|
||||||
|
*
|
||||||
|
* @param logMsg {ILogMsg}
|
||||||
|
*/
|
||||||
|
private sendToCloud(logMsg: ILogMsg): void {
|
||||||
|
// don't send logs if it is not desired by the user
|
||||||
|
if (this.desiredLogLevel && this.desiredLogLevel !== logMsg.level) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.loggerWindow && !this.loggerWindow.isDestroyed()) {
|
||||||
|
this.loggerWindow.send('log', {
|
||||||
|
msgs: [logMsg],
|
||||||
|
logLevel: this.desiredLogLevel,
|
||||||
|
showInConsole: this.showInConsole,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logQueue.push(logMsg);
|
||||||
|
// don't store more than 100 msgs. keep most recent log msgs.
|
||||||
|
if (this.logQueue.length > MAX_LOG_QUEUE_LENGTH) {
|
||||||
|
this.logQueue.shift();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans up logs older than a day
|
||||||
|
*/
|
||||||
|
private cleanupOldLogs(): void {
|
||||||
|
const files = fs.readdirSync(this.logPath);
|
||||||
|
const deleteTimeStamp = new Date().getTime() - 5 * 24 * 60 * 60 * 1000;
|
||||||
|
files.forEach((file) => {
|
||||||
|
// nosemgrep
|
||||||
|
const filePath = path.join(this.logPath, file);
|
||||||
|
if (fs.existsSync(filePath)) {
|
||||||
|
const stat = fs.statSync(filePath);
|
||||||
|
const fileTimestamp = new Date(util.inspect(stat.mtime)).getTime();
|
||||||
|
if (fileTimestamp < deleteTimeStamp) {
|
||||||
|
fs.unlinkSync(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user