diff --git a/src/common/Validator.ts b/src/common/Validator.ts index 43468a78..388d6273 100644 --- a/src/common/Validator.ts +++ b/src/common/Validator.ts @@ -1,6 +1,5 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import log from 'electron-log'; import Joi from 'joi'; @@ -12,9 +11,11 @@ import {AppState} from 'types/appState'; import {ComparableCertificate} from 'types/certificate'; import {PermissionType, TrustedOrigin} from 'types/trustedOrigin'; +import {Logger} from 'common/log'; import {TAB_MESSAGING} from 'common/tabs/TabView'; import urlUtils from 'common/utils/url'; +const log = new Logger('Validator'); const defaultOptions = { stripUnknown: true, }; diff --git a/src/common/config/RegistryConfig.ts b/src/common/config/RegistryConfig.ts index eb18c40a..c7292908 100644 --- a/src/common/config/RegistryConfig.ts +++ b/src/common/config/RegistryConfig.ts @@ -3,12 +3,14 @@ // See LICENSE.txt for license information. import {EventEmitter} from 'events'; -import log from 'electron-log'; import WindowsRegistry from 'winreg'; import WindowsRegistryUTF8 from 'winreg-utf8'; import {RegistryConfig as RegistryConfigType, Team} from 'types/config'; +import {Logger} from 'common/log'; + +const log = new Logger('RegistryConfig'); const REGISTRY_HIVE_LIST = [WindowsRegistry.HKLM, WindowsRegistry.HKCU]; const BASE_REGISTRY_KEY_PATH = '\\Software\\Policies\\Mattermost'; export const REGISTRY_READ_EVENT = 'registry-read'; @@ -42,7 +44,7 @@ export default class RegistryConfig extends EventEmitter { this.data.teams!.push(...servers); } } catch (error) { - log.warn('[RegistryConfig] Nothing retrieved for \'DefaultServerList\'', error); + log.warn('Nothing retrieved for \'DefaultServerList\'', error); } // extract EnableServerManagement from the registry @@ -52,7 +54,7 @@ export default class RegistryConfig extends EventEmitter { this.data.enableServerManagement = enableServerManagement; } } catch (error) { - log.warn('[RegistryConfig] Nothing retrieved for \'EnableServerManagement\'', error); + log.warn('Nothing retrieved for \'EnableServerManagement\'', error); } // extract EnableAutoUpdater from the registry @@ -62,7 +64,7 @@ export default class RegistryConfig extends EventEmitter { this.data.enableAutoUpdater = enableAutoUpdater; } } catch (error) { - log.warn('[RegistryConfig] Nothing retrieved for \'EnableAutoUpdater\'', error); + log.warn('Nothing retrieved for \'EnableAutoUpdater\'', error); } } @@ -161,9 +163,9 @@ export default class RegistryConfig extends EventEmitter { } handleRegistryEntryError(e: Error, hive: string, key: string, name?: string, utf8?: boolean) { - log.verbose('There was an error accessing the registry for', {hive, key, name, utf8}, e); + log.debug('There was an error accessing the registry for', {hive, key, name, utf8}, e); if (utf8) { - log.verbose('Trying without UTF-8...', {hive, key, name}); + log.debug('Trying without UTF-8...', {hive, key, name}); return this.getRegistryEntryValues(hive, key, name, false); } diff --git a/src/common/config/index.ts b/src/common/config/index.ts index 08e398f4..8c258015 100644 --- a/src/common/config/index.ts +++ b/src/common/config/index.ts @@ -8,7 +8,6 @@ import path from 'path'; import {EventEmitter} from 'events'; import {ipcMain, nativeTheme, app} from 'electron'; -import log from 'electron-log'; import { AnyConfig, @@ -22,7 +21,7 @@ import { import {UPDATE_TEAMS, GET_CONFIGURATION, UPDATE_CONFIGURATION, GET_LOCAL_CONFIGURATION, UPDATE_PATHS} from 'common/communication'; import * as Validator from 'common/Validator'; - +import {Logger} from 'common/log'; import {getDefaultTeamWithTabsFromTeam} from 'common/tabs/TabView'; import Utils from 'common/utils/util'; @@ -34,6 +33,8 @@ import buildConfig from './buildConfig'; import RegistryConfig, {REGISTRY_READ_EVENT} from './RegistryConfig'; import migrateConfigItems from './migrationPreferences'; +const log = new Logger('Config'); + /** * Handles loading and merging all sources of configuration as well as saving user provided config */ @@ -160,7 +161,7 @@ export class Config extends EventEmitter { * @param {*} data value to save for provided key */ set = (key: keyof ConfigType, data: ConfigType[keyof ConfigType]): void => { - log.debug('Config.set'); + log.debug('set'); this.setMultiple({[key]: data}); } @@ -184,7 +185,7 @@ export class Config extends EventEmitter { * @param {array} properties an array of config properties to save */ setMultiple = (newData: Partial) => { - log.debug('Config.setMultiple', newData); + log.debug('setMultiple', newData); this.localConfigData = Object.assign({}, this.localConfigData, newData); if (newData.teams && this.localConfigData) { diff --git a/src/common/log.test.js b/src/common/log.test.js new file mode 100644 index 00000000..0f73089b --- /dev/null +++ b/src/common/log.test.js @@ -0,0 +1,60 @@ +// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import log from 'electron-log'; + +import {Logger} from 'common/log'; +import Util from 'common/utils/util'; + +jest.unmock('common/log'); + +jest.mock('electron-log', () => ({ + log: jest.fn(), +})); + +jest.mock('common/utils/util', () => ({ + shorten: jest.fn(), +})); + +describe('common/log', () => { + describe('withPrefix', () => { + beforeEach(() => { + Util.shorten.mockImplementation((string) => { + const maxLength = 20; + if (string.length >= maxLength) { + return `${string.slice(0, maxLength - 3)}...`; + } + return string; + }); + }); + + afterEach(() => { + jest.clearAllMocks(); + }); + + it('should just print the log item without prefixes if not provided', () => { + const logger = new Logger(); + logger.log('test item'); + expect(log.log).toBeCalledWith('test item'); + }); + + it('should print the log item with a prefix', () => { + const logger = new Logger('prefix'); + logger.log('test item'); + expect(log.log).toBeCalledWith('[prefix]', 'test item'); + }); + + it('should allow for multiple prefixes', () => { + const logger = new Logger('prefix1', 'prefix2'); + logger.log('test item'); + expect(log.log).toBeCalledWith('[prefix1]', '[prefix2]', 'test item'); + }); + + it('should truncate really long prefixes', () => { + const logger = new Logger('a really really really long prefix'); + logger.log('test item'); + expect(log.log).toBeCalledWith('[a really really r...]', 'test item'); + }); + }); +}); + diff --git a/src/common/log.ts b/src/common/log.ts new file mode 100644 index 00000000..cf52f2f5 --- /dev/null +++ b/src/common/log.ts @@ -0,0 +1,52 @@ +// Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +import log, {LevelOption} from 'electron-log'; + +import Util from 'common/utils/util'; + +export const setLoggingLevel = (level: string) => { + if (log.transports.file.level === level) { + return; + } + log.error('Logger', 'Log level set to:', level); + + log.transports.console.level = level as LevelOption; + log.transports.file.level = level as LevelOption; +}; + +export class Logger { + private prefixes: string[]; + + constructor(...prefixes: string[]) { + this.prefixes = this.shortenPrefixes(...prefixes); + } + + withPrefix = (...prefixes: string[]) => { + return { + error: this.prefixed(log.error, ...prefixes), + warn: this.prefixed(log.warn, ...prefixes), + info: this.prefixed(log.info, ...prefixes), + verbose: this.prefixed(log.verbose, ...prefixes), + debug: this.prefixed(log.debug, ...prefixes), + silly: this.prefixed(log.silly, ...prefixes), + log: this.prefixed(log.log, ...prefixes), + }; + } + + private prefixed = (func: (...args: any[]) => void, ...additionalPrefixes: string[]) => { + return (...args: any[]) => func(...this.prefixes, ...this.shortenPrefixes(...additionalPrefixes), ...args); + } + + private shortenPrefixes = (...prefixes: string[]) => { + return prefixes.map((prefix) => `[${Util.shorten(prefix)}]`); + } + + error = this.prefixed(log.error); + warn = this.prefixed(log.warn); + info = this.prefixed(log.info); + verbose = this.prefixed(log.verbose); + debug = this.prefixed(log.debug); + silly = this.prefixed(log.silly); + log = this.prefixed(log.log); +} diff --git a/src/jest/jestSetup.js b/src/jest/jestSetup.js index c8b1b1e8..c563fbf0 100644 --- a/src/jest/jestSetup.js +++ b/src/jest/jestSetup.js @@ -12,7 +12,7 @@ jest.mock('main/constants', () => ({ updatePaths: jest.fn(), })); -jest.mock('electron-log', () => { +jest.mock('common/log', () => { const logLevelsFn = { error: jest.fn(), warn: jest.fn(), @@ -22,15 +22,13 @@ jest.mock('electron-log', () => { silly: jest.fn(), }; return { - create: jest.fn(() => ({ + Logger: jest.fn().mockImplementation(() => ({ ...logLevelsFn, + withPrefix: () => ({ + ...logLevelsFn, + }), })), - ...logLevelsFn, - transports: { - file: { - level: '', - }, - }, + setLoggingLevel: jest.fn(), }; }); diff --git a/src/main/AutoLauncher.ts b/src/main/AutoLauncher.ts index ccfda780..a173489b 100644 --- a/src/main/AutoLauncher.ts +++ b/src/main/AutoLauncher.ts @@ -5,7 +5,10 @@ import AutoLaunch from 'auto-launch'; import {app} from 'electron'; import isDev from 'electron-is-dev'; -import log from 'electron-log'; + +import {Logger} from 'common/log'; + +const log = new Logger('AutoLauncher'); export class AutoLauncher { appLauncher: AutoLaunch; diff --git a/src/main/CriticalErrorHandler.ts b/src/main/CriticalErrorHandler.ts index dc8aaefa..4c05d404 100644 --- a/src/main/CriticalErrorHandler.ts +++ b/src/main/CriticalErrorHandler.ts @@ -8,10 +8,13 @@ import os from 'os'; import path from 'path'; import {app, dialog} from 'electron'; -import log from 'electron-log'; + +import {Logger} from 'common/log'; import {localizeMessage} from 'main/i18nManager'; +const log = new Logger('CriticalErrorHandler'); + export class CriticalErrorHandler { init = () => { process.on('unhandledRejection', this.processUncaughtExceptionHandler); diff --git a/src/main/UserActivityMonitor.ts b/src/main/UserActivityMonitor.ts index 7178f616..71b8f20a 100644 --- a/src/main/UserActivityMonitor.ts +++ b/src/main/UserActivityMonitor.ts @@ -4,7 +4,10 @@ import {EventEmitter} from 'events'; import {app, powerMonitor} from 'electron'; -import log from 'electron-log'; + +import {Logger} from 'common/log'; + +const log = new Logger('UserActivityMonitor'); /** * Monitors system idle time, listens for system events and fires status updates as needed diff --git a/src/main/allowProtocolDialog.ts b/src/main/allowProtocolDialog.ts index 076f4e1b..f3fd0284 100644 --- a/src/main/allowProtocolDialog.ts +++ b/src/main/allowProtocolDialog.ts @@ -6,16 +6,18 @@ import fs from 'fs'; import {dialog, shell} from 'electron'; -import log from 'electron-log'; import {localizeMessage} from 'main/i18nManager'; import buildConfig from 'common/config/buildConfig'; +import {Logger} from 'common/log'; import * as Validator from 'common/Validator'; import MainWindow from './windows/mainWindow'; import {allowedProtocolFile} from './constants'; +const log = new Logger('AllowProtocolDialog'); + export class AllowProtocolDialog { allowedProtocols: string[]; diff --git a/src/main/app/app.ts b/src/main/app/app.ts index 0101a36b..394f0cee 100644 --- a/src/main/app/app.ts +++ b/src/main/app/app.ts @@ -2,8 +2,8 @@ // See LICENSE.txt for license information. import {app, BrowserWindow, Event, dialog, WebContents, Certificate, Details} from 'electron'; -import log from 'electron-log'; +import {Logger} from 'common/log'; import urlUtils from 'common/utils/url'; import Config from 'common/config'; @@ -18,13 +18,15 @@ import {getDeeplinkingURL, openDeepLink, resizeScreen} from './utils'; export const certificateErrorCallbacks = new Map(); +const log = new Logger('App.App'); + // // app event handlers // // activate first app instance, subsequent instances will quit themselves export function handleAppSecondInstance(event: Event, argv: string[]) { - log.debug('App.handleAppSecondInstance', argv); + log.debug('handleAppSecondInstance', argv); // Protocol handler for win32 // argv: An array of the second instance’s (command line / deep linked) arguments @@ -33,7 +35,7 @@ export function handleAppSecondInstance(event: Event, argv: string[]) { } export function handleAppWindowAllClosed() { - log.debug('App.handleAppWindowAllClosed'); + log.debug('handleAppWindowAllClosed'); // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q @@ -43,7 +45,7 @@ export function handleAppWindowAllClosed() { } export function handleAppBrowserWindowCreated(event: Event, newWindow: BrowserWindow) { - log.debug('App.handleAppBrowserWindowCreated'); + log.debug('handleAppBrowserWindowCreated'); // Screen cannot be required before app is ready resizeScreen(newWindow); @@ -66,7 +68,7 @@ export function handleAppWillFinishLaunching() { } export function handleAppBeforeQuit() { - log.debug('App.handleAppBeforeQuit'); + log.debug('handleAppBeforeQuit'); // Make sure tray icon gets removed if the user exits via CTRL-Q destroyTray(); @@ -75,7 +77,7 @@ export function handleAppBeforeQuit() { } export async function handleAppCertificateError(event: Event, webContents: WebContents, url: string, error: string, certificate: Certificate, callback: (isTrusted: boolean) => void) { - log.verbose('App.handleAppCertificateError', {url, error, certificate}); + log.verbose('handleAppCertificateError', {url, error, certificate}); const parsedURL = urlUtils.parseURL(url); if (!parsedURL) { diff --git a/src/main/app/config.test.js b/src/main/app/config.test.js index 896b6bf7..36a953da 100644 --- a/src/main/app/config.test.js +++ b/src/main/app/config.test.js @@ -5,10 +5,10 @@ import {app} from 'electron'; import {RELOAD_CONFIGURATION} from 'common/communication'; import Config from 'common/config'; +import {setLoggingLevel} from 'common/log'; import {handleConfigUpdate} from 'main/app/config'; import {handleMainWindowIsShown} from 'main/app/intercom'; -import {setLoggingLevel} from 'main/app/utils'; import WindowManager from 'main/windows/windowManager'; import AutoLauncher from 'main/AutoLauncher'; diff --git a/src/main/app/config.ts b/src/main/app/config.ts index d8f50f83..46242650 100644 --- a/src/main/app/config.ts +++ b/src/main/app/config.ts @@ -2,12 +2,12 @@ // See LICENSE.txt for license information. import {app, ipcMain} from 'electron'; -import log, {LogLevel} from 'electron-log'; import {CombinedConfig} from 'types/config'; import {DARK_MODE_CHANGE, EMIT_CONFIGURATION, RELOAD_CONFIGURATION} from 'common/communication'; import Config from 'common/config'; +import {Logger, setLoggingLevel} from 'common/log'; import AutoLauncher from 'main/AutoLauncher'; import {setUnreadBadgeSetting} from 'main/badge'; @@ -16,22 +16,21 @@ import LoadingScreen from 'main/views/loadingScreen'; import WindowManager from 'main/windows/windowManager'; import {handleMainWindowIsShown} from './intercom'; -import {handleUpdateMenuEvent, setLoggingLevel, updateServerInfos, updateSpellCheckerLocales} from './utils'; +import {handleUpdateMenuEvent, updateServerInfos, updateSpellCheckerLocales} from './utils'; + +const log = new Logger('App.Config'); // // config event handlers // export function handleConfigUpdate(newConfig: CombinedConfig) { - if (log.transports.file.level !== newConfig.logLevel) { - log.error('Log level set to:', newConfig.logLevel); - } if (newConfig.logLevel) { - setLoggingLevel(newConfig.logLevel as LogLevel); + setLoggingLevel(newConfig.logLevel); } - log.debug('App.Config.handleConfigUpdate'); - log.silly('App.Config.handleConfigUpdate', newConfig); + log.debug('handleConfigUpdate'); + log.silly('handleConfigUpdate', newConfig); if (!newConfig) { return; @@ -77,7 +76,7 @@ export function handleConfigUpdate(newConfig: CombinedConfig) { } export function handleDarkModeChange(darkMode: boolean) { - log.debug('App.Config.handleDarkModeChange', darkMode); + log.debug('handleDarkModeChange', darkMode); refreshTrayImages(Config.trayIconTheme); WindowManager.sendToRenderer(DARK_MODE_CHANGE, darkMode); diff --git a/src/main/app/initialize.ts b/src/main/app/initialize.ts index 065d654e..f377d8a1 100644 --- a/src/main/app/initialize.ts +++ b/src/main/app/initialize.ts @@ -6,7 +6,6 @@ import path from 'path'; import {app, ipcMain, session} from 'electron'; import installExtension, {REACT_DEVELOPER_TOOLS} from 'electron-devtools-installer'; import isDev from 'electron-is-dev'; -import log from 'electron-log'; import { SWITCH_SERVER, @@ -38,6 +37,7 @@ import { OPEN_APP_MENU, } from 'common/communication'; import Config from 'common/config'; +import {Logger} from 'common/log'; import urlUtils from 'common/utils/url'; import AllowProtocolDialog from 'main/allowProtocolDialog'; @@ -103,6 +103,8 @@ import { export const mainProtocol = protocols?.[0]?.schemes?.[0]; +const log = new Logger('App.Initialize'); + /** * Main entry point for the application, ensures that everything initializes in the proper order */ @@ -302,7 +304,7 @@ function initializeAfterAppReady() { if (typeof Config.canUpgrade === 'undefined') { // windows might not be ready, so we have to wait until it is Config.once('update', () => { - log.debug('Initialize.checkForUpdates'); + log.debug('checkForUpdates'); if (Config.canUpgrade && Config.autoCheckForUpdates) { setTimeout(() => { updateManager.checkForUpdates(false); @@ -348,7 +350,7 @@ function initializeAfterAppReady() { // listen for status updates and pass on to renderer UserActivityMonitor.on('status', (status) => { - log.debug('Initialize.UserActivityMonitor.on(status)', status); + log.debug('UserActivityMonitor.on(status)', status); WindowManager.sendToMattermostViews(USER_ACTIVITY_UPDATE, status); }); diff --git a/src/main/app/intercom.ts b/src/main/app/intercom.ts index e239e7c2..dc358c97 100644 --- a/src/main/app/intercom.ts +++ b/src/main/app/intercom.ts @@ -2,12 +2,12 @@ // See LICENSE.txt for license information. import {app, dialog, IpcMainEvent, IpcMainInvokeEvent, Menu} from 'electron'; -import log from 'electron-log'; import {Team, TeamWithIndex} from 'types/config'; import {MentionData} from 'types/notification'; import Config from 'common/config'; +import {Logger} from 'common/log'; import {getDefaultTeamWithTabsFromTeam} from 'common/tabs/TabView'; import {ping} from 'common/utils/requests'; @@ -20,8 +20,10 @@ import MainWindow from 'main/windows/mainWindow'; import {handleAppBeforeQuit} from './app'; import {updateServerInfos} from './utils'; +const log = new Logger('App.Intercom'); + export function handleReloadConfig() { - log.debug('Intercom.handleReloadConfig'); + log.debug('handleReloadConfig'); Config.reload(); WindowManager.handleUpdateConfig(); @@ -42,17 +44,17 @@ export function handleQuit(e: IpcMainEvent, reason: string, stack: string) { } export function handleSwitchServer(event: IpcMainEvent, serverName: string) { - log.silly('Intercom.handleSwitchServer', serverName); + log.silly('handleSwitchServer', serverName); WindowManager.switchServer(serverName); } export function handleSwitchTab(event: IpcMainEvent, serverName: string, tabName: string) { - log.silly('Intercom.handleSwitchTab', {serverName, tabName}); + log.silly('handleSwitchTab', {serverName, tabName}); WindowManager.switchTab(serverName, tabName); } export function handleCloseTab(event: IpcMainEvent, serverName: string, tabName: string) { - log.debug('Intercom.handleCloseTab', {serverName, tabName}); + log.debug('handleCloseTab', {serverName, tabName}); const teams = Config.teams; teams.forEach((team) => { @@ -70,7 +72,7 @@ export function handleCloseTab(event: IpcMainEvent, serverName: string, tabName: } export function handleOpenTab(event: IpcMainEvent, serverName: string, tabName: string) { - log.debug('Intercom.handleOpenTab', {serverName, tabName}); + log.debug('handleOpenTab', {serverName, tabName}); const teams = Config.teams; teams.forEach((team) => { @@ -87,7 +89,7 @@ export function handleOpenTab(event: IpcMainEvent, serverName: string, tabName: } export function handleShowOnboardingScreens(showWelcomeScreen: boolean, showNewServerModal: boolean, mainWindowIsVisible: boolean) { - log.debug('Intercom.handleShowOnboardingScreens', {showWelcomeScreen, showNewServerModal, mainWindowIsVisible}); + log.debug('handleShowOnboardingScreens', {showWelcomeScreen, showNewServerModal, mainWindowIsVisible}); if (showWelcomeScreen) { handleWelcomeScreenModal(); @@ -124,7 +126,7 @@ export function handleMainWindowIsShown() { const mainWindow = MainWindow.get(); - log.debug('intercom.handleMainWindowIsShown', {configTeams: Config.teams, showWelcomeScreen, showNewServerModal, mainWindow: Boolean(mainWindow)}); + log.debug('handleMainWindowIsShown', {configTeams: Config.teams, showWelcomeScreen, showNewServerModal, mainWindow: Boolean(mainWindow)}); if (mainWindow?.isVisible()) { handleShowOnboardingScreens(showWelcomeScreen(), showNewServerModal(), true); } else { @@ -135,7 +137,7 @@ export function handleMainWindowIsShown() { } export function handleNewServerModal() { - log.debug('Intercom.handleNewServerModal'); + log.debug('handleNewServerModal'); const html = getLocalURLString('newServer.html'); @@ -167,7 +169,7 @@ export function handleNewServerModal() { } export function handleEditServerModal(e: IpcMainEvent, name: string) { - log.debug('Intercom.handleEditServerModal', name); + log.debug('handleEditServerModal', name); const html = getLocalURLString('editServer.html'); @@ -209,7 +211,7 @@ export function handleEditServerModal(e: IpcMainEvent, name: string) { } export function handleRemoveServerModal(e: IpcMainEvent, name: string) { - log.debug('Intercom.handleRemoveServerModal', name); + log.debug('handleRemoveServerModal', name); const html = getLocalURLString('removeServer.html'); @@ -249,7 +251,7 @@ export function handleRemoveServerModal(e: IpcMainEvent, name: string) { } export function handleWelcomeScreenModal() { - log.debug('Intercom.handleWelcomeScreenModal'); + log.debug('handleWelcomeScreenModal'); const html = getLocalURLString('welcomeScreen.html'); @@ -281,12 +283,12 @@ export function handleWelcomeScreenModal() { } export function handleMentionNotification(event: IpcMainEvent, title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, data: MentionData) { - log.debug('Intercom.handleMentionNotification', {title, body, channel, teamId, url, silent, data}); + log.debug('handleMentionNotification', {title, body, channel, teamId, url, silent, data}); displayMention(title, body, channel, teamId, url, silent, event.sender, data); } export function handleOpenAppMenu() { - log.debug('Intercom.handleOpenAppMenu'); + log.debug('handleOpenAppMenu'); const windowMenu = Menu.getApplicationMenu(); if (!windowMenu) { @@ -301,7 +303,7 @@ export function handleOpenAppMenu() { } export async function handleSelectDownload(event: IpcMainInvokeEvent, startFrom: string) { - log.debug('Intercom.handleSelectDownload', startFrom); + log.debug('handleSelectDownload', startFrom); const message = 'Specify the folder where files will download'; const result = await dialog.showOpenDialog({defaultPath: startFrom || Config.downloadLocation, @@ -312,7 +314,7 @@ export async function handleSelectDownload(event: IpcMainInvokeEvent, startFrom: } export function handleUpdateLastActive(event: IpcMainEvent, serverName: string, viewName: string) { - log.debug('Intercom.handleUpdateLastActive', {serverName, viewName}); + log.debug('handleUpdateLastActive', {serverName, viewName}); const teams = Config.teams; teams.forEach((team) => { diff --git a/src/main/app/utils.ts b/src/main/app/utils.ts index c8928930..1e577ed6 100644 --- a/src/main/app/utils.ts +++ b/src/main/app/utils.ts @@ -6,13 +6,13 @@ import path from 'path'; import fs from 'fs-extra'; import {app, BrowserWindow, Menu, Rectangle, Session, session, dialog, nativeImage, screen} from 'electron'; -import log, {LevelOption} from 'electron-log'; import {MigrationInfo, TeamWithTabs} from 'types/config'; import {RemoteInfo} from 'types/server'; import {Boundaries} from 'types/utils'; import Config from 'common/config'; +import {Logger} from 'common/log'; import JsonFileManager from 'common/JsonFileManager'; import {MattermostServer} from 'common/servers/MattermostServer'; import {TAB_FOCALBOARD, TAB_MESSAGING, TAB_PLAYBOOKS} from 'common/tabs/TabView'; @@ -35,6 +35,7 @@ import {mainProtocol} from './initialize'; const assetsDir = path.resolve(app.getAppPath(), 'assets'); const appIconURL = path.resolve(assetsDir, 'appicon_with_spacing_32.png'); const appIcon = nativeImage.createFromPath(appIconURL); +const log = new Logger('App.Utils'); export function openDeepLink(deeplinkingUrl: string) { try { @@ -104,7 +105,7 @@ function openExtraTabs(data: Array, team: TeamW } export function handleUpdateMenuEvent() { - log.debug('Utils.handleUpdateMenuEvent'); + log.debug('handleUpdateMenuEvent'); const aMenu = createAppMenu(Config, updateManager); Menu.setApplicationMenu(aMenu); @@ -193,7 +194,7 @@ function getValidWindowPosition(state: Rectangle) { export function resizeScreen(browserWindow: BrowserWindow) { function handle() { - log.debug('Utils.resizeScreen.handle'); + log.debug('resizeScreen.handle'); const position = browserWindow.getPosition(); const size = browserWindow.getSize(); const validPosition = getValidWindowPosition({ @@ -214,7 +215,7 @@ export function resizeScreen(browserWindow: BrowserWindow) { } export function flushCookiesStore(session: Session) { - log.debug('Utils.flushCookiesStore'); + log.debug('flushCookiesStore'); session.cookies.flushStore().catch((err) => { log.error(`There was a problem flushing cookies:\n${err}`); }); @@ -289,8 +290,3 @@ export function migrateMacAppStore() { log.error('MAS: An error occurred importing the existing configuration', e); } } - -export function setLoggingLevel(level: LevelOption) { - log.transports.console.level = level; - log.transports.file.level = level; -} diff --git a/src/main/appState.ts b/src/main/appState.ts index e18836d6..dcb2a5aa 100644 --- a/src/main/appState.ts +++ b/src/main/appState.ts @@ -4,12 +4,14 @@ import events from 'events'; import {ipcMain} from 'electron'; -import log from 'electron-log'; +import {Logger} from 'common/log'; import {UPDATE_MENTIONS, UPDATE_TRAY, UPDATE_BADGE, SESSION_EXPIRED, UPDATE_DROPDOWN_MENTIONS} from 'common/communication'; import WindowManager from './windows/windowManager'; +const log = new Logger('AppState'); + const status = { unreads: new Map(), mentions: new Map(), @@ -23,7 +25,7 @@ const emitMentions = (serverName: string) => { const isExpired = getIsExpired(serverName); WindowManager.sendToRenderer(UPDATE_MENTIONS, serverName, newMentions, newUnreads, isExpired); - log.silly('AppState.emitMentions', {serverName, isExpired, newMentions, newUnreads}); + log.silly('emitMentions', {serverName, isExpired, newMentions, newUnreads}); emitStatus(); }; diff --git a/src/main/authManager.ts b/src/main/authManager.ts index 24b5c8aa..8d509111 100644 --- a/src/main/authManager.ts +++ b/src/main/authManager.ts @@ -1,11 +1,11 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. import {AuthenticationResponseDetails, AuthInfo, WebContents} from 'electron'; -import log from 'electron-log'; import {PermissionType} from 'types/trustedOrigin'; import {LoginModalData} from 'types/auth'; +import {Logger} from 'common/log'; import {BASIC_AUTH_PERMISSION} from 'common/permissions'; import urlUtils from 'common/utils/url'; @@ -15,6 +15,7 @@ import {getLocalURLString, getLocalPreload} from 'main/utils'; import WindowManager from 'main/windows/windowManager'; import MainWindow from 'main/windows/mainWindow'; +const log = new Logger('AuthManager'); const preload = getLocalPreload('desktopAPI.js'); const loginModalHtml = getLocalURLString('loginModal.html'); const permissionModalHtml = getLocalURLString('permissionModal.html'); @@ -32,7 +33,7 @@ export class AuthManager { } handleAppLogin = (event: Event, webContents: WebContents, request: AuthenticationResponseDetails, authInfo: AuthInfo, callback?: (username?: string, password?: string) => void) => { - log.verbose('AuthManager.handleAppLogin', {request, authInfo}); + log.verbose('handleAppLogin', {request, authInfo}); event.preventDefault(); const parsedURL = urlUtils.parseURL(request.url); diff --git a/src/main/autoUpdater.ts b/src/main/autoUpdater.ts index ad92d4d4..5a9d397d 100644 --- a/src/main/autoUpdater.ts +++ b/src/main/autoUpdater.ts @@ -4,10 +4,10 @@ import path from 'path'; import {dialog, ipcMain, app, nativeImage} from 'electron'; -import log from 'electron-log'; - import {autoUpdater, CancellationToken, ProgressInfo, UpdateInfo} from 'electron-updater'; +import {Logger} from 'common/log'; + import downloadsManager from 'main/downloadsManager'; import {localizeMessage} from 'main/i18nManager'; import {displayUpgrade, displayRestartToUpgrade} from 'main/notifications'; @@ -28,7 +28,7 @@ import Config from 'common/config'; const NEXT_NOTIFY = 86400000; // 24 hours const NEXT_CHECK = 3600000; // 1 hour -log.transports.file.level = 'info'; +const log = new Logger('UpdateManager'); autoUpdater.logger = log; autoUpdater.autoDownload = false; autoUpdater.disableWebInstaller = true; @@ -64,14 +64,14 @@ export class UpdateManager { this.cancellationToken = new CancellationToken(); autoUpdater.on('error', (err: Error) => { - log.error(`[Mattermost] There was an error while trying to update: ${err}`); + log.error('There was an error while trying to update', err); }); autoUpdater.on('update-available', (info: UpdateInfo) => { autoUpdater.removeListener('update-not-available', this.displayNoUpgrade); this.versionAvailable = info.version; ipcMain.emit(UPDATE_SHORTCUT_MENU); - log.info(`[Mattermost] available version ${info.version}`); + log.info('New version available:', info.version); this.notify(); }); @@ -79,7 +79,7 @@ export class UpdateManager { this.versionDownloaded = info.version; this.downloadedInfo = info; ipcMain.emit(UPDATE_SHORTCUT_MENU); - log.info(`[Mattermost] downloaded version ${info.version}`); + log.info('Downloaded version', info.version); this.notifyDownloaded(); }); @@ -88,7 +88,7 @@ export class UpdateManager { }); ipcMain.on(CANCEL_UPGRADE, () => { - log.info('[Mattermost] User Canceled upgrade'); + log.info('User Canceled upgrade'); }); ipcMain.on(CHECK_FOR_UPDATES, () => { @@ -179,7 +179,7 @@ export class UpdateManager { } }).catch((reason) => { ipcMain.emit(NO_UPDATE_AVAILABLE); - log.error(`[Mattermost] Failed to check for updates: ${reason}`); + log.error('Failed to check for updates:', reason); }); this.lastCheck = setTimeout(() => this.checkForUpdates(false), NEXT_CHECK); } diff --git a/src/main/badge.ts b/src/main/badge.ts index 5fc0a183..25972440 100644 --- a/src/main/badge.ts +++ b/src/main/badge.ts @@ -3,15 +3,16 @@ // See LICENSE.txt for license information. import {BrowserWindow, app, nativeImage} from 'electron'; -import log from 'electron-log'; import {UPDATE_BADGE} from 'common/communication'; +import {Logger} from 'common/log'; import {localizeMessage} from 'main/i18nManager'; import * as AppState from './appState'; import MainWindow from './windows/mainWindow'; +const log = new Logger('Badge'); const MAX_WIN_COUNT = 99; let showUnreadBadgeSetting: boolean; @@ -110,7 +111,7 @@ function showBadgeLinux(sessionExpired: boolean, mentionCount: number) { } function showBadge(sessionExpired: boolean, mentionCount: number, showUnreadBadge: boolean) { - log.silly('Badge.showBadge', {sessionExpired, mentionCount, showUnreadBadge}); + log.silly('showBadge', {sessionExpired, mentionCount, showUnreadBadge}); switch (process.platform) { case 'win32': diff --git a/src/main/certificateManager.ts b/src/main/certificateManager.ts index 4e6545d1..74a62412 100644 --- a/src/main/certificateManager.ts +++ b/src/main/certificateManager.ts @@ -1,14 +1,17 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import log from 'electron-log'; + import {Certificate, WebContents} from 'electron'; import {CertificateModalData} from 'types/certificate'; +import {Logger} from 'common/log'; + import modalManager from './views/modalManager'; import {getLocalURLString, getLocalPreload} from './utils'; import MainWindow from './windows/mainWindow'; +const log = new Logger('CertificateManager'); const preload = getLocalPreload('desktopAPI.js'); const html = getLocalURLString('certificateModal.html'); @@ -24,7 +27,7 @@ export class CertificateManager { } handleSelectCertificate = (event: Event, webContents: WebContents, url: string, list: Certificate[], callback: (certificate?: Certificate | undefined) => void) => { - log.verbose('CertificateManager.handleSelectCertificate', url, list); + log.verbose('handleSelectCertificate', url, list); if (list.length > 1) { event.preventDefault(); // prevent the app from getting the first certificate available diff --git a/src/main/certificateStore.ts b/src/main/certificateStore.ts index 796c2cd1..118d7e0b 100644 --- a/src/main/certificateStore.ts +++ b/src/main/certificateStore.ts @@ -6,11 +6,11 @@ import fs from 'fs'; import {Certificate, ipcMain} from 'electron'; -import log from 'electron-log'; import {ComparableCertificate} from 'types/certificate'; import {UPDATE_PATHS} from 'common/communication'; +import {Logger} from 'common/log'; import urlUtils from 'common/utils/url'; import * as Validator from 'common/Validator'; @@ -94,6 +94,6 @@ let certificateStore = new CertificateStore(certificateStorePath); export default certificateStore; ipcMain.on(UPDATE_PATHS, () => { - log.debug('certificateStore.UPDATE_PATHS'); + new Logger('certificateStore').debug('UPDATE_PATHS'); certificateStore = new CertificateStore(certificateStorePath); }); diff --git a/src/main/downloadsManager.ts b/src/main/downloadsManager.ts index 43a665e3..c275d662 100644 --- a/src/main/downloadsManager.ts +++ b/src/main/downloadsManager.ts @@ -4,7 +4,6 @@ import path from 'path'; import fs from 'fs'; import {DownloadItem, Event, WebContents, FileFilter, ipcMain, dialog, shell, Menu, app} from 'electron'; -import log from 'electron-log'; import {ProgressInfo, UpdateInfo} from 'electron-updater'; import {DownloadedItem, DownloadItemDoneEventState, DownloadedItems, DownloadItemState, DownloadItemUpdatedEventState} from 'types/downloads'; @@ -26,6 +25,7 @@ import { } from 'common/communication'; import Config from 'common/config'; import JsonFileManager from 'common/JsonFileManager'; +import {Logger} from 'common/log'; import {APP_UPDATE_KEY, UPDATE_DOWNLOAD_ITEM} from 'common/constants'; import {DOWNLOADS_DROPDOWN_AUTOCLOSE_TIMEOUT, DOWNLOADS_DROPDOWN_MAX_ITEMS} from 'common/utils/constants'; import * as Validator from 'common/Validator'; @@ -37,6 +37,8 @@ import {doubleSecToMs, getPercentage, isStringWithLength, readFilenameFromConten import appVersionManager from './AppVersionManager'; import {downloadsJson} from './constants'; +const log = new Logger('DownloadsManager'); + export enum DownloadItemTypeEnum { FILE = 'file', UPDATE = 'update', @@ -68,7 +70,7 @@ export class DownloadsManager extends JsonFileManager { private init = () => { // ensure data loaded from file is valid const validatedJSON = Validator.validateDownloads(this.json); - log.debug('DownloadsManager.init', {'this.json': this.json, validatedJSON}); + log.debug('init', {'this.json': this.json, validatedJSON}); if (validatedJSON) { this.saveAll(validatedJSON); } else { @@ -100,7 +102,7 @@ export class DownloadsManager extends JsonFileManager { }; handleNewDownload = async (event: Event, item: DownloadItem, webContents: WebContents) => { - log.debug('DownloadsManager.handleNewDownload', {item, sourceURL: webContents.getURL()}); + log.debug('handleNewDownload', {item, sourceURL: webContents.getURL()}); const url = item.getURL(); @@ -180,7 +182,7 @@ export class DownloadsManager extends JsonFileManager { } checkForDeletedFiles = () => { - log.debug('DownloadsManager.checkForDeletedFiles'); + log.debug('checkForDeletedFiles'); const downloads = this.downloads; let modified = false; @@ -223,7 +225,7 @@ export class DownloadsManager extends JsonFileManager { }; clearDownloadsDropDown = () => { - log.debug('DownloadsManager.clearDownloadsDropDown'); + log.debug('clearDownloadsDropDown'); if (this.hasUpdate()) { this.saveAll({ @@ -238,10 +240,10 @@ export class DownloadsManager extends JsonFileManager { }; showFileInFolder = (item?: DownloadedItem) => { - log.debug('DownloadsDropdownView.showFileInFolder', {item}); + log.debug('showFileInFolder', {item}); if (!item) { - log.debug('DownloadsDropdownView.showFileInFolder', 'ITEM_UNDEFINED'); + log.debug('showFileInFolder', 'ITEM_UNDEFINED'); return; } @@ -260,14 +262,14 @@ export class DownloadsManager extends JsonFileManager { return; } - log.debug('DownloadsDropdownView.showFileInFolder', 'NO_DOWNLOAD_LOCATION'); + log.debug('showFileInFolder', 'NO_DOWNLOAD_LOCATION'); }; openFile = (item?: DownloadedItem) => { - log.debug('DownloadsDropdownView.openFile', {item}); + log.debug('openFile', {item}); if (!item) { - log.debug('DownloadsDropdownView.openFile', 'FILE_UNDEFINED'); + log.debug('openFile', 'FILE_UNDEFINED'); return; } @@ -282,19 +284,19 @@ export class DownloadsManager extends JsonFileManager { func = app.startAccessingSecurityScopedResource(bookmark.bookmark); } shell.openPath(item.location).catch((err) => { - log.debug('DownloadsDropdownView.openFileError', {err}); + log.debug('openFileError', {err}); this.showFileInFolder(item); }); func?.(); } else { - log.debug('DownloadsDropdownView.openFile', 'COULD_NOT_OPEN_FILE'); + log.debug('openFile', 'COULD_NOT_OPEN_FILE'); this.markFileAsDeleted(item); this.showFileInFolder(item); } }; clearFile = (item?: DownloadedItem) => { - log.debug('DownloadsDropdownView.clearFile', {item}); + log.debug('clearFile', {item}); if (!item || item.type === DownloadItemTypeEnum.UPDATE) { return; @@ -311,7 +313,7 @@ export class DownloadsManager extends JsonFileManager { }; cancelDownload = (item?: DownloadedItem) => { - log.debug('DownloadsDropdownView.cancelDownload', {item}); + log.debug('cancelDownload', {item}); if (!item) { return; @@ -346,7 +348,7 @@ export class DownloadsManager extends JsonFileManager { }; hasDownloads = () => { - log.debug('DownloadsManager.hasDownloads'); + log.debug('hasDownloads'); return (Object.keys(this.downloads)?.length || 0) > 0; }; @@ -355,7 +357,7 @@ export class DownloadsManager extends JsonFileManager { }; openDownloadsDropdown = () => { - log.debug('DownloadsManager.openDownloadsDropdown'); + log.debug('openDownloadsDropdown'); this.open = true; ipcMain.emit(OPEN_DOWNLOADS_DROPDOWN); WindowManager.sendToRenderer(HIDE_DOWNLOADS_DROPDOWN_BUTTON_BADGE); @@ -386,7 +388,7 @@ export class DownloadsManager extends JsonFileManager { }; private saveAll = (downloads: DownloadedItems): void => { - log.debug('DownloadsManager.saveAll'); + log.debug('saveAll'); this.downloads = downloads; this.setJson(downloads); @@ -395,7 +397,7 @@ export class DownloadsManager extends JsonFileManager { }; private save = (key: string, item: DownloadedItem) => { - log.debug('DownloadsManager.save'); + log.debug('save'); this.downloads[key] = item; this.setValue(key, item); ipcMain.emit(UPDATE_DOWNLOADS_DROPDOWN, true, this.downloads); @@ -415,7 +417,7 @@ export class DownloadsManager extends JsonFileManager { * This function return true if "downloadLocation" is undefined */ private shouldShowSaveDialog = (item: DownloadItem, downloadLocation?: string) => { - log.debug('DownloadsManager.shouldShowSaveDialog', {downloadLocation}); + log.debug('shouldShowSaveDialog', {downloadLocation}); return !item.hasUserGesture() || !downloadLocation; }; @@ -433,7 +435,7 @@ export class DownloadsManager extends JsonFileManager { }; private closeDownloadsDropdown = () => { - log.debug('DownloadsManager.closeDownloadsDropdown'); + log.debug('closeDownloadsDropdown'); this.open = false; ipcMain.emit(CLOSE_DOWNLOADS_DROPDOWN); ipcMain.emit(CLOSE_DOWNLOADS_DROPDOWN_MENU); @@ -449,7 +451,7 @@ export class DownloadsManager extends JsonFileManager { private upsertFileToDownloads = (item: DownloadItem, state: DownloadItemState, overridePath?: string) => { const fileId = this.getFileId(item); - log.debug('DownloadsManager.upsertFileToDownloads', {fileId}); + log.debug('upsertFileToDownloads', {fileId}); const formattedItem = this.formatDownloadItem(item, state, overridePath); this.save(fileId, formattedItem); this.checkIfMaxFilesReached(); @@ -479,7 +481,7 @@ export class DownloadsManager extends JsonFileManager { }; private shouldShowBadge = () => { - log.debug('DownloadsManager.shouldShowBadge'); + log.debug('shouldShowBadge'); if (this.open === true) { WindowManager.sendToRenderer(HIDE_DOWNLOADS_DROPDOWN_BUTTON_BADGE); @@ -492,7 +494,7 @@ export class DownloadsManager extends JsonFileManager { * DownloadItem event handlers */ private updatedEventController = (updatedEvent: Event, state: DownloadItemUpdatedEventState, item: DownloadItem) => { - log.debug('DownloadsManager.updatedEventController', {state}); + log.debug('updatedEventController', {state}); this.upsertFileToDownloads(item, state); @@ -504,7 +506,7 @@ export class DownloadsManager extends JsonFileManager { }; private doneEventController = (doneEvent: Event, state: DownloadItemDoneEventState, item: DownloadItem, webContents: WebContents) => { - log.debug('DownloadsManager.doneEventController', {state}); + log.debug('doneEventController', {state}); if (state === 'completed' && !this.open) { displayDownloadCompleted(path.basename(item.savePath), item.savePath, WindowManager.getServerNameByWebContentsId(webContents.id) || ''); @@ -536,7 +538,7 @@ export class DownloadsManager extends JsonFileManager { this.openDownloadsDropdown(); }; private onUpdateDownloaded = (event: Event, info: UpdateInfo) => { - log.debug('DownloadsManager.onUpdateDownloaded', {info}); + log.debug('onUpdateDownloaded', {info}); const {version} = info; const update = this.downloads[APP_UPDATE_KEY]; @@ -548,7 +550,7 @@ export class DownloadsManager extends JsonFileManager { this.openDownloadsDropdown(); }; private onUpdateProgress = (event: Event, progress: ProgressInfo) => { - log.debug('DownloadsManager.onUpdateProgress', {progress}); + log.debug('onUpdateProgress', {progress}); const {total, transferred, percent} = progress; const update = this.downloads[APP_UPDATE_KEY] || {...UPDATE_DOWNLOAD_ITEM}; if (typeof update.addedAt !== 'number' || update.addedAt === 0) { diff --git a/src/main/i18nManager.ts b/src/main/i18nManager.ts index 394d7b56..ecffe020 100644 --- a/src/main/i18nManager.ts +++ b/src/main/i18nManager.ts @@ -2,9 +2,9 @@ // See LICENSE.txt for license information. import {ipcMain} from 'electron'; -import log from 'electron-log'; import {GET_AVAILABLE_LANGUAGES, GET_LANGUAGE_INFORMATION} from 'common/communication'; +import {Logger} from 'common/log'; import {Language, languages} from '../../i18n/i18n'; @@ -16,6 +16,8 @@ export function localizeMessage(s: string, defaultString = '', values: any = {}) return str; } +const log = new Logger('i18nManager'); + export class I18nManager { currentLanguage: Language; @@ -27,7 +29,7 @@ export class I18nManager { } setLocale = (locale: string) => { - log.debug('i18nManager.setLocale', locale); + log.debug('setLocale', locale); if (this.isLanguageAvailable(locale)) { this.currentLanguage = this.getLanguages()[locale]; diff --git a/src/main/notifications/dnd-linux.ts b/src/main/notifications/dnd-linux.ts index f103aa2a..42afcfba 100644 --- a/src/main/notifications/dnd-linux.ts +++ b/src/main/notifications/dnd-linux.ts @@ -3,9 +3,10 @@ import {execSync} from 'child_process'; -import log from 'electron-log'; +import {Logger} from 'common/log'; const GNOME_READ_DND = 'gsettings get org.gnome.desktop.notifications show-banners'; +const log = new Logger('Linux-DnD'); function getLinuxDoNotDisturb() { try { diff --git a/src/main/notifications/index.ts b/src/main/notifications/index.ts index e44d846b..8c4d7e77 100644 --- a/src/main/notifications/index.ts +++ b/src/main/notifications/index.ts @@ -2,7 +2,6 @@ // See LICENSE.txt for license information. import {app, shell, Notification} from 'electron'; -import log from 'electron-log'; import {getDoNotDisturb as getDarwinDoNotDisturb} from 'macos-notification-state'; @@ -10,6 +9,7 @@ import {MentionData} from 'types/notification'; import Config from 'common/config'; import {PLAY_SOUND} from 'common/communication'; +import {Logger} from 'common/log'; import {TAB_MESSAGING} from 'common/tabs/TabView'; import MainWindow from '../windows/mainWindow'; @@ -23,8 +23,10 @@ import getWindowsDoNotDisturb from './dnd-windows'; export const currentNotifications = new Map(); +const log = new Logger('Notifications'); + export function displayMention(title: string, body: string, channel: {id: string}, teamId: string, url: string, silent: boolean, webcontents: Electron.WebContents, data: MentionData) { - log.debug('Notifications.displayMention', {title, body, channel, teamId, url, silent, data}); + log.debug('displayMention', {title, body, channel, teamId, url, silent, data}); if (!Notification.isSupported()) { log.error('notification not supported'); @@ -48,7 +50,7 @@ export function displayMention(title: string, body: string, channel: {id: string const mentionKey = `${mention.teamId}:${mention.channel.id}`; mention.on('show', () => { - log.debug('Notifications.displayMention.show'); + log.debug('displayMention.show'); // On Windows, manually dismiss notifications from the same channel and only show the latest one if (process.platform === 'win32') { @@ -77,7 +79,7 @@ export function displayMention(title: string, body: string, channel: {id: string } export function displayDownloadCompleted(fileName: string, path: string, serverName: string) { - log.debug('Notifications.displayDownloadCompleted', {fileName, path, serverName}); + log.debug('displayDownloadCompleted', {fileName, path, serverName}); if (!Notification.isSupported()) { log.error('notification not supported'); diff --git a/src/main/server/serverAPI.ts b/src/main/server/serverAPI.ts index 25401ca7..3471e6df 100644 --- a/src/main/server/serverAPI.ts +++ b/src/main/server/serverAPI.ts @@ -2,9 +2,11 @@ // See LICENSE.txt for license information. import {net, session} from 'electron'; -import log from 'electron-log'; import {COOKIE_NAME_AUTH_TOKEN, COOKIE_NAME_CSRF, COOKIE_NAME_USER_ID} from 'common/constants'; +import {Logger} from 'common/log'; + +const log = new Logger('serverAPI'); export async function getServerAPI(url: URL, isAuthenticated: boolean, onSuccess?: (data: T) => void, onAbort?: () => void, onError?: (error: Error) => void) { if (isAuthenticated) { @@ -36,11 +38,11 @@ export async function getServerAPI(url: URL, isAuthenticated: boolean, onSucc if (onSuccess) { req.on('response', (response: Electron.IncomingMessage) => { - log.silly('getServerAPI.response', response); + log.silly('response', response); if (response.statusCode === 200) { let raw = ''; response.on('data', (chunk: Buffer) => { - log.silly('getServerAPI.response.data', `${chunk}`); + log.silly('response.data', `${chunk}`); raw += `${chunk}`; }); response.on('end', () => { diff --git a/src/main/server/serverInfo.ts b/src/main/server/serverInfo.ts index da8f359a..38f07f30 100644 --- a/src/main/server/serverInfo.ts +++ b/src/main/server/serverInfo.ts @@ -1,14 +1,15 @@ // Copyright (c) 2016-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import log from 'electron-log'; - import {ClientConfig, RemoteInfo} from 'types/server'; import {MattermostServer} from 'common/servers/MattermostServer'; +import {Logger} from 'common/log'; import {getServerAPI} from './serverAPI'; +const log = new Logger('ServerInfo'); + export class ServerInfo { server: MattermostServer; remoteInfo: RemoteInfo; @@ -57,7 +58,7 @@ export class ServerInfo { } trySendRemoteInfo = () => { - log.debug('ServerInfo.trySendRemoteInfo', this.server.name, this.remoteInfo); + log.debug('trySendRemoteInfo', this.server.name, this.remoteInfo); if (this.isRemoteInfoRetrieved()) { this.onRetrievedRemoteInfo?.(this.remoteInfo); diff --git a/src/main/trustedOrigins.ts b/src/main/trustedOrigins.ts index 78312b04..e5e2e702 100644 --- a/src/main/trustedOrigins.ts +++ b/src/main/trustedOrigins.ts @@ -6,16 +6,18 @@ import fs from 'fs'; import {ipcMain} from 'electron'; -import log from 'electron-log'; import {TrustedOrigin, PermissionType} from 'types/trustedOrigin'; import {UPDATE_PATHS} from 'common/communication'; +import {Logger} from 'common/log'; import urlUtils from 'common/utils/url'; import * as Validator from 'common/Validator'; import {trustedOriginsStoreFile} from './constants'; +const log = new Logger('TrustedOriginsStore'); + export class TrustedOriginsStore { storeFile: string; data?: Map; @@ -117,7 +119,7 @@ const trustedOriginsStore = new TrustedOriginsStore(trustedOriginsStoreFile); export default trustedOriginsStore; ipcMain.on(UPDATE_PATHS, () => { - log.debug('trustedOriginsStore.UPDATE_PATHS'); + log.debug('UPDATE_PATHS'); trustedOriginsStore.storeFile = trustedOriginsStoreFile; if (trustedOriginsStore.data) { trustedOriginsStore.load(); diff --git a/src/main/views/MattermostView.ts b/src/main/views/MattermostView.ts index 19979381..c18f2d92 100644 --- a/src/main/views/MattermostView.ts +++ b/src/main/views/MattermostView.ts @@ -3,7 +3,6 @@ import {BrowserView, app, ipcMain} from 'electron'; import {BrowserViewConstructorOptions, Event, Input} from 'electron/main'; -import log from 'electron-log'; import {EventEmitter} from 'events'; @@ -23,6 +22,7 @@ import { } from 'common/communication'; import {MattermostServer} from 'common/servers/MattermostServer'; import {TabView, TabTuple} from 'common/tabs/TabView'; +import {Logger} from 'common/log'; import {ServerInfo} from 'main/server/serverInfo'; import MainWindow from 'main/windows/mainWindow'; @@ -42,6 +42,7 @@ export enum Status { } const MENTIONS_GROUP = 2; +const log = new Logger('MattermostView'); export class MattermostView extends EventEmitter { tab: TabView; @@ -94,7 +95,7 @@ export class MattermostView extends EventEmitter { } this.view.webContents.on('did-finish-load', () => { - log.debug('MattermostView.did-finish-load', this.tab.name); + log.debug('did-finish-load', this.tab.name); // wait for screen to truly finish loading before sending the message down const timeout = setInterval(() => { @@ -355,7 +356,7 @@ export class MattermostView extends EventEmitter { }; handleInputEvents = (_: Event, input: Input) => { - log.silly('MattermostView.handleInputEvents', {tabName: this.tab.name, input}); + log.silly('handleInputEvents', {tabName: this.tab.name, input}); this.registerAltKeyPressed(input); @@ -365,7 +366,7 @@ export class MattermostView extends EventEmitter { } handleDidNavigate = (event: Event, url: string) => { - log.debug('MattermostView.handleDidNavigate', {tabName: this.tab.name, url}); + log.debug('handleDidNavigate', {tabName: this.tab.name, url}); if (shouldHaveBackBar(this.tab.url || '', url)) { this.setBounds(getWindowBoundaries(MainWindow.get()!, true)); @@ -379,7 +380,7 @@ export class MattermostView extends EventEmitter { } handleUpdateTarget = (e: Event, url: string) => { - log.silly('MattermostView.handleUpdateTarget', {tabName: this.tab.name, url}); + log.silly('handleUpdateTarget', {tabName: this.tab.name, url}); if (url && !urlUtils.isInternalURL(urlUtils.parseURL(url), this.tab.server.url)) { this.emit(UPDATE_TARGET_URL, url); } else { @@ -390,7 +391,7 @@ export class MattermostView extends EventEmitter { titleParser = /(\((\d+)\) )?(\* )?/g handleTitleUpdate = (e: Event, title: string) => { - log.debug('MattermostView.handleTitleUpdate', {tabName: this.tab.name, title}); + log.debug('handleTitleUpdate', {tabName: this.tab.name, title}); this.updateMentionsFromTitle(title); } @@ -404,7 +405,7 @@ export class MattermostView extends EventEmitter { } handleFaviconUpdate = (e: Event, favicons: string[]) => { - log.silly('MattermostView.handleFaviconUpdate', {tabName: this.tab.name, favicons}); + log.silly('handleFaviconUpdate', {tabName: this.tab.name, favicons}); // if unread state is stored for that favicon, retrieve value. // if not, get related info from preload and store it for future changes @@ -425,7 +426,7 @@ export class MattermostView extends EventEmitter { // if favicon is null, it means it is the initial load, // so don't memoize as we don't have the favicons and there is no rush to find out. handleFaviconIsUnread = (e: Event, favicon: string, viewName: string, result: boolean) => { - log.silly('MattermostView.handleFaviconIsUnread', {favicon, viewName, result}); + log.silly('handleFaviconIsUnread', {favicon, viewName, result}); if (this.tab && viewName === this.tab.name) { appState.updateUnreads(viewName, result); diff --git a/src/main/views/downloadsDropdownMenuView.ts b/src/main/views/downloadsDropdownMenuView.ts index a9e7e905..db03f1ad 100644 --- a/src/main/views/downloadsDropdownMenuView.ts +++ b/src/main/views/downloadsDropdownMenuView.ts @@ -2,8 +2,6 @@ // See LICENSE.txt for license information. import {BrowserView, ipcMain, IpcMainEvent} from 'electron'; -import log from 'electron-log'; - import {CombinedConfig} from 'types/config'; import {CoordinatesToJsonType, DownloadedItem, DownloadsMenuOpenEventPayload} from 'types/downloads'; @@ -20,6 +18,7 @@ import { UPDATE_DOWNLOADS_DROPDOWN_MENU, UPDATE_DOWNLOADS_DROPDOWN_MENU_ITEM, } from 'common/communication'; +import {Logger} from 'common/log'; import { DOWNLOADS_DROPDOWN_FULL_WIDTH, DOWNLOADS_DROPDOWN_MENU_FULL_HEIGHT, @@ -32,6 +31,8 @@ import WindowManager from '../windows/windowManager'; import downloadsManager from 'main/downloadsManager'; import MainWindow from 'main/windows/mainWindow'; +const log = new Logger('DownloadsDropdownMenuView'); + export default class DownloadsDropdownMenuView { open: boolean; view: BrowserView; @@ -81,7 +82,7 @@ export default class DownloadsDropdownMenuView { } updateItem = (event: IpcMainEvent, item: DownloadedItem) => { - log.debug('DownloadsDropdownMenuView.updateItem', {item}); + log.debug('updateItem', {item}); this.item = item; @@ -89,7 +90,7 @@ export default class DownloadsDropdownMenuView { } updateConfig = (event: IpcMainEvent, config: CombinedConfig) => { - log.debug('DownloadsDropdownMenuView.updateConfig'); + log.debug('updateConfig'); this.darkMode = config.darkMode; this.updateDownloadsDropdownMenu(); @@ -100,7 +101,7 @@ export default class DownloadsDropdownMenuView { * the downloads dropdown at the correct position */ updateWindowBounds = () => { - log.debug('DownloadsDropdownMenuView.updateWindowBounds'); + log.debug('updateWindowBounds'); const mainWindow = MainWindow.get(); if (mainWindow) { @@ -111,7 +112,7 @@ export default class DownloadsDropdownMenuView { } updateDownloadsDropdownMenu = () => { - log.debug('DownloadsDropdownMenuView.updateDownloadsDropdownMenu'); + log.debug('updateDownloadsDropdownMenu'); this.view.webContents.send( UPDATE_DOWNLOADS_DROPDOWN_MENU, @@ -123,7 +124,7 @@ export default class DownloadsDropdownMenuView { } handleOpen = (event: IpcMainEvent, payload: DownloadsMenuOpenEventPayload = {} as DownloadsMenuOpenEventPayload) => { - log.debug('DownloadsDropdownMenuView.handleOpen', {bounds: this.bounds, payload}); + log.debug('handleOpen', {bounds: this.bounds, payload}); if (!this.bounds) { return; @@ -131,7 +132,7 @@ export default class DownloadsDropdownMenuView { const {item, coordinates} = payload; - log.debug('DownloadsDropdownMenuView.handleOpen', {item, coordinates}); + log.debug('handleOpen', {item, coordinates}); this.open = true; this.coordinates = coordinates; @@ -144,7 +145,7 @@ export default class DownloadsDropdownMenuView { } handleClose = () => { - log.debug('DownloadsDropdownMenuView.handleClose'); + log.debug('handleClose'); this.open = false; this.item = undefined; diff --git a/src/main/views/downloadsDropdownView.ts b/src/main/views/downloadsDropdownView.ts index ed0faf24..f7bb7999 100644 --- a/src/main/views/downloadsDropdownView.ts +++ b/src/main/views/downloadsDropdownView.ts @@ -3,8 +3,6 @@ import {BrowserView, ipcMain, IpcMainEvent, IpcMainInvokeEvent} from 'electron'; -import log from 'electron-log'; - import {CombinedConfig} from 'types/config'; import {DownloadedItem, DownloadedItems} from 'types/downloads'; @@ -20,6 +18,7 @@ import { GET_DOWNLOADED_IMAGE_THUMBNAIL_LOCATION, DOWNLOADS_DROPDOWN_OPEN_FILE, } from 'common/communication'; +import {Logger} from 'common/log'; import {TAB_BAR_HEIGHT, DOWNLOADS_DROPDOWN_WIDTH, DOWNLOADS_DROPDOWN_HEIGHT, DOWNLOADS_DROPDOWN_FULL_WIDTH} from 'common/utils/constants'; import {getLocalPreload, getLocalURLString} from 'main/utils'; @@ -27,6 +26,8 @@ import WindowManager from '../windows/windowManager'; import downloadsManager from 'main/downloadsManager'; import MainWindow from 'main/windows/mainWindow'; +const log = new Logger('DownloadsDropdownView'); + export default class DownloadsDropdownView { bounds?: Electron.Rectangle; darkMode: boolean; @@ -75,7 +76,7 @@ export default class DownloadsDropdownView { } updateDownloads = (event: IpcMainEvent, downloads: DownloadedItems) => { - log.debug('DownloadsDropdownView.updateDownloads', {downloads}); + log.debug('updateDownloads', {downloads}); this.downloads = downloads; @@ -83,13 +84,13 @@ export default class DownloadsDropdownView { } updateDownloadsDropdownMenuItem = (event: IpcMainEvent, item?: DownloadedItem) => { - log.debug('DownloadsDropdownView.updateDownloadsDropdownMenuItem', {item}); + log.debug('updateDownloadsDropdownMenuItem', {item}); this.item = item; this.updateDownloadsDropdown(); } updateConfig = (event: IpcMainEvent, config: CombinedConfig) => { - log.debug('DownloadsDropdownView.updateConfig'); + log.debug('updateConfig'); this.darkMode = config.darkMode; this.updateDownloadsDropdown(); @@ -100,7 +101,7 @@ export default class DownloadsDropdownView { * the downloads dropdown at the correct position */ updateWindowBounds = () => { - log.debug('DownloadsDropdownView.updateWindowBounds'); + log.debug('updateWindowBounds'); const mainWindow = MainWindow.get(); if (mainWindow) { @@ -111,7 +112,7 @@ export default class DownloadsDropdownView { } updateDownloadsDropdown = () => { - log.debug('DownloadsDropdownView.updateDownloadsDropdown'); + log.debug('updateDownloadsDropdown'); this.view.webContents.send( UPDATE_DOWNLOADS_DROPDOWN, @@ -123,7 +124,7 @@ export default class DownloadsDropdownView { } handleOpen = () => { - log.debug('DownloadsDropdownView.handleOpen', {bounds: this.bounds}); + log.debug('handleOpen', {bounds: this.bounds}); if (!this.bounds) { return; @@ -137,7 +138,7 @@ export default class DownloadsDropdownView { } handleClose = () => { - log.debug('DownloadsDropdownView.handleClose'); + log.debug('handleClose'); this.view.setBounds(this.getBounds(0, 0)); downloadsManager.onClose(); @@ -150,7 +151,7 @@ export default class DownloadsDropdownView { } openFile = (e: IpcMainEvent, item: DownloadedItem) => { - log.debug('DownloadsDropdownView.openFile', {item}); + log.debug('openFile', {item}); downloadsManager.openFile(item); } @@ -192,7 +193,7 @@ export default class DownloadsDropdownView { } handleReceivedDownloadsDropdownSize = (event: IpcMainEvent, width: number, height: number) => { - log.silly('DownloadsDropdownView.handleReceivedDownloadsDropdownSize', {width, height}); + log.silly('handleReceivedDownloadsDropdownSize', {width, height}); this.bounds = this.getBounds(width, height); if (downloadsManager.getIsOpen()) { diff --git a/src/main/views/loadingScreen.ts b/src/main/views/loadingScreen.ts index 0cb35cc7..8ec919fc 100644 --- a/src/main/views/loadingScreen.ts +++ b/src/main/views/loadingScreen.ts @@ -2,9 +2,9 @@ // See LICENSE.txt for license information. import {BrowserView, app, ipcMain} from 'electron'; -import log from 'electron-log'; import {DARK_MODE_CHANGE, LOADING_SCREEN_ANIMATION_FINISHED, TOGGLE_LOADING_SCREEN_VISIBILITY} from 'common/communication'; +import {Logger} from 'common/log'; import {getLocalPreload, getLocalURLString, getWindowBoundaries} from 'main/utils'; import MainWindow from 'main/windows/mainWindow'; @@ -15,6 +15,8 @@ enum LoadingScreenState { HIDDEN = 3, } +const log = new Logger('LoadingScreen'); + export class LoadingScreen { private view?: BrowserView; private state: LoadingScreenState; diff --git a/src/main/views/modalManager.ts b/src/main/views/modalManager.ts index 9102ec0b..d850b028 100644 --- a/src/main/views/modalManager.ts +++ b/src/main/views/modalManager.ts @@ -4,8 +4,6 @@ import {BrowserWindow, ipcMain} from 'electron'; import {IpcMainEvent, IpcMainInvokeEvent} from 'electron/main'; -import log from 'electron-log'; - import {CombinedConfig} from 'types/config'; import { @@ -20,6 +18,7 @@ import { RESIZE_MODAL, } from 'common/communication'; import Config from 'common/config'; +import {Logger} from 'common/log'; import {getAdjustedWindowBoundaries} from 'main/utils'; import WebContentsEventManager from 'main/views/webContentEvents'; @@ -27,6 +26,8 @@ import WindowManager from 'main/windows/windowManager'; import {ModalView} from './modalView'; +const log = new Logger('ModalManager'); + export class ModalManager { modalQueue: Array>; modalPromises: Map>; @@ -74,7 +75,7 @@ export class ModalManager { } handleInfoRequest = (event: IpcMainInvokeEvent) => { - log.debug('ModalManager.handleInfoRequest'); + log.debug('handleInfoRequest'); const requestModal = this.findModalByCaller(event); if (requestModal) { @@ -98,7 +99,7 @@ export class ModalManager { } handleModalFinished = (mode: 'resolve' | 'reject', event: IpcMainEvent, data: unknown) => { - log.debug('ModalManager.handleModalFinished', {mode, data}); + log.debug('handleModalFinished', {mode, data}); const requestModal = this.findModalByCaller(event); if (requestModal) { @@ -131,7 +132,7 @@ export class ModalManager { } handleResizeModal = (event: IpcMainEvent, bounds: Electron.Rectangle) => { - log.debug('ModalManager.handleResizeModal', {bounds, modalQueueLength: this.modalQueue.length}); + log.debug('handleResizeModal', {bounds, modalQueueLength: this.modalQueue.length}); if (this.modalQueue.length) { const currentModal = this.modalQueue[0]; @@ -147,7 +148,7 @@ export class ModalManager { handleEmitConfiguration = (event: IpcMainEvent, config: CombinedConfig) => { if (this.modalQueue.length) { - log.debug('ModalManager.handleEmitConfiguration'); + log.debug('handleEmitConfiguration'); } this.modalQueue.forEach((modal) => { diff --git a/src/main/views/modalView.ts b/src/main/views/modalView.ts index 1536e8d9..cddb906b 100644 --- a/src/main/views/modalView.ts +++ b/src/main/views/modalView.ts @@ -2,7 +2,8 @@ // See LICENSE.txt for license information. import {BrowserView, BrowserWindow} from 'electron'; -import log from 'electron-log'; + +import {Logger} from 'common/log'; import ContextMenu from '../contextMenu'; import {getWindowBoundaries} from '../utils'; @@ -25,12 +26,14 @@ export class ModalView { status: Status; contextMenu: ContextMenu; uncloseable: boolean; + private log: Logger; constructor(key: string, html: string, preload: string, data: T, onResolve: (value: T2) => void, onReject: (value: T2) => void, currentWindow: BrowserWindow, uncloseable: boolean) { this.key = key; this.html = html; this.data = data; - log.info(`preloading with ${preload}`); + this.log = new Logger('ModalView', key); + this.log.info(`preloading with ${preload}`); this.view = new BrowserView({webPreferences: { preload, @@ -48,8 +51,8 @@ export class ModalView { try { this.view.webContents.loadURL(this.html); } catch (e) { - log.error('there was an error loading the modal:'); - log.error(e); + this.log.error('there was an error loading the modal:'); + this.log.error(e); } this.contextMenu = new ContextMenu({}, this.view); @@ -84,7 +87,7 @@ export class ModalView { } if (withDevTools) { - log.info(`showing dev tools for ${this.key}`); + this.log.info(`showing dev tools for ${this.key}`); this.view.webContents.openDevTools({mode: 'detach'}); } } diff --git a/src/main/views/teamDropdownView.ts b/src/main/views/teamDropdownView.ts index 3f22a42b..c26b9bc1 100644 --- a/src/main/views/teamDropdownView.ts +++ b/src/main/views/teamDropdownView.ts @@ -3,8 +3,6 @@ import {BrowserView, ipcMain, IpcMainEvent} from 'electron'; -import log from 'electron-log'; - import {CombinedConfig, Team, TeamWithTabs, TeamWithTabsAndGpo} from 'types/config'; import { @@ -17,12 +15,15 @@ import { RECEIVE_DROPDOWN_MENU_SIZE, SET_ACTIVE_VIEW, } from 'common/communication'; -import * as AppState from '../appState'; +import {Logger} from 'common/log'; import {TAB_BAR_HEIGHT, THREE_DOT_MENU_WIDTH, THREE_DOT_MENU_WIDTH_MAC, MENU_SHADOW_WIDTH} from 'common/utils/constants'; import {getLocalPreload, getLocalURLString} from 'main/utils'; +import * as AppState from '../appState'; import WindowManager from '../windows/windowManager'; import MainWindow from '../windows/mainWindow'; +const log = new Logger('TeamDropdownView'); + export default class TeamDropdownView { view: BrowserView; bounds?: Electron.Rectangle; @@ -68,9 +69,8 @@ export default class TeamDropdownView { } updateConfig = (event: IpcMainEvent, config: CombinedConfig) => { - log.silly('TeamDropdownView.config', {config}); + log.silly('config', {config}); - this.teams = this.addGpoToTeams(config.teams, config.registryTeams); this.darkMode = config.darkMode; this.enableServerManagement = config.enableServerManagement; this.hasGPOTeams = config.registryTeams && config.registryTeams.length > 0; @@ -78,14 +78,14 @@ export default class TeamDropdownView { } updateActiveTeam = (event: IpcMainEvent, name: string) => { - log.silly('TeamDropdownView.updateActiveTeam', {name}); + log.silly('updateActiveTeam', {name}); this.activeTeam = name; this.updateDropdown(); } updateMentions = (expired: Map, mentions: Map, unreads: Map) => { - log.silly('TeamDropdownView.updateMentions', {expired, mentions, unreads}); + log.silly('updateMentions', {expired, mentions, unreads}); this.unreads = unreads; this.mentions = mentions; @@ -99,7 +99,7 @@ export default class TeamDropdownView { } updateDropdown = () => { - log.silly('TeamDropdownView.updateDropdown'); + log.silly('updateDropdown'); this.view.webContents.send( UPDATE_TEAMS_DROPDOWN, @@ -116,7 +116,7 @@ export default class TeamDropdownView { } handleOpen = () => { - log.debug('TeamDropdownView.handleOpen'); + log.debug('handleOpen'); if (!this.bounds) { return; @@ -129,7 +129,7 @@ export default class TeamDropdownView { } handleClose = () => { - log.debug('TeamDropdownView.handleClose'); + log.debug('handleClose'); this.view.setBounds(this.getBounds(0, 0)); WindowManager.sendToRenderer(CLOSE_TEAMS_DROPDOWN); @@ -137,7 +137,7 @@ export default class TeamDropdownView { } handleReceivedMenuSize = (event: IpcMainEvent, width: number, height: number) => { - log.silly('TeamDropdownView.handleReceivedMenuSize', {width, height}); + log.silly('handleReceivedMenuSize', {width, height}); this.bounds = this.getBounds(width, height); if (this.isOpen) { diff --git a/src/main/views/viewManager.ts b/src/main/views/viewManager.ts index 1bf69951..ef8e0306 100644 --- a/src/main/views/viewManager.ts +++ b/src/main/views/viewManager.ts @@ -2,7 +2,6 @@ // See LICENSE.txt for license information. import {BrowserView, dialog, ipcMain, IpcMainEvent} from 'electron'; -import log from 'electron-log'; import {BrowserViewConstructorOptions} from 'electron/main'; import {Tuple as tuple} from '@bloomberg/record-tuple-polyfill'; @@ -23,6 +22,7 @@ import { MAIN_WINDOW_SHOWN, } from 'common/communication'; import Config from 'common/config'; +import {Logger} from 'common/log'; import urlUtils, {equalUrlsIgnoringSubpath} from 'common/utils/url'; import Utils from 'common/utils/util'; import {MattermostServer} from 'common/servers/MattermostServer'; @@ -42,6 +42,7 @@ import modalManager from './modalManager'; import WebContentsEventManager from './webContentEvents'; import LoadingScreen from './loadingScreen'; +const log = new Logger('ViewManager'); const URL_VIEW_DURATION = 10 * SECOND; const URL_VIEW_HEIGHT = 20; @@ -114,7 +115,7 @@ export class ViewManager { * close, open, or reload tabs, taking care to reuse tabs and * preserve focus on the currently selected tab. */ reloadConfiguration = (configServers: TeamWithTabs[]) => { - log.debug('viewManager.reloadConfiguration'); + log.debug('reloadConfiguration'); const focusedTuple: TabTuple | undefined = this.views.get(this.currentView as string)?.urlTypeTuple; @@ -188,7 +189,7 @@ export class ViewManager { } showInitial = () => { - log.verbose('viewManager.showInitial'); + log.verbose('showInitial'); const servers = this.getServers(); if (servers.length) { @@ -211,7 +212,7 @@ export class ViewManager { } showByName = (name: string) => { - log.debug('viewManager.showByName', name); + log.debug('showByName', name); const newView = this.views.get(name); if (newView) { @@ -258,7 +259,7 @@ export class ViewManager { } activateView = (viewName: string) => { - log.debug('viewManager.activateView', viewName); + log.debug('activateView', viewName); if (this.currentView === viewName) { this.showByName(this.currentView); @@ -272,7 +273,7 @@ export class ViewManager { } finishLoading = (server: string) => { - log.debug('viewManager.finishLoading', server); + log.debug('finishLoading', server); const view = this.views.get(server); if (view && this.getCurrentView() === view) { @@ -299,7 +300,7 @@ export class ViewManager { } failLoading = (tabName: string) => { - log.debug('viewManager.failLoading', tabName); + log.debug('failLoading', tabName); LoadingScreen.fade(); if (this.currentView === tabName) { @@ -339,7 +340,7 @@ export class ViewManager { } showURLView = (url: URL | string) => { - log.silly('viewManager.showURLView', url); + log.silly('showURLView', url); if (this.urlViewCancel) { this.urlViewCancel(); @@ -415,7 +416,7 @@ export class ViewManager { } deeplinkSuccess = (viewName: string) => { - log.debug('viewManager.deeplinkSuccess', viewName); + log.debug('deeplinkSuccess', viewName); const view = this.views.get(viewName); if (!view) { @@ -435,7 +436,7 @@ export class ViewManager { } getViewByURL = (inputURL: URL | string, ignoreScheme = false) => { - log.silly('ViewManager.getViewByURL', `${inputURL}`, ignoreScheme); + log.silly('getViewByURL', `${inputURL}`, ignoreScheme); const parsedURL = urlUtils.parseURL(inputURL); if (!parsedURL) { diff --git a/src/main/views/webContentEvents.ts b/src/main/views/webContentEvents.ts index 4ea52509..1cc87885 100644 --- a/src/main/views/webContentEvents.ts +++ b/src/main/views/webContentEvents.ts @@ -2,9 +2,9 @@ // See LICENSE.txt for license information. import {BrowserWindow, session, shell, WebContents} from 'electron'; -import log from 'electron-log'; import Config from 'common/config'; +import {Logger} from 'common/log'; import urlUtils from 'common/utils/url'; import {flushCookiesStore} from 'main/app/utils'; @@ -23,6 +23,7 @@ type CustomLogin = { inProgress: boolean; } +const log = new Logger('WebContentsEventManager'); const scheme = protocols && protocols[0] && protocols[0].schemes && protocols[0].schemes[0]; export class WebContentsEventManager { @@ -35,6 +36,13 @@ export class WebContentsEventManager { this.listeners = {}; } + private log = (webContentsId?: number) => { + if (webContentsId) { + return log.withPrefix(String(webContentsId)); + } + return log; + } + private isTrustedPopupWindow = (webContentsId: number) => { if (!this.popupWindow) { return false; @@ -52,7 +60,7 @@ export class WebContentsEventManager { generateWillNavigate = (webContentsId: number) => { return (event: Event, url: string) => { - log.debug('webContentEvents.will-navigate', {webContentsId, url}); + this.log(webContentsId).debug('will-navigate', url); const parsedURL = urlUtils.parseURL(url)!; const serverURL = this.getServerURLFromWebContentsId(webContentsId); @@ -81,14 +89,14 @@ export class WebContentsEventManager { return; } - log.info(`Prevented desktop from navigating to: ${url}`); + this.log(webContentsId).info(`Prevented desktop from navigating to: ${url}`); event.preventDefault(); }; }; generateDidStartNavigation = (webContentsId: number) => { return (event: Event, url: string) => { - log.debug('webContentEvents.did-start-navigation', {webContentsId, url}); + this.log(webContentsId).debug('did-start-navigation', {webContentsId, url}); const parsedURL = urlUtils.parseURL(url)!; const serverURL = this.getServerURLFromWebContentsId(webContentsId); @@ -106,17 +114,17 @@ export class WebContentsEventManager { }; denyNewWindow = (details: Electron.HandlerDetails): {action: 'deny' | 'allow'} => { - log.warn(`Prevented popup window to open a new window to ${details.url}.`); + this.log().warn(`Prevented popup window to open a new window to ${details.url}.`); return {action: 'deny'}; }; generateNewWindowListener = (webContentsId: number, spellcheck?: boolean) => { return (details: Electron.HandlerDetails): {action: 'deny' | 'allow'} => { - log.debug('webContentEvents.new-window', details.url); + this.log(webContentsId).debug('new-window', details.url); const parsedURL = urlUtils.parseURL(details.url); if (!parsedURL) { - log.warn(`Ignoring non-url ${details.url}`); + this.log(webContentsId).warn(`Ignoring non-url ${details.url}`); return {action: 'deny'}; } @@ -170,11 +178,11 @@ export class WebContentsEventManager { return {action: 'deny'}; } if (urlUtils.isAdminUrl(serverURL, parsedURL)) { - log.info(`${details.url} is an admin console page, preventing to open a new window`); + this.log(webContentsId).info(`${details.url} is an admin console page, preventing to open a new window`); return {action: 'deny'}; } if (this.popupWindow && this.popupWindow.win.webContents.getURL() === details.url) { - log.info(`Popup window already open at provided url: ${details.url}`); + this.log(webContentsId).info(`Popup window already open at provided url: ${details.url}`); return {action: 'deny'}; } @@ -314,14 +322,14 @@ export class WebContentsEventManager { contents.removeListener('did-start-navigation', didStartNavigation); removeListeners?.(contents); } catch (e) { - log.error(`Error while trying to detach listeners, this might be ok if the process crashed: ${e}`); + this.log(contents.id).error(`Error while trying to detach listeners, this might be ok if the process crashed: ${e}`); } }; this.listeners[contents.id] = removeWebContentsListeners; contents.once('render-process-gone', (event, details) => { if (details.reason !== 'clean-exit') { - log.error('Renderer process for a webcontent is no longer available:', details.reason); + this.log(contents.id).error('Renderer process for a webcontent is no longer available:', details.reason); } removeWebContentsListeners(); }); diff --git a/src/main/windows/callsWidgetWindow.ts b/src/main/windows/callsWidgetWindow.ts index cb1c0f01..e2c1afe7 100644 --- a/src/main/windows/callsWidgetWindow.ts +++ b/src/main/windows/callsWidgetWindow.ts @@ -3,7 +3,6 @@ import {EventEmitter} from 'events'; import {BrowserWindow, ipcMain, IpcMainEvent, Rectangle} from 'electron'; -import log from 'electron-log'; import { CallsJoinedCallMessage, @@ -16,6 +15,7 @@ import {MattermostView} from 'main/views/MattermostView'; import {getLocalPreload} from 'main/utils'; +import {Logger} from 'common/log'; import {CALLS_PLUGIN_ID, MINIMUM_CALLS_WIDGET_HEIGHT, MINIMUM_CALLS_WIDGET_WIDTH} from 'common/utils/constants'; import Utils from 'common/utils/util'; import urlUtils, {getFormattedPathName} from 'common/utils/url'; @@ -31,6 +31,8 @@ type LoadURLOpts = { extraHeaders: string; } +const log = new Logger('CallsWidgetWindow'); + export default class CallsWidgetWindow extends EventEmitter { public win: BrowserWindow; private main: BrowserWindow; @@ -86,7 +88,7 @@ export default class CallsWidgetWindow extends EventEmitter { } public async close() { - log.debug('CallsWidgetWindow.close'); + log.debug('close'); return new Promise((resolve) => { if (this.win.isDestroyed()) { resolve(); @@ -113,7 +115,7 @@ export default class CallsWidgetWindow extends EventEmitter { if (url === this.getWidgetURL()) { return; } - log.warn(`CallsWidgetWindow: prevented widget window from navigating to: ${url}`); + log.warn(`prevented widget window from navigating to: ${url}`); ev.preventDefault(); } @@ -125,7 +127,7 @@ export default class CallsWidgetWindow extends EventEmitter { } private onClosed = () => { - log.debug('CallsWidgetWindow.onClosed'); + log.debug('onClosed'); this.emit('closed'); this.removeAllListeners('closed'); ipcMain.off(CALLS_WIDGET_RESIZE, this.onResize); @@ -150,10 +152,10 @@ export default class CallsWidgetWindow extends EventEmitter { } private onResize = (ev: IpcMainEvent, _: string, msg: CallsWidgetResizeMessage) => { - log.debug('CallsWidgetWindow.onResize', msg); + log.debug('onResize', msg); if (!this.isAllowedEvent(ev)) { - log.warn('CallsWidgetWindow.onResize', 'Disallowed calls event'); + log.warn('onResize', 'Disallowed calls event'); return; } @@ -170,7 +172,7 @@ export default class CallsWidgetWindow extends EventEmitter { } private onShareScreen = (ev: IpcMainEvent, _: string, message: CallsWidgetShareScreenMessage) => { - log.debug('CallsWidgetWindow.onShareScreen'); + log.debug('onShareScreen'); if (!this.isAllowedEvent(ev)) { log.warn('Disallowed calls event'); @@ -181,10 +183,10 @@ export default class CallsWidgetWindow extends EventEmitter { } private onJoinedCall = (ev: IpcMainEvent, _: string, message: CallsJoinedCallMessage) => { - log.debug('CallsWidgetWindow.onJoinedCall'); + log.debug('onJoinedCall'); if (!this.isAllowedEvent(ev)) { - log.warn('CallsWidgetWindow.onJoinedCall', 'Disallowed calls event'); + log.warn('onJoinedCall', 'Disallowed calls event'); return; } @@ -204,7 +206,7 @@ export default class CallsWidgetWindow extends EventEmitter { } private onShow = () => { - log.debug('CallsWidgetWindow.onShow'); + log.debug('onShow'); this.win.focus(); this.win.setVisibleOnAllWorkspaces(true, {visibleOnFullScreen: true, skipTransformProcessType: true}); @@ -237,7 +239,7 @@ export default class CallsWidgetWindow extends EventEmitter { }; } - log.warn(`CallsWidgetWindow.onPopOutOpen: prevented window open to ${url}`); + log.warn(`onPopOutOpen: prevented window open to ${url}`); return {action: 'deny' as const}; } @@ -253,7 +255,7 @@ export default class CallsWidgetWindow extends EventEmitter { } private onPopOutClosed = () => { - log.debug('CallsWidgetWindow.onPopOutClosed'); + log.debug('onPopOutClosed'); this.popOut?.removeAllListeners('closed'); this.popOut = null; } diff --git a/src/main/windows/mainWindow.ts b/src/main/windows/mainWindow.ts index 318ceae5..7f0d0a96 100644 --- a/src/main/windows/mainWindow.ts +++ b/src/main/windows/mainWindow.ts @@ -8,12 +8,12 @@ import path from 'path'; import os from 'os'; import {app, BrowserWindow, BrowserWindowConstructorOptions, dialog, Event, globalShortcut, Input, ipcMain, screen} from 'electron'; -import log from 'electron-log'; import {SavedWindowState} from 'types/mainWindow'; import {SELECT_NEXT_TAB, SELECT_PREVIOUS_TAB, GET_FULL_SCREEN_STATUS, FOCUS_THREE_DOT_MENU} from 'common/communication'; import Config from 'common/config'; +import {Logger} from 'common/log'; import {DEFAULT_WINDOW_HEIGHT, DEFAULT_WINDOW_WIDTH, MINIMUM_WINDOW_HEIGHT, MINIMUM_WINDOW_WIDTH} from 'common/utils/constants'; import Utils from 'common/utils/util'; import * as Validator from 'common/Validator'; @@ -24,6 +24,7 @@ import {localizeMessage} from 'main/i18nManager'; import ContextMenu from '../contextMenu'; import {getLocalPreload, getLocalURLString, isInsideRectangle} from '../utils'; +const log = new Logger('MainWindow'); const ALT_MENU_KEYS = ['Alt+F', 'Alt+E', 'Alt+V', 'Alt+H', 'Alt+W', 'Alt+P']; export class MainWindow { @@ -224,7 +225,7 @@ export class MainWindow { } private onClose = (event: Event) => { - log.debug('MainWindow.on.close'); + log.debug('onClose'); if (!this.win) { return; diff --git a/src/main/windows/settingsWindow.ts b/src/main/windows/settingsWindow.ts index ced050d4..f02ac97e 100644 --- a/src/main/windows/settingsWindow.ts +++ b/src/main/windows/settingsWindow.ts @@ -2,16 +2,18 @@ // See LICENSE.txt for license information. import {BrowserWindow, ipcMain} from 'electron'; -import log from 'electron-log'; import {SHOW_SETTINGS_WINDOW} from 'common/communication'; import Config from 'common/config'; +import {Logger} from 'common/log'; import ContextMenu from '../contextMenu'; import {getLocalPreload, getLocalURLString} from '../utils'; import MainWindow from './mainWindow'; +const log = new Logger('SettingsWindow'); + export class SettingsWindow { private win?: BrowserWindow; diff --git a/src/main/windows/windowManager.ts b/src/main/windows/windowManager.ts index 3bcf6f08..85c48b59 100644 --- a/src/main/windows/windowManager.ts +++ b/src/main/windows/windowManager.ts @@ -5,7 +5,6 @@ import path from 'path'; import {app, BrowserWindow, systemPreferences, ipcMain, IpcMainEvent, IpcMainInvokeEvent, desktopCapturer} from 'electron'; -import log from 'electron-log'; import { CallsJoinCallMessage, @@ -39,6 +38,7 @@ import { CALLS_ERROR, CALLS_LINK_CLICK, } from 'common/communication'; +import {Logger} from 'common/log'; import urlUtils from 'common/utils/url'; import {SECOND} from 'common/utils/constants'; import Config from 'common/config'; @@ -61,12 +61,13 @@ import DownloadsDropdownView from '../views/downloadsDropdownView'; import DownloadsDropdownMenuView from '../views/downloadsDropdownMenuView'; import MainWindow from './mainWindow'; - import CallsWidgetWindow from './callsWidgetWindow'; import SettingsWindow from './settingsWindow'; // singleton module to manage application's windows +const log = new Logger('WindowManager'); + export class WindowManager { assetsDir: string; @@ -112,7 +113,7 @@ export class WindowManager { genCallsEventHandler = (handler: CallsEventHandler) => { return (event: IpcMainEvent, viewName: string, msg?: any) => { if (this.callsWidgetWindow && !this.callsWidgetWindow.isAllowedEvent(event)) { - log.warn('WindowManager.genCallsEventHandler', 'Disallowed calls event'); + log.warn('genCallsEventHandler', 'Disallowed calls event'); return; } handler(viewName, msg); @@ -120,7 +121,7 @@ export class WindowManager { } createCallsWidgetWindow = async (viewName: string, msg: CallsJoinCallMessage) => { - log.debug('WindowManager.createCallsWidgetWindow'); + log.debug('createCallsWidgetWindow'); if (this.callsWidgetWindow) { // trying to join again the call we are already in should not be allowed. if (this.callsWidgetWindow.getCallID() === msg.callID) { @@ -148,7 +149,7 @@ export class WindowManager { } handleDesktopSourcesModalRequest = () => { - log.debug('WindowManager.handleDesktopSourcesModalRequest'); + log.debug('handleDesktopSourcesModalRequest'); if (this.callsWidgetWindow) { this.switchServer(this.callsWidgetWindow.getServerName()); @@ -158,7 +159,7 @@ export class WindowManager { } handleCallsWidgetChannelLinkClick = () => { - log.debug('WindowManager.handleCallsWidgetChannelLinkClick'); + log.debug('handleCallsWidgetChannelLinkClick'); if (this.callsWidgetWindow) { this.switchServer(this.callsWidgetWindow.getServerName()); @@ -168,7 +169,7 @@ export class WindowManager { } handleCallsError = (_: string, msg: CallsErrorMessage) => { - log.debug('WindowManager.handleCallsError', msg); + log.debug('handleCallsError', msg); if (this.callsWidgetWindow) { this.switchServer(this.callsWidgetWindow.getServerName()); @@ -178,7 +179,7 @@ export class WindowManager { } handleCallsLinkClick = (_: string, msg: CallsLinkClickMessage) => { - log.debug('WindowManager.handleCallsLinkClick with linkURL', msg.link); + log.debug('handleCallsLinkClick with linkURL', msg.link); if (this.callsWidgetWindow) { this.switchServer(this.callsWidgetWindow.getServerName()); @@ -188,13 +189,13 @@ export class WindowManager { } handleCallsLeave = () => { - log.debug('WindowManager.handleCallsLeave'); + log.debug('handleCallsLeave'); this.callsWidgetWindow?.close(); } showMainWindow = (deeplinkingURL?: string | URL) => { - log.debug('WindowManager.showMainWindow', deeplinkingURL); + log.debug('showMainWindow', deeplinkingURL); const mainWindow = MainWindow.get(); if (mainWindow) { @@ -252,7 +253,7 @@ export class WindowManager { isResizing = false; handleWillResizeMainWindow = (event: Event, newBounds: Electron.Rectangle) => { - log.silly('WindowManager.handleWillResizeMainWindow'); + log.silly('handleWillResizeMainWindow'); if (!(this.viewManager && MainWindow.get())) { return; @@ -282,7 +283,7 @@ export class WindowManager { } handleResizedMainWindow = () => { - log.silly('WindowManager.handleResizedMainWindow'); + log.silly('handleResizedMainWindow'); if (MainWindow.get()) { const bounds = this.getBounds(); @@ -300,14 +301,14 @@ export class WindowManager { } private throttledWillResize = (newBounds: Electron.Rectangle) => { - log.silly('WindowManager.throttledWillResize', {newBounds}); + log.silly('throttledWillResize', {newBounds}); this.isResizing = true; this.setCurrentViewBounds(newBounds); } handleResizeMainWindow = () => { - log.silly('WindowManager.handleResizeMainWindow'); + log.silly('handleResizeMainWindow'); if (!(this.viewManager && MainWindow.get())) { return; @@ -330,7 +331,7 @@ export class WindowManager { }; setCurrentViewBounds = (bounds: {width: number; height: number}) => { - log.debug('WindowManager.setCurrentViewBounds', {bounds}); + log.debug('setCurrentViewBounds', {bounds}); const currentView = this.viewManager?.getCurrentView(); if (currentView) { @@ -471,7 +472,7 @@ export class WindowManager { } switchServer = (serverName: string, waitForViewToExist = false) => { - log.debug('windowManager.switchServer'); + log.debug('switchServer'); this.showMainWindow(); const server = Config.teams.find((team) => team.name === serverName); if (!server) { @@ -499,14 +500,14 @@ export class WindowManager { } switchTab = (serverName: string, tabName: string) => { - log.debug('windowManager.switchTab'); + log.debug('switchTab'); this.showMainWindow(); const tabViewName = getTabViewName(serverName, tabName); this.viewManager?.showByName(tabViewName); } focusBrowserView = () => { - log.debug('WindowManager.focusBrowserView'); + log.debug('focusBrowserView'); if (this.viewManager) { this.viewManager.focus(); @@ -533,7 +534,7 @@ export class WindowManager { } handleReactAppInitialized = (e: IpcMainEvent, view: string) => { - log.debug('WindowManager.handleReactAppInitialized', view); + log.debug('handleReactAppInitialized', view); if (this.viewManager) { this.viewManager.setServerInitialized(view); @@ -592,7 +593,7 @@ export class WindowManager { } handleHistory = (event: IpcMainEvent, offset: number) => { - log.debug('WindowManager.handleHistory', offset); + log.debug('handleHistory', offset); if (this.viewManager) { const activeView = this.viewManager.getCurrentView(); @@ -645,7 +646,7 @@ export class WindowManager { } handleBrowserHistoryPush = (e: IpcMainEvent, viewName: string, pathName: string) => { - log.debug('WindowManager.handleBrowserHistoryPush', {viewName, pathName}); + log.debug('handleBrowserHistoryPush', {viewName, pathName}); const currentView = this.viewManager?.views.get(viewName); const cleanedPathName = urlUtils.cleanPathName(currentView?.tab.server.url.pathname || '', pathName); @@ -673,7 +674,7 @@ export class WindowManager { } handleBrowserHistoryButton = (e: IpcMainEvent, viewName: string) => { - log.debug('WindowManager.handleBrowserHistoryButton', viewName); + log.debug('handleBrowserHistoryButton', viewName); const currentView = this.viewManager?.views.get(viewName); if (currentView) { @@ -692,7 +693,7 @@ export class WindowManager { } handleAppLoggedIn = (event: IpcMainEvent, viewName: string) => { - log.debug('WindowManager.handleAppLoggedIn', viewName); + log.debug('handleAppLoggedIn', viewName); const view = this.viewManager?.views.get(viewName); if (view && !view.isLoggedIn) { @@ -702,7 +703,7 @@ export class WindowManager { } handleAppLoggedOut = (event: IpcMainEvent, viewName: string) => { - log.debug('WindowManager.handleAppLoggedOut', viewName); + log.debug('handleAppLoggedOut', viewName); const view = this.viewManager?.views.get(viewName); if (view && view.isLoggedIn) { @@ -719,11 +720,11 @@ export class WindowManager { } handleGetDesktopSources = async (viewName: string, opts: Electron.SourcesOptions) => { - log.debug('WindowManager.handleGetDesktopSources', {viewName, opts}); + log.debug('handleGetDesktopSources', {viewName, opts}); const view = this.viewManager?.views.get(viewName); if (!view) { - log.error('WindowManager.handleGetDesktopSources: view not found'); + log.error('handleGetDesktopSources: view not found'); return Promise.resolve(); } @@ -784,7 +785,7 @@ export class WindowManager { } handleReloadCurrentView = () => { - log.debug('WindowManager.handleReloadCurrentView'); + log.debug('handleReloadCurrentView'); const view = this.viewManager?.getCurrentView(); if (!view) {