add more logging to all the source files

This commit is contained in:
Vishwas Shashidhar 2019-05-16 19:00:00 +05:30
parent a053faedda
commit 4a7fe58fba
13 changed files with 159 additions and 74 deletions

View File

@ -1,6 +1,5 @@
import { app } from 'electron'; import { app } from 'electron';
import { logger } from '../common/logger';
import { isDevEnv } from '../common/env';
import { getCommandLineArgs } from '../common/utils'; import { getCommandLineArgs } from '../common/utils';
import { config, IConfig } from './config-handler'; import { config, IConfig } from './config-handler';
@ -8,6 +7,7 @@ import { config, IConfig } from './config-handler';
* Sets chrome flags * Sets chrome flags
*/ */
export const setChromeFlags = () => { export const setChromeFlags = () => {
logger.info(`chrome-flags: Checking if we need to set chrome flags!`);
const { customFlags } = config.getGlobalConfigFields([ 'customFlags' ]) as IConfig; const { customFlags } = config.getGlobalConfigFields([ 'customFlags' ]) as IConfig;
const configFlags: object = { const configFlags: object = {
@ -23,44 +23,51 @@ export const setChromeFlags = () => {
if (!Object.prototype.hasOwnProperty.call(configFlags, key)) { if (!Object.prototype.hasOwnProperty.call(configFlags, key)) {
continue; continue;
} }
if (key && configFlags[key]) { const val = configFlags[key];
app.commandLine.appendSwitch(key, configFlags[key]); if (key && val) {
logger.info(`chrome-flags: Setting chrome flag for ${key} with value ${val}!`);
app.commandLine.appendSwitch(key, val);
} }
} }
if (isDevEnv) { logger.info(`chrome-flags: Checking to see if we have any flags passsed from command line!`);
const chromeFlagsFromCmd = getCommandLineArgs(process.argv, '--chrome-flags=', false); const chromeFlagsFromCmd = getCommandLineArgs(process.argv, '--chrome-flags=', false);
if (!chromeFlagsFromCmd) { if (!chromeFlagsFromCmd) {
logger.info(`chrome-flags: No flags passed from command line, returning`);
return;
}
const chromeFlagsArgs = chromeFlagsFromCmd.substr(15);
logger.info(`chrome-flags: Command line args passed as ${chromeFlagsArgs}`);
if (!chromeFlagsArgs) {
logger.info(`chrome-flags: Not a valid set of args passed through command line for setting chrome flags, returning`);
return;
}
const flags = chromeFlagsArgs.split(',');
logger.info(`chrome-flags: Flags we have are ${flags}`);
if (!flags || !Array.isArray(flags)) {
logger.info(`chrome-flags: Empty set of flags passed! returning`);
return;
}
for (const key in flags) {
if (!Object.prototype.hasOwnProperty.call(flags, key)) {
continue;
}
if (!flags[key]) {
return; return;
} }
const chromeFlagsArgs = chromeFlagsFromCmd.substr(15); const flagArray = flags[key].split(':');
if (!chromeFlagsArgs) {
return;
}
const flags = chromeFlagsArgs.split(','); if (flagArray && Array.isArray(flagArray) && flagArray.length > 0) {
if (!flags || !Array.isArray(flags)) { const chromeFlagKey = flagArray[0];
return; const chromeFlagValue = flagArray[1];
} logger.info(`chrome-flags: Setting chrome flag from command line for key ${chromeFlagKey} and value ${chromeFlagValue}`);
app.commandLine.appendSwitch(chromeFlagKey, chromeFlagValue);
for (const key in flags) {
if (!Object.prototype.hasOwnProperty.call(flags, key)) {
continue;
}
if (!flags[key]) {
return;
}
const flagArray = flags[key].split(':');
if (flagArray && Array.isArray(flagArray) && flagArray.length > 0) {
const chromeFlagKey = flagArray[0];
const chromeFlagValue = flagArray[1];
app.commandLine.appendSwitch(chromeFlagKey, chromeFlagValue);
}
} }
} }
}; };

View File

@ -106,6 +106,7 @@ class Config {
* @param fields * @param fields
*/ */
public getConfigFields(fields: string[]): IConfig { public getConfigFields(fields: string[]): IConfig {
logger.info(`config-handler: Trying to get config values for the fields ${fields}`);
return { ...this.getGlobalConfigFields(fields), ...this.getUserConfigFields(fields) } as IConfig; return { ...this.getGlobalConfigFields(fields), ...this.getUserConfigFields(fields) } as IConfig;
} }
@ -115,6 +116,7 @@ class Config {
* @param fields {Array} * @param fields {Array}
*/ */
public getUserConfigFields(fields: string[]): IConfig { public getUserConfigFields(fields: string[]): IConfig {
logger.info(`config-handler: Trying to get user config values for the fields ${fields}`);
return pick(this.userConfig, fields) as IConfig; return pick(this.userConfig, fields) as IConfig;
} }
@ -124,6 +126,7 @@ class Config {
* @param fields {Array} * @param fields {Array}
*/ */
public getGlobalConfigFields(fields: string[]): IConfig { public getGlobalConfigFields(fields: string[]): IConfig {
logger.info(`config-handler: Trying to get global config values for the fields ${fields}`);
return pick(this.globalConfig, fields) as IConfig; return pick(this.globalConfig, fields) as IConfig;
} }
@ -133,12 +136,14 @@ class Config {
* @param data {IConfig} * @param data {IConfig}
*/ */
public async updateUserConfig(data: Partial<IConfig>): Promise<void> { public async updateUserConfig(data: Partial<IConfig>): Promise<void> {
logger.info(`config-handler: updating user config values with the data ${data}`);
this.userConfig = { ...this.userConfig, ...data }; this.userConfig = { ...this.userConfig, ...data };
try { try {
await writeFile(this.userConfigPath, JSON.stringify(this.userConfig), { encoding: 'utf8' }); await writeFile(this.userConfigPath, JSON.stringify(this.userConfig), { encoding: 'utf8' });
logger.info(`config-handler: updated user config values with the data ${data}`);
} catch (error) { } catch (error) {
logger.error(`config-handler: failed to update user config file with ${data}`, error); logger.error(`config-handler: failed to update user config file with ${data}`, error);
dialog.showErrorBox('Error updating user config file', 'failed to write user config file with ${}'); dialog.showErrorBox(`Update failed`, `Failed to update user config due to error: ${error}`);
} }
} }
@ -161,6 +166,7 @@ class Config {
const filteredFields: IConfig = omit(this.userConfig, ignoreSettings) as IConfig; const filteredFields: IConfig = omit(this.userConfig, ignoreSettings) as IConfig;
// update to the new build number // update to the new build number
filteredFields.buildNumber = buildNumber; filteredFields.buildNumber = buildNumber;
logger.info(`config-handler: setting first time launch for build ${buildNumber}`);
return await this.updateUserConfig(filteredFields); return await this.updateUserConfig(filteredFields);
} }
} }
@ -173,11 +179,14 @@ class Config {
private parseConfigData(data: string): object { private parseConfigData(data: string): object {
let parsedData; let parsedData;
if (!data) { if (!data) {
logger.error(`config-handler: unable to read config file`);
throw new Error('unable to read user config file'); throw new Error('unable to read user config file');
} }
try { try {
parsedData = JSON.parse(data); parsedData = JSON.parse(data);
logger.info(`config-handler: parsed JSON file with data ${JSON.stringify(parsedData)}`);
} catch (e) { } catch (e) {
logger.error(`config-handler: parsing JSON file failed due to error ${e}`);
throw new Error(e); throw new Error(e);
} }
return parsedData; return parsedData;
@ -191,9 +200,11 @@ class Config {
*/ */
private async readUserConfig() { private async readUserConfig() {
if (!fs.existsSync(this.userConfigPath)) { if (!fs.existsSync(this.userConfigPath)) {
logger.info(`config-handler: user config doesn't exist! will create new one and update config`);
await this.updateUserConfig({ configVersion: app.getVersion().toString(), buildNumber } as IConfig); await this.updateUserConfig({ configVersion: app.getVersion().toString(), buildNumber } as IConfig);
} }
this.userConfig = this.parseConfigData(fs.readFileSync(this.userConfigPath, 'utf8')); this.userConfig = this.parseConfigData(fs.readFileSync(this.userConfigPath, 'utf8'));
logger.info(`config-handler: user config exists with data ${JSON.stringify(this.userConfig)}`);
} }
/** /**
@ -201,24 +212,28 @@ class Config {
*/ */
private readGlobalConfig() { private readGlobalConfig() {
this.globalConfig = this.parseConfigData(fs.readFileSync(this.globalConfigPath, 'utf8')); this.globalConfig = this.parseConfigData(fs.readFileSync(this.globalConfigPath, 'utf8'));
logger.info(`config-handler: global config exists with data ${JSON.stringify(this.globalConfig)}`);
} }
/** /**
* Verifies if the application is launched for the first time * Verifies if the application is launched for the first time
*/ */
private async checkFirstTimeLaunch() { private async checkFirstTimeLaunch() {
logger.info('checking first launch'); logger.info('config-handler: checking first time launch');
const configBuildNumber = this.userConfig && (this.userConfig as IConfig).buildNumber || null; const configBuildNumber = this.userConfig && (this.userConfig as IConfig).buildNumber || null;
if (!configBuildNumber) { if (!configBuildNumber) {
logger.info(`config-handler: there's no build number found, this is a first time launch`);
this.isFirstTime = true; this.isFirstTime = true;
return; return;
} }
if (configBuildNumber && typeof configBuildNumber === 'string' && configBuildNumber !== buildNumber) { if (configBuildNumber && typeof configBuildNumber === 'string' && configBuildNumber !== buildNumber) {
logger.info(`config-handler: build number found is of an older build, this is a first time launch`);
this.isFirstTime = true; this.isFirstTime = true;
return; return;
} }
logger.info(`config-handler: build number is the same as the previous build, not a first time launch`);
this.isFirstTime = false; this.isFirstTime = false;
} }
} }

View File

@ -30,45 +30,43 @@ app.setAsDefaultProtocolClient('symphony');
*/ */
const startApplication = async () => { const startApplication = async () => {
await app.whenReady(); await app.whenReady();
logger.info(`main: app is ready, performing initial checks`);
createAppCacheFile(); createAppCacheFile();
windowHandler.showLoadingScreen(); windowHandler.showLoadingScreen();
windowHandler.createApplication(); windowHandler.createApplication();
logger.info(`main: created application`);
if (config.isFirstTimeLaunch()) { if (config.isFirstTimeLaunch()) {
logger.info('first time launch'); logger.info(`main: This is a first time launch! will update config and handle auto launch`);
await config.setUpFirstTimeLaunch(); await config.setUpFirstTimeLaunch();
/**
* Enables or disables auto launch base on user settings
*/
await autoLaunchInstance.handleAutoLaunch(); await autoLaunchInstance.handleAutoLaunch();
} }
/**
* Sets chrome flags from global config
*/
setChromeFlags(); setChromeFlags();
}; };
// Handle multiple/single instances // Handle multiple/single instances
if (!allowMultiInstance) { if (!allowMultiInstance) {
logger.info('Multiple instance not allowed requesting lock', { allowMultiInstance }); logger.info('main: Multiple instances are not allowed, requesting lock', { allowMultiInstance });
const gotTheLock = app.requestSingleInstanceLock(); const gotTheLock = app.requestSingleInstanceLock();
// quit if another instance is already running, ignore for dev env or if app was started with multiInstance flag // quit if another instance is already running, ignore for dev env or if app was started with multiInstance flag
if (!gotTheLock) { if (!gotTheLock) {
logger.info('Got the lock hence closing the instance', { gotTheLock }); logger.info(`main: got the lock hence closing the new instance`, { gotTheLock });
app.quit(); app.quit();
} else { } else {
logger.info('Creating the first instance of the application'); logger.info(`main: Creating the first instance of the application`);
app.on('second-instance', (_event, argv) => { app.on('second-instance', (_event, argv) => {
// Someone tried to run a second instance, we should focus our window. // Someone tried to run a second instance, we should focus our window.
logger.info(`main: We've got a second instance of the app, will check if it's allowed and exit if not`);
const mainWindow = windowHandler.getMainWindow(); const mainWindow = windowHandler.getMainWindow();
if (mainWindow && !mainWindow.isDestroyed()) { if (mainWindow && !mainWindow.isDestroyed()) {
if (isMac) { if (isMac) {
logger.info(`main: We are on mac, so, showing the existing window`);
return mainWindow.show(); return mainWindow.show();
} }
if (mainWindow.isMinimized()) { if (mainWindow.isMinimized()) {
logger.info(`main: our main window is minimised, will restore it!`);
mainWindow.restore(); mainWindow.restore();
} }
mainWindow.focus(); mainWindow.focus();
@ -78,7 +76,7 @@ if (!allowMultiInstance) {
startApplication(); startApplication();
} }
} else { } else {
logger.info('Multiple instance allowed hence create application', { allowMultiInstance }); logger.info(`main: multi instance allowed, creating second instance`, { allowMultiInstance });
startApplication(); startApplication();
} }
@ -86,12 +84,18 @@ if (!allowMultiInstance) {
* Is triggered when all the windows are closed * Is triggered when all the windows are closed
* In which case we quit the app * In which case we quit the app
*/ */
app.on('window-all-closed', () => app.quit()); app.on('window-all-closed', () => {
logger.info(`main: all windows are closed, quitting the app!`);
app.quit();
});
/** /**
* Creates a new empty cache file when the app is quit * Creates a new empty cache file when the app is quit
*/ */
app.on('quit', () => cleanUpAppCache()); app.on('quit', () => {
logger.info(`main: quitting the app!`);
cleanUpAppCache();
});
/** /**
* Cleans up reference before quiting * Cleans up reference before quiting
@ -107,9 +111,11 @@ app.on('before-quit', () => windowHandler.willQuitApp = true);
app.on('activate', () => { app.on('activate', () => {
const mainWindow: ICustomBrowserWindow | null = windowHandler.getMainWindow(); const mainWindow: ICustomBrowserWindow | null = windowHandler.getMainWindow();
if (!mainWindow || mainWindow.isDestroyed()) { if (!mainWindow || mainWindow.isDestroyed()) {
logger.info(`main: main window not existing or destroyed, creating a new instance of the main window!`);
startApplication(); startApplication();
return; return;
} }
logger.info(`main: activating & showing main window now!`);
mainWindow.show(); mainWindow.show();
}); });
@ -118,4 +124,7 @@ app.on('activate', () => {
* *
* This event is emitted only on macOS at this moment * This event is emitted only on macOS at this moment
*/ */
app.on('open-url', (_event, url) => protocolHandler.sendProtocol(url)); app.on('open-url', (_event, url) => {
logger.info(`main: we got a protocol request with url ${url}! processing the request!`);
protocolHandler.sendProtocol(url);
});

View File

@ -30,6 +30,7 @@ class MemoryMonitor {
*/ */
public setMemoryInfo(memoryInfo: Electron.ProcessMemoryInfo): void { public setMemoryInfo(memoryInfo: Electron.ProcessMemoryInfo): void {
this.memoryInfo = memoryInfo; this.memoryInfo = memoryInfo;
logger.info(`memory-monitor: setting memory info to ${memoryInfo}`);
this.validateMemory(); this.validateMemory();
} }
@ -40,15 +41,17 @@ class MemoryMonitor {
*/ */
public setMeetingStatus(isInMeeting: boolean): void { public setMeetingStatus(isInMeeting: boolean): void {
this.isInMeeting = isInMeeting; this.isInMeeting = isInMeeting;
logger.info(`memory-monitor: setting meeting status to ${isInMeeting}`);
} }
/** /**
* Validates the predefined conditions and refreshes the client * Validates the predefined conditions and refreshes the client
*/ */
private validateMemory(): void { private validateMemory(): void {
logger.info(`memory-monitor: validating memory refresh conditions`);
const { memoryRefresh } = config.getConfigFields([ 'memoryRefresh' ]); const { memoryRefresh } = config.getConfigFields([ 'memoryRefresh' ]);
if (!memoryRefresh) { if (!memoryRefresh) {
logger.info(`memory refresh is disabled`); logger.info(`memory-monitor: memory refresh is disabled in the config, not going to refresh!`);
return; return;
} }
@ -61,7 +64,7 @@ class MemoryMonitor {
&& idleTime > this.maxIdleTime && idleTime > this.maxIdleTime
&& (workingSetSizeInMB > this.memoryThreshold)) && (workingSetSizeInMB > this.memoryThreshold))
) { ) {
logger.info(`Not Reloading the app as logger.info(`memory-monitor: Not Reloading the app as
application was refreshed less than a hour ago? ${this.canReload ? 'no' : 'yes'} application was refreshed less than a hour ago? ${this.canReload ? 'no' : 'yes'}
memory consumption is ${(workingSetSizeInMB) || 'unknown'}mb is less than? ${this.memoryThreshold}mb memory consumption is ${(workingSetSizeInMB) || 'unknown'}mb is less than? ${this.memoryThreshold}mb
system idle tick was ${idleTime}ms is less than? ${this.maxIdleTime}ms system idle tick was ${idleTime}ms is less than? ${this.maxIdleTime}ms
@ -71,7 +74,7 @@ class MemoryMonitor {
} }
const mainWindow = windowHandler.getMainWindow(); const mainWindow = windowHandler.getMainWindow();
if (mainWindow && windowExists(mainWindow)) { if (mainWindow && windowExists(mainWindow)) {
logger.info(`Reloading the app to optimize memory usage as logger.info(`memory-monitor: Reloading the app to optimize memory usage as
memory consumption is ${workingSetSizeInMB}mb is greater than? ${this.memoryThreshold}mb threshold memory consumption is ${workingSetSizeInMB}mb is greater than? ${this.memoryThreshold}mb threshold
system idle tick was ${idleTime}ms is greater than ${this.maxIdleTime}ms system idle tick was ${idleTime}ms is greater than ${this.maxIdleTime}ms
user was in a meeting? ${this.isInMeeting} user was in a meeting? ${this.isInMeeting}

View File

@ -1,5 +1,6 @@
import { apiName } from '../common/api-interface'; import { apiName } from '../common/api-interface';
import { isMac } from '../common/env'; import { isMac } from '../common/env';
import { logger } from '../common/logger';
import { getCommandLineArgs } from '../common/utils'; import { getCommandLineArgs } from '../common/utils';
import { activate } from './window-actions'; import { activate } from './window-actions';
@ -25,9 +26,10 @@ class ProtocolHandler {
*/ */
public setPreloadWebContents(webContents: Electron.WebContents): void { public setPreloadWebContents(webContents: Electron.WebContents): void {
this.preloadWebContents = webContents; this.preloadWebContents = webContents;
// check for cashed protocol uri and process it logger.info(`protocol handler: SFE is active and we have a valid protocol window with web contents!`);
if (this.protocolUri) { if (this.protocolUri) {
this.sendProtocol(this.protocolUri); this.sendProtocol(this.protocolUri);
logger.info(`protocol handler: we have a cached url ${this.protocolUri}, so, processed the request to SFE!`);
this.protocolUri = null; this.protocolUri = null;
} }
} }
@ -35,12 +37,14 @@ class ProtocolHandler {
/** /**
* Sends the protocol uri to the web app to further process * Sends the protocol uri to the web app to further process
* *
* @param uri {String} * @param url {String}
* @param isAppRunning {Boolean} - whether the application is running * @param isAppRunning {Boolean} - whether the application is running
*/ */
public sendProtocol(uri: string, isAppRunning: boolean = true): void { public sendProtocol(url: string, isAppRunning: boolean = true): void {
logger.info(`protocol handler: processing protocol request for the url ${url}!`);
if (!this.preloadWebContents || !isAppRunning) { if (!this.preloadWebContents || !isAppRunning) {
this.protocolUri = uri; logger.info(`protocol handler: app was started from the protocol request. Caching the URL ${url}!`);
this.protocolUri = url;
return; return;
} }
// This is needed for mac OS as it brings pop-outs to foreground // This is needed for mac OS as it brings pop-outs to foreground
@ -49,8 +53,9 @@ class ProtocolHandler {
activate(apiName.mainWindowName); activate(apiName.mainWindowName);
} }
if (ProtocolHandler.isValidProtocolUri(uri)) { if (ProtocolHandler.isValidProtocolUri(url)) {
this.preloadWebContents.send('protocol-action', uri); logger.info(`protocol handler: our protocol request is a valid url ${url}! sending request to SFE for further action!`);
this.preloadWebContents.send('protocol-action', url);
} }
} }
@ -60,8 +65,10 @@ class ProtocolHandler {
* @param argv {String[]} - data received from process.argv * @param argv {String[]} - data received from process.argv
*/ */
public processArgv(argv?: string[]): void { public processArgv(argv?: string[]): void {
logger.info(`protocol handler: processing protocol args!`);
const protocolUriFromArgv = getCommandLineArgs(argv || process.argv, protocol.SymphonyProtocol, false); const protocolUriFromArgv = getCommandLineArgs(argv || process.argv, protocol.SymphonyProtocol, false);
if (protocolUriFromArgv) { if (protocolUriFromArgv) {
logger.info(`protocol handler: we have a protocol request for the url ${protocolUriFromArgv}!`);
this.sendProtocol(protocolUriFromArgv, false); this.sendProtocol(protocolUriFromArgv, false);
} }
} }

View File

@ -6,6 +6,7 @@ import * as path from 'path';
import { isMac } from '../common/env'; import { isMac } from '../common/env';
import { i18n } from '../common/i18n'; import { i18n } from '../common/i18n';
import { logger } from '../common/logger';
/** /**
* Archives files in the source directory * Archives files in the source directory
@ -19,14 +20,17 @@ import { i18n } from '../common/i18n';
const generateArchiveForDirectory = (source: string, destination: string, fileExtensions: string[]): Promise<void> => { const generateArchiveForDirectory = (source: string, destination: string, fileExtensions: string[]): Promise<void> => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
logger.info(`reports-handler: generating archive for directory ${source}`);
const output = fs.createWriteStream(destination); const output = fs.createWriteStream(destination);
const archive = archiver('zip', { zlib: { level: 9 } }); const archive = archiver('zip', { zlib: { level: 9 } });
output.on('close', () => { output.on('close', () => {
logger.info(`reports-handler: generated archive for directory ${source}`);
return resolve(); return resolve();
}); });
archive.on('error', (err) => { archive.on('error', (err: Error) => {
logger.error(`reports-handler: error archiving directory for ${source} with error ${err}`);
return reject(err); return reject(err);
}); });
@ -69,8 +73,9 @@ export const exportLogs = (): void => {
const focusedWindow = BrowserWindow.getFocusedWindow(); const focusedWindow = BrowserWindow.getFocusedWindow();
if (!fs.existsSync(source) && focusedWindow && !focusedWindow.isDestroyed()) { if (!fs.existsSync(source) && focusedWindow && !focusedWindow.isDestroyed()) {
logger.error(`reports-handler: Can't find any logs to share!`);
dialog.showMessageBox(focusedWindow, { dialog.showMessageBox(focusedWindow, {
message: i18n.t('No logs are available to share')(), message: i18n.t(`Can't find any logs to share!`)(),
title: i18n.t('Failed!')(), title: i18n.t('Failed!')(),
type: 'error', type: 'error',
}); });
@ -86,6 +91,7 @@ export const exportLogs = (): void => {
}) })
.catch((err) => { .catch((err) => {
if (focusedWindow && !focusedWindow.isDestroyed()) { if (focusedWindow && !focusedWindow.isDestroyed()) {
logger.error(`reports-handler: Can't share logs due to error ${err}`);
dialog.showMessageBox(focusedWindow, { dialog.showMessageBox(focusedWindow, {
message: `${i18n.t('Unable to generate logs due to ')()} ${err}`, message: `${i18n.t('Unable to generate logs due to ')()} ${err}`,
title: i18n.t('Failed!')(), title: i18n.t('Failed!')(),

View File

@ -38,26 +38,32 @@ class ScreenSnippet {
* @param webContents {Electron.webContents} * @param webContents {Electron.webContents}
*/ */
public async capture(webContents: Electron.webContents) { public async capture(webContents: Electron.webContents) {
logger.info(`screen-snippet-handler: Starting screen capture!`);
this.outputFileName = path.join(this.tempDir, 'symphonyImage-' + Date.now() + '.jpg'); this.outputFileName = path.join(this.tempDir, 'symphonyImage-' + Date.now() + '.jpg');
this.captureUtilArgs = isMac this.captureUtilArgs = isMac
? [ '-i', '-s', '-t', 'jpg', this.outputFileName ] ? [ '-i', '-s', '-t', 'jpg', this.outputFileName ]
: [ this.outputFileName, i18n.getLocale() ]; : [ this.outputFileName, i18n.getLocale() ];
logger.info(`screen-snippet-handler: Capturing snippet with file ${this.outputFileName} and args ${this.captureUtilArgs}!`);
const mainWindow = windowHandler.getMainWindow(); const mainWindow = windowHandler.getMainWindow();
if (mainWindow) { if (mainWindow) {
this.isAlwaysOnTop = mainWindow.isAlwaysOnTop(); this.isAlwaysOnTop = mainWindow.isAlwaysOnTop();
logger.info(`screen-snippet-handler: Is main window always on top? ${this.isAlwaysOnTop}!`);
updateAlwaysOnTop(false, false); updateAlwaysOnTop(false, false);
} }
// only allow one screen capture at a time. // only allow one screen capture at a time.
if (this.child) { if (this.child) {
logger.info(`screen-snippet-handler: Child screen capture exists, killing it and keeping only 1 instance!`);
this.child.kill(); this.child.kill();
} }
try { try {
await this.execCmd(this.captureUtil, this.captureUtilArgs); await this.execCmd(this.captureUtil, this.captureUtilArgs);
const { message, data, type }: IScreenSnippet = await this.convertFileToData(); const { message, data, type }: IScreenSnippet = await this.convertFileToData();
logger.info(`screen-snippet-handler: Snippet captured! Sending data to SFE`);
webContents.send('screen-snippet-data', { message, data, type }); webContents.send('screen-snippet-data', { message, data, type });
} catch (error) { } catch (error) {
logger.error(`screen-snippet: screen snippet process was killed`, error); logger.error(`screen-snippet-handler: screen capture failed with error: ${error}!`);
} }
} }
@ -105,10 +111,12 @@ class ScreenSnippet {
private async convertFileToData(): Promise<IScreenSnippet> { private async convertFileToData(): Promise<IScreenSnippet> {
try { try {
if (!this.outputFileName) { if (!this.outputFileName) {
logger.info(`screen-snippet-handler: screen capture failed! output file doesn't exist!`);
return { message: 'output file name is required', type: 'ERROR' }; return { message: 'output file name is required', type: 'ERROR' };
} }
const data = await readFile(this.outputFileName); const data = await readFile(this.outputFileName);
if (!data) { if (!data) {
logger.info(`screen-snippet-handler: screen capture failed! data doesn't exist!`);
return { message: `no file data provided`, type: 'ERROR' }; return { message: `no file data provided`, type: 'ERROR' };
} }
// convert binary data to base64 encoded string // convert binary data to base64 encoded string
@ -125,10 +133,9 @@ class ScreenSnippet {
// remove tmp file (async) // remove tmp file (async)
if (this.outputFileName) { if (this.outputFileName) {
fs.unlink(this.outputFileName, (removeErr) => { fs.unlink(this.outputFileName, (removeErr) => {
// note: node complains if calling async logger.info(`screen-snippet-handler: cleaning up temp snippet file: ${this.outputFileName}!`);
// func without callback.
if (removeErr) { if (removeErr) {
logger.error(`ScreenSnippet: error removing temp snippet file: ${this.outputFileName}, err: ${removeErr}`); logger.error(`screen-snippet-handler: error removing temp snippet file: ${this.outputFileName}, err: ${removeErr}`);
} }
}); });
} }

View File

@ -4,6 +4,7 @@ import * as path from 'path';
import { ContextMenuBuilder, DictionarySync, SpellCheckHandler } from 'electron-spellchecker'; import { ContextMenuBuilder, DictionarySync, SpellCheckHandler } from 'electron-spellchecker';
import { isDevEnv, isMac } from '../common/env'; import { isDevEnv, isMac } from '../common/env';
import { i18n, LocaleType } from '../common/i18n'; import { i18n, LocaleType } from '../common/i18n';
import { logger } from '../common/logger';
export class SpellChecker { export class SpellChecker {
public locale: LocaleType = 'en-US'; public locale: LocaleType = 'en-US';
@ -42,6 +43,7 @@ export class SpellChecker {
const contextMenuBuilder = new ContextMenuBuilder(this.spellCheckHandler, webContents, false, this.processMenu); const contextMenuBuilder = new ContextMenuBuilder(this.spellCheckHandler, webContents, false, this.processMenu);
contextMenuBuilder.setAlternateStringFormatter(this.getStringTable()); contextMenuBuilder.setAlternateStringFormatter(this.getStringTable());
this.locale = i18n.getLocale(); this.locale = i18n.getLocale();
logger.info(`spell-check-handler: Building context menu with locale ${this.locale}!`);
const contextMenuListener = (_event, info) => { const contextMenuListener = (_event, info) => {
if (this.locale !== i18n.getLocale()) { if (this.locale !== i18n.getLocale()) {
contextMenuBuilder.setAlternateStringFormatter(this.getStringTable()); contextMenuBuilder.setAlternateStringFormatter(this.getStringTable());
@ -52,6 +54,7 @@ export class SpellChecker {
webContents.on('context-menu', contextMenuListener); webContents.on('context-menu', contextMenuListener);
webContents.once('destroyed', () => { webContents.once('destroyed', () => {
logger.info(`spell-check-handler: web contents destroyed, removing context menu listener!`);
webContents.removeListener('context-menu', contextMenuListener); webContents.removeListener('context-menu', contextMenuListener);
}); });
} }

View File

@ -1,7 +1,7 @@
import { BrowserWindow } from 'electron'; import { BrowserWindow } from 'electron';
import { apiName, IBoundsChange, KeyCodes } from '../common/api-interface'; import { apiName, IBoundsChange, KeyCodes } from '../common/api-interface';
import { isMac, isWindowsOS } from '../common/env'; import { isMac, isWindowsOS } from '../common/env';
import { logger } from '../common/logger';
import { throttle } from '../common/utils'; import { throttle } from '../common/utils';
import { config } from './config-handler'; import { config } from './config-handler';
import { ICustomBrowserWindow, windowHandler } from './window-handler'; import { ICustomBrowserWindow, windowHandler } from './window-handler';
@ -95,6 +95,7 @@ export const activate = (windowName: string, shouldFocus: boolean = true): void
* @param shouldActivateMainWindow * @param shouldActivateMainWindow
*/ */
export const updateAlwaysOnTop = (shouldSetAlwaysOnTop: boolean, shouldActivateMainWindow: boolean = true): void => { export const updateAlwaysOnTop = (shouldSetAlwaysOnTop: boolean, shouldActivateMainWindow: boolean = true): void => {
logger.info(`window-actions: Should we set always on top? ${shouldSetAlwaysOnTop}!`);
const browserWins: ICustomBrowserWindow[] = BrowserWindow.getAllWindows() as ICustomBrowserWindow[]; const browserWins: ICustomBrowserWindow[] = BrowserWindow.getAllWindows() as ICustomBrowserWindow[];
if (browserWins.length > 0) { if (browserWins.length > 0) {
browserWins browserWins
@ -107,6 +108,7 @@ export const updateAlwaysOnTop = (shouldSetAlwaysOnTop: boolean, shouldActivateM
const mainWindow = windowHandler.getMainWindow(); const mainWindow = windowHandler.getMainWindow();
if (mainWindow && mainWindow.winName && shouldActivateMainWindow) { if (mainWindow && mainWindow.winName && shouldActivateMainWindow) {
activate(mainWindow.winName); activate(mainWindow.winName);
logger.info(`window-actions: activated main window!`);
} }
} }
}; };

View File

@ -225,7 +225,7 @@ export class WindowHandler {
public createApplication() { public createApplication() {
this.spellchecker = new SpellChecker(); this.spellchecker = new SpellChecker();
logger.info(`initialized spellchecker module with locale ${this.spellchecker.locale}`); logger.info(`window-handler: initialized spellchecker module with locale ${this.spellchecker.locale}`);
// set window opts with additional config // set window opts with additional config
this.mainWindow = new BrowserWindow({ this.mainWindow = new BrowserWindow({
@ -235,13 +235,16 @@ export class WindowHandler {
const { isFullScreen, isMaximized } = this.config.mainWinPos ? this.config.mainWinPos : { isFullScreen: false, isMaximized: false }; const { isFullScreen, isMaximized } = this.config.mainWinPos ? this.config.mainWinPos : { isFullScreen: false, isMaximized: false };
if (isMaximized) { if (isMaximized) {
this.mainWindow.maximize(); this.mainWindow.maximize();
logger.info(`window-handler: window is maximized!`);
} }
if (isFullScreen) { if (isFullScreen) {
logger.info(`window-handler: window is in full screen!`);
this.mainWindow.setFullScreen(true); this.mainWindow.setFullScreen(true);
} }
// Event needed to hide native menu bar on Windows 10 as we use custom menu bar // Event needed to hide native menu bar on Windows 10 as we use custom menu bar
this.mainWindow.webContents.once('did-start-loading', () => { this.mainWindow.webContents.once('did-start-loading', () => {
logger.info(`window-handler: main window web contents started loading!`);
if ((this.config.isCustomTitleBar || isWindowsOS) && this.mainWindow && windowExists(this.mainWindow)) { if ((this.config.isCustomTitleBar || isWindowsOS) && this.mainWindow && windowExists(this.mainWindow)) {
this.mainWindow.setMenuBarVisibility(false); this.mainWindow.setMenuBarVisibility(false);
} }
@ -254,8 +257,10 @@ export class WindowHandler {
// loads the main window with url from config/cmd line // loads the main window with url from config/cmd line
this.mainWindow.loadURL(this.url); this.mainWindow.loadURL(this.url);
this.mainWindow.webContents.on('did-finish-load', async () => { this.mainWindow.webContents.on('did-finish-load', async () => {
logger.info(`window-handler: main window web contents finished loading!`);
// early exit if the window has already been destroyed // early exit if the window has already been destroyed
if (!this.mainWindow || !windowExists(this.mainWindow)) { if (!this.mainWindow || !windowExists(this.mainWindow)) {
logger.info(`window-handler: main window web contents destroyed already! exiting`);
return; return;
} }
this.url = this.mainWindow.webContents.getURL(); this.url = this.mainWindow.webContents.getURL();
@ -277,7 +282,7 @@ export class WindowHandler {
}); });
this.mainWindow.webContents.on('did-fail-load', (_event, errorCode, errorDesc, validatedURL) => { this.mainWindow.webContents.on('did-fail-load', (_event, errorCode, errorDesc, validatedURL) => {
logger.error(`Failed to load ${validatedURL}, with an error: ${errorCode}::${errorDesc}`); logger.error(`window-handler: Failed to load ${validatedURL}, with an error: ${errorCode}::${errorDesc}`);
this.loadFailError = errorDesc; this.loadFailError = errorDesc;
}); });
@ -301,8 +306,10 @@ export class WindowHandler {
this.mainWindow.webContents.on('crashed', (_event: Event, killed: boolean) => { this.mainWindow.webContents.on('crashed', (_event: Event, killed: boolean) => {
if (killed) { if (killed) {
logger.info(`window-handler: main window crashed (killed)!`);
return; return;
} }
logger.info(`window-handler: main window crashed!`);
electron.dialog.showMessageBox({ electron.dialog.showMessageBox({
type: 'error', type: 'error',
title: i18n.t('Renderer Process Crashed')(), title: i18n.t('Renderer Process Crashed')(),
@ -323,6 +330,7 @@ export class WindowHandler {
} }
if (this.willQuitApp) { if (this.willQuitApp) {
logger.info(`window-handler: app is quitting, destroying all windows!`);
return this.destroyAllWindows(); return this.destroyAllWindows();
} }
@ -336,6 +344,7 @@ export class WindowHandler {
}); });
this.mainWindow.once('closed', () => { this.mainWindow.once('closed', () => {
logger.info(`window-handler: main window closed, destroying all windows!`);
this.destroyAllWindows(); this.destroyAllWindows();
}); });
@ -369,8 +378,10 @@ export class WindowHandler {
* all the HTML content have been injected * all the HTML content have been injected
*/ */
public initMainWindow(): void { public initMainWindow(): void {
logger.info(`window-handler: initializing main window!`);
if (this.mainWindow && windowExists(this.mainWindow)) { if (this.mainWindow && windowExists(this.mainWindow)) {
if (!this.isOnline && this.loadingWindow && windowExists(this.loadingWindow)) { if (!this.isOnline && this.loadingWindow && windowExists(this.loadingWindow)) {
logger.info(`window-handler: network is offline!`);
this.loadingWindow.webContents.send('loading-screen-data', { error: 'NETWORK_OFFLINE' }); this.loadingWindow.webContents.send('loading-screen-data', { error: 'NETWORK_OFFLINE' });
return; return;
} }
@ -378,6 +389,7 @@ export class WindowHandler {
// close the loading window when // close the loading window when
// the main windows finished loading // the main windows finished loading
if (this.loadingWindow && windowExists(this.loadingWindow)) { if (this.loadingWindow && windowExists(this.loadingWindow)) {
logger.info(`window-handler: closing loading window as the main window is now ready!`);
this.loadingWindow.close(); this.loadingWindow.close();
} }
@ -412,6 +424,7 @@ export class WindowHandler {
* @param winKey {string} - Unique ID assigned to the window * @param winKey {string} - Unique ID assigned to the window
*/ */
public closeWindow(windowType: WindowTypes, winKey?: string): void { public closeWindow(windowType: WindowTypes, winKey?: string): void {
logger.info(`window-handler: closing window type ${windowType} with key ${winKey}!`);
switch (windowType) { switch (windowType) {
case 'screen-picker': case 'screen-picker':
if (this.screenPickerWindow && windowExists(this.screenPickerWindow)) { if (this.screenPickerWindow && windowExists(this.screenPickerWindow)) {
@ -489,8 +502,10 @@ export class WindowHandler {
return; return;
} }
if (error) { if (error) {
logger.info(`window-handler: loading screen failed ${error}!`);
this.loadingWindow.webContents.send('loading-screen-data', { error }); this.loadingWindow.webContents.send('loading-screen-data', { error });
} }
logger.info(`window-handler: loading screen started ${error}!`);
}); });
ipcMain.once('reload-symphony', () => { ipcMain.once('reload-symphony', () => {
@ -767,6 +782,7 @@ export class WindowHandler {
public openUrlInDefaultBrowser(urlToOpen) { public openUrlInDefaultBrowser(urlToOpen) {
if (urlToOpen) { if (urlToOpen) {
electron.shell.openExternal(urlToOpen); electron.shell.openExternal(urlToOpen);
logger.info(`window-handler: opened url ${urlToOpen} in the default browser!`);
} }
} }
@ -793,6 +809,7 @@ export class WindowHandler {
* Registers keyboard shortcuts or devtools * Registers keyboard shortcuts or devtools
*/ */
private registerGlobalShortcuts(): void { private registerGlobalShortcuts(): void {
logger.info(`window-handler: registering global shortcuts!`);
globalShortcut.register(isMac ? 'Cmd+Alt+I' : 'Ctrl+Shift+I', this.onRegisterDevtools); globalShortcut.register(isMac ? 'Cmd+Alt+I' : 'Ctrl+Shift+I', this.onRegisterDevtools);
app.on('browser-window-focus', () => { app.on('browser-window-focus', () => {
@ -819,6 +836,7 @@ export class WindowHandler {
return; return;
} }
focusedWindow.webContents.closeDevTools(); focusedWindow.webContents.closeDevTools();
logger.info(`window-handler: dev tools disabled by admin, showing error dialog to user!`);
electron.dialog.showMessageBox(focusedWindow, { electron.dialog.showMessageBox(focusedWindow, {
type: 'warning', type: 'warning',
buttons: [ 'Ok' ], buttons: [ 'Ok' ],

View File

@ -52,9 +52,11 @@ export const preventWindowNavigation = (browserWindow: BrowserWindow, isPopOutWi
if (!browserWindow || !windowExists(browserWindow)) { if (!browserWindow || !windowExists(browserWindow)) {
return; return;
} }
logger.info(`window-utils: preventing window from navigating!`);
const listener = (e: Electron.Event, winUrl: string) => { const listener = (e: Electron.Event, winUrl: string) => {
if (!winUrl.startsWith('http' || 'https')) { if (!winUrl.startsWith('http' || 'https')) {
logger.info(`window-utils: ${winUrl} doesn't start with http or https, so, not navigating!`);
e.preventDefault(); e.preventDefault();
return; return;
} }
@ -158,10 +160,12 @@ export const createComponentWindow = (
*/ */
export const showBadgeCount = (count: number): void => { export const showBadgeCount = (count: number): void => {
if (typeof count !== 'number') { if (typeof count !== 'number') {
logger.warn(`badgeCount: invalid func arg, must be a number: ${count}`); logger.warn(`window-utils: badgeCount: invalid func arg, must be a number: ${count}`);
return; return;
} }
logger.info(`window-utils: updating barge count to ${count}!`);
if (isMac) { if (isMac) {
// too big of a number here and setBadgeCount crashes // too big of a number here and setBadgeCount crashes
app.setBadgeCount(Math.min(1e8, count)); app.setBadgeCount(Math.min(1e8, count));
@ -219,7 +223,7 @@ export const isValidWindow = (browserWin: Electron.BrowserWindow): boolean => {
} }
if (!result) { if (!result) {
logger.warn('invalid window try to perform action, ignoring action'); logger.warn('window-utils: invalid window try to perform action, ignoring action');
} }
return result; return result;
@ -231,10 +235,12 @@ export const isValidWindow = (browserWin: Electron.BrowserWindow): boolean => {
* @param locale {LocaleType} * @param locale {LocaleType}
*/ */
export const updateLocale = (locale: LocaleType): void => { export const updateLocale = (locale: LocaleType): void => {
logger.info(`window-utils: updating locale to ${locale}!`);
// sets the new locale // sets the new locale
i18n.setLocale(locale); i18n.setLocale(locale);
const appMenu = windowHandler.appMenu; const appMenu = windowHandler.appMenu;
if (appMenu) { if (appMenu) {
logger.info(`window-utils: updating app menu with locale ${locale}!`);
appMenu.update(locale); appMenu.update(locale);
} }
}; };
@ -454,8 +460,10 @@ export const isSymphonyReachable = (window: ICustomBrowserWindow | null) => {
return; return;
} }
const podUrl = `${protocol}//${hostname}`; const podUrl = `${protocol}//${hostname}`;
logger.info(`window-utils: checking to see if pod ${podUrl} is reachable!`);
fetch(podUrl, { method: 'GET' }).then((rsp) => { fetch(podUrl, { method: 'GET' }).then((rsp) => {
if (rsp.status === 200 && windowHandler.isOnline) { if (rsp.status === 200 && windowHandler.isOnline) {
logger.info(`window-utils: pod ${podUrl} is reachable, loading main window!`);
window.loadURL(podUrl); window.loadURL(podUrl);
if (networkStatusCheckIntervalId) { if (networkStatusCheckIntervalId) {
clearInterval(networkStatusCheckIntervalId); clearInterval(networkStatusCheckIntervalId);
@ -463,9 +471,9 @@ export const isSymphonyReachable = (window: ICustomBrowserWindow | null) => {
} }
return; return;
} }
logger.warn(`Symphony down! statusCode: ${rsp.status} is online: ${windowHandler.isOnline}`); logger.warn(`window-utils: POD is down! statusCode: ${rsp.status}, is online: ${windowHandler.isOnline}`);
}).catch((error) => { }).catch((error) => {
logger.error(`Network status check: No active network connection ${error}`); logger.error(`window-utils: Network status check: No active network connection ${error}`);
}); });
}, networkStatusCheckInterval); }, networkStatusCheckInterval);
}; };

View File

@ -30,7 +30,7 @@ export class AnimationQueue {
try { try {
await object.func.apply(null, object.args); await object.func.apply(null, object.args);
} catch (err) { } catch (err) {
logger.error(`animationQueue: encountered an error: ${err} with stack trace: ${err.stack}`); logger.error(`animation-queue: encountered an error: ${err} with stack trace: ${err.stack}`);
} finally { } finally {
if (this.queue.length > 0) { if (this.queue.length > 0) {
// Run next animation // Run next animation

View File

@ -57,7 +57,7 @@ export class WhitelistHandler {
* returns true if hostName or domain present in the whitelist * returns true if hostName or domain present in the whitelist
* *
* @param url {String} - url the electron is navigated to * @param url {String} - url the electron is navigated to
* @param whitelistUrl {String} - coma separated whitelists * @param whitelistUrl {String} - comma separated whitelists
* *
* @returns {boolean} * @returns {boolean}
*/ */