diff --git a/app/crashReports.ts b/app/crashReports.ts index 91934c1a0d96..bfb71ee0d8e7 100644 --- a/app/crashReports.ts +++ b/app/crashReports.ts @@ -46,11 +46,11 @@ async function eraseDumps( ); } -export async function setup(getLogger: () => LoggerType): Promise { - const isEnabled = !isProduction(app.getVersion()); +export function setup(getLogger: () => LoggerType, forceEnable = false): void { + const isEnabled = !isProduction(app.getVersion()) || forceEnable; if (isEnabled) { - getLogger().info('crashReporter: enabled'); + getLogger().info(`crashReporter: ${forceEnable ? 'force ' : ''}enabled`); crashReporter.start({ uploadToServer: false }); } diff --git a/app/main.ts b/app/main.ts index 085fdbb9f453..0c6eaf3419b5 100644 --- a/app/main.ts +++ b/app/main.ts @@ -44,7 +44,7 @@ import { createSupportUrl } from '../ts/util/createSupportUrl'; import { missingCaseError } from '../ts/util/missingCaseError'; import { strictAssert } from '../ts/util/assert'; import { drop } from '../ts/util/drop'; -import { consoleLogger } from '../ts/util/consoleLogger'; +import { createBufferedConsoleLogger } from '../ts/util/consoleLogger'; import type { ThemeSettingType } from '../ts/types/StorageUIKeys'; import { ThemeType } from '../ts/types/Util'; import * as Errors from '../ts/types/errors'; @@ -135,6 +135,16 @@ let mainWindow: BrowserWindow | undefined; let mainWindowCreated = false; let loadingWindow: BrowserWindow | undefined; +// Create a buffered logger to hold our log lines until we fully initialize +// the logger in `app.on('ready')` +const consoleLogger = createBufferedConsoleLogger(); + +// These will be set after app fires the 'ready' event +let logger: LoggerType | undefined; +let preferredSystemLocales: Array | undefined; +let resolvedTranslationsLocale: LocaleType | undefined; +let settingsChannel: SettingsChannel | undefined; + const activeWindows = new Set(); function getMainWindow() { @@ -170,6 +180,12 @@ const defaultWebPrefs = { const DISABLE_GPU = OS.isLinux() && !process.argv.some(arg => arg === '--enable-gpu'); +const FORCE_ENABLE_CRASH_REPORTS = process.argv.some( + arg => arg === '--enable-crash-reports' +); + +setupCrashReports(getLogger, FORCE_ENABLE_CRASH_REPORTS); + function showWindow() { if (!mainWindow) { return; @@ -347,12 +363,6 @@ if (windowFromUserConfig) { let menuOptions: CreateTemplateOptionsType | undefined; -// These will be set after app fires the 'ready' event -let logger: LoggerType | undefined; -let preferredSystemLocales: Array | undefined; -let resolvedTranslationsLocale: LocaleType | undefined; -let settingsChannel: SettingsChannel | undefined; - function getLogger(): LoggerType { if (!logger) { console.warn('getLogger: Logger not yet initialized!'); @@ -1673,7 +1683,8 @@ app.on('ready', async () => { logger = await logging.initialize(getMainWindow); - await setupCrashReports(getLogger); + // Write buffered information into newly created logger. + consoleLogger.writeBufferInto(logger); if (!resolvedTranslationsLocale) { preferredSystemLocales = resolveCanonicalLocales( diff --git a/ts/logging/debuglogs.ts b/ts/logging/debuglogs.ts index 8b631fbc7b82..393ea38b442b 100644 --- a/ts/logging/debuglogs.ts +++ b/ts/logging/debuglogs.ts @@ -39,7 +39,6 @@ const getHeader = ( capabilities, remoteConfig, statistics, - appMetrics, user, }: Omit, nodeVersion: string, @@ -57,29 +56,6 @@ const getHeader = ( headerSection('User info', user), headerSection('Capabilities', capabilities), headerSection('Remote config', remoteConfig), - headerSection( - 'Metrics', - appMetrics.reduce((acc, stats, index) => { - const { - type = '?', - serviceName = '?', - name = '?', - cpu, - memory, - } = stats; - - const processId = `${index}:${type}/${serviceName}/${name}`; - - return { - ...acc, - [processId]: - `cpuUsage=${cpu.percentCPUUsage.toFixed(2)} ` + - `wakeups=${cpu.idleWakeupsPerSecond} ` + - `workingMemory=${memory.workingSetSize} ` + - `peakWorkingMemory=${memory.peakWorkingSetSize}`, - }; - }, {}) - ), headerSection('Statistics', statistics), headerSectionTitle('Logs'), ].join('\n'); diff --git a/ts/logging/main_process_logging.ts b/ts/logging/main_process_logging.ts index 6126f295ee2a..c13452b3ab87 100644 --- a/ts/logging/main_process_logging.ts +++ b/ts/logging/main_process_logging.ts @@ -26,7 +26,6 @@ import { CircularBuffer } from 'cirbuf'; import type { LoggerType } from '../types/Logging'; import * as Errors from '../types/errors'; -import * as durations from '../util/durations'; import { createRotatingPinoDest } from '../util/rotatingPinoDest'; import * as log from './log'; @@ -64,13 +63,6 @@ export async function initialize( const logPath = join(basePath, 'logs'); mkdirSync(logPath, { recursive: true }); - let appMetrics = app.getAppMetrics(); - - setInterval(() => { - // CPU stats are computed since the last call to `getAppMetrics`. - appMetrics = app.getAppMetrics(); - }, 30 * durations.SECOND).unref(); - try { await cleanupLogs(logPath); } catch (error) { @@ -141,7 +133,6 @@ export async function initialize( ]); data = { logEntries, - appMetrics, ...rest, }; } catch (error) { @@ -340,7 +331,7 @@ export function fetchLogs(logPath: string): Promise> { export const fetchAdditionalLogData = ( mainWindow: BrowserWindow -): Promise> => +): Promise> => new Promise(resolve => { mainWindow.webContents.send('additional-log-data-request'); ipc.once('additional-log-data-response', (_event, data) => { diff --git a/ts/logging/shared.ts b/ts/logging/shared.ts index 5912c9f6fe1f..00f4b7c26340 100644 --- a/ts/logging/shared.ts +++ b/ts/logging/shared.ts @@ -2,7 +2,6 @@ // SPDX-License-Identifier: AGPL-3.0-only import pino from 'pino'; -import type { ProcessMetric } from 'electron'; import { isRecord } from '../util/isRecord'; import { redactAll } from '../util/privacy'; import { missingCaseError } from '../util/missingCaseError'; @@ -16,7 +15,6 @@ export type FetchLogIpcData = { remoteConfig: Record; statistics: Record; user: Record; - appMetrics: ReadonlyArray; // We expect `logEntries` to be `Array`, but we don't validate that // upfront—we only validate it when we go to log each line. This improves the diff --git a/ts/util/consoleLogger.ts b/ts/util/consoleLogger.ts index 47ed99ee8e1b..02658931e162 100644 --- a/ts/util/consoleLogger.ts +++ b/ts/util/consoleLogger.ts @@ -24,4 +24,48 @@ export const consoleLogger: LoggerType = { console.log(...args); }, }; + +export type BufferedLoggerType = LoggerType & { + writeBufferInto(logger: LoggerType): void; +}; + +export function createBufferedConsoleLogger(): BufferedLoggerType { + type BufferEntryType = Readonly<{ + level: keyof LoggerType; + args: Array; + }>; + const buffer = new Array(); + return { + fatal(...args: Array) { + buffer.push({ level: 'fatal', args }); + console.error(...args); + }, + error(...args: Array) { + buffer.push({ level: 'error', args }); + console.error(...args); + }, + warn(...args: Array) { + buffer.push({ level: 'warn', args }); + console.warn(...args); + }, + info(...args: Array) { + buffer.push({ level: 'info', args }); + console.info(...args); + }, + debug(...args: Array) { + buffer.push({ level: 'debug', args }); + console.debug(...args); + }, + trace(...args: Array) { + buffer.push({ level: 'trace', args }); + console.log(...args); + }, + + writeBufferInto(output) { + for (const { level, args } of buffer) { + output[level](...args); + } + }, + }; +} /* eslint-enable no-console */