Skip to content

Commit

Permalink
feat: Add developer option to send logs via email (WEBAPP-6493) (back…
Browse files Browse the repository at this point in the history
…port) (#3155)
  • Loading branch information
ffflorian authored Oct 24, 2019
1 parent d67c70b commit beb2a61
Show file tree
Hide file tree
Showing 5 changed files with 92 additions and 38 deletions.
5 changes: 4 additions & 1 deletion electron/src/logging/getLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
*/

import {LogFactory, LoggerOptions} from '@wireapp/commons';
import {remote} from 'electron';
import {app, remote} from 'electron';
import * as logdown from 'logdown';

import {config} from '../settings/config';

const mainProcess = remote ? remote.process : process;
const logDir = path.join((remote ? remote.app : app).getPath('userData'), 'logs');
const logFile = path.join(logDir, 'electron.log');

const isDevelopment = config.environment !== 'production';
const forceLogging = mainProcess.argv.includes('--enable-logging');
Expand All @@ -33,6 +35,7 @@ export const ENABLE_LOGGING = isDevelopment || forceLogging;

export function getLogger(name: string): logdown.Logger {
const options: LoggerOptions = {
logFilePath: logFile,
namespace: LOGGER_NAMESPACE,
separator: '/',
};
Expand Down
49 changes: 49 additions & 0 deletions electron/src/logging/loggerUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Wire
* Copyright (C) 2019 Wire Swiss GmbH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see http://www.gnu.org/licenses/.
*
*/

import {app} from 'electron';
import * as fs from 'fs-extra';
import * as globby from 'globby';
import * as path from 'path';

const logDir = path.join(app.getPath('userData'), 'logs');

export function getLogFiles(base: string = logDir, absolute: boolean = false): Promise<string[]> {
return globby('**/*.{log,old}', {cwd: base, followSymbolicLinks: false, onlyFiles: true, absolute});
}

export async function gatherLogs(): Promise<string> {
let log = '';

const relativeFilePaths = await getLogFiles();

for (const relativeFilePath of relativeFilePaths) {
const resolvedPath = path.join(logDir, relativeFilePath);
log += `\n\n+++++++ ${relativeFilePath} +++++++\n`;
try {
const fileContent = await fs.readFile(resolvedPath, 'utf-8');
log += fileContent || '(no content)\n';
} catch (error) {
log += '(fle not readable)\n';
}
log += '++++++++++++++++++++++++++++\n';
}

return log || 'No log files found.';
}
60 changes: 24 additions & 36 deletions electron/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import {WebViewFocus} from './lib/webViewFocus';
import * as locale from './locale/locale';
import {ENABLE_LOGGING, getLogger} from './logging/getLogger';
import {Raygun} from './logging/initRaygun';
import {getLogFiles} from './logging/loggerUtils';
import {menuItem as developerMenu} from './menu/developer';
import * as systemMenu from './menu/system';
import {TrayHandler} from './menu/TrayHandler';
Expand Down Expand Up @@ -276,9 +277,9 @@ const showMainWindow = (mainWindowState: WindowStateKeeper.State) => {

// App Events
const handleAppEvents = () => {
app.on('window-all-closed', async () => {
app.on('window-all-closed', () => {
if (!EnvironmentUtil.platform.IS_MAC_OS) {
await lifecycle.quit();
lifecycle.quit();
}
});

Expand Down Expand Up @@ -310,41 +311,27 @@ const handleAppEvents = () => {
});
};

const renameFileExtensions = (files: string[], oldExtension: string, newExtension: string): void => {
files
.filter(file => {
try {
return fs.statSync(file).isFile();
} catch (statError) {
return false;
const renameFileExtensions = async (files: string[], oldExtension: string, newExtension: string): Promise<void> => {
for (const file of files) {
try {
const fileStat = await fs.stat(file);
if (fileStat.isFile() && file.endsWith(oldExtension)) {
await fs.rename(file, file.replace(oldExtension, newExtension));
}
})
.forEach(file => {
if (file.endsWith(oldExtension)) {
try {
fs.renameSync(file, file.replace(oldExtension, newExtension));
} catch (error) {
logger.error(`Failed to rename log file: "${error.message}"`);
}
}
});
};

const renameWebViewLogFiles = (): void => {
// Rename "console.log" to "console.old" (for every log directory of every account)
fs.readdir(LOG_DIR, (readError, contents) => {
if (readError) {
return logger.log(`Failed to read log directory with error: ${readError.message}`);
} catch (error) {
logger.error(`Failed to rename log file: "${error.message}"`);
}

const logFiles = contents.map(file => path.join(LOG_DIR, file, config.logFileName));
renameFileExtensions(logFiles, '.log', '.old');
});
}
};

const initElectronLogFile = (): void => {
renameFileExtensions([LOG_FILE], '.log', '.old');
fs.ensureFileSync(LOG_FILE);
const renameWebViewLogFiles = async (): Promise<void> => {
// Rename "console.log" to "console.old" (for every log directory of every account)
try {
const logFiles = await getLogFiles(LOG_DIR, true);
await renameFileExtensions(logFiles, '.log', '.old');
} catch (error) {
logger.log(`Failed to read log directory with error: ${error.message}`);
}
};

const addLinuxWorkarounds = () => {
Expand Down Expand Up @@ -519,7 +506,8 @@ if (lifecycle.isFirstInstance) {
addLinuxWorkarounds();
bindIpcEvents();
handleAppEvents();
renameWebViewLogFiles();
initElectronLogFile();
new ElectronWrapperInit().run().catch(logger.error);
renameWebViewLogFiles()
.then(() => fs.ensureFile(LOG_FILE))
.then(() => new ElectronWrapperInit().run())
.catch(error => logger.error(error));
}
15 changes: 14 additions & 1 deletion electron/src/menu/developer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@
*
*/

import {MenuItem, app} from 'electron';
import {MenuItem, app, shell} from 'electron';

import {gatherLogs} from '../logging/loggerUtils';
import * as EnvironmentUtil from '../runtime/EnvironmentUtil';
import {config} from '../settings/config';
import {settings} from '../settings/ConfigurationPersistence';
Expand All @@ -33,6 +34,17 @@ const reloadTemplate: Electron.MenuItemConstructorOptions = {
label: 'Reload',
};

const sendLogTemplate: Electron.MenuItemConstructorOptions = {
click: async () => {
const logText = await gatherLogs();
const subject = encodeURIComponent('Wire Desktop Log');
const body = encodeURIComponent(logText);
const mailToLink = `mailto:[email protected]?subject=${subject}&body=${body}`;
await shell.openExternal(mailToLink);
},
label: 'Send Debug Logs',
};

const devToolsTemplate: Electron.MenuItemConstructorOptions = {
label: 'Toggle DevTools',
submenu: [
Expand Down Expand Up @@ -109,6 +121,7 @@ const menuTemplate: Electron.MenuItemConstructorOptions = {
submenu: [
devToolsTemplate,
reloadTemplate,
sendLogTemplate,
separatorTemplate,
...createEnvironmentTemplates(),
separatorTemplate,
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"electron-window-state": "5.0.3",
"file-url": "3.0.0",
"fs-extra": "8.0.1",
"globby": "10.0.1",
"iconv-lite": "0.5.0",
"image-type": "4.1.0",
"lodash": "4.17.15",
Expand Down

0 comments on commit beb2a61

Please sign in to comment.