- Migrate to `electron-log` v5.X.X, centralizing log files to adhere to best-practices. - Add critical event logging in the log file. - Replace `ElectronLog` type with `LogFunctions` for better abstraction. - Unify log handling in `desktop-runtime-error` by removing `renderer.log` due to `electron-log` v5 changes. - Update and extend logger interfaces, removing 'I' prefix and adding common log levels to abstract `electron-log` completely. - Move logger interfaces to the application layer as it's cross-cutting concern, meanwhile keeping the implementations in the infrastructure layer. - Introduce `useLogger` hook for easier logging in Vue components. - Simplify `WindowVariables` by removing nullable properties. - Improve documentation to clearly differentiate between desktop and web versions, outlining specific features of each.
92 lines
2.9 KiB
TypeScript
92 lines
2.9 KiB
TypeScript
import { unlink, readFile } from 'fs/promises';
|
|
import { join } from 'path';
|
|
import { log, die, LogLevel } from '../utils/log';
|
|
import { exists } from '../utils/io';
|
|
import { SupportedPlatform, CURRENT_PLATFORM } from '../utils/platform';
|
|
import { getAppName } from '../utils/npm';
|
|
|
|
export async function clearAppLogFiles(
|
|
projectDir: string,
|
|
): Promise<void> {
|
|
if (!projectDir) { throw new Error('missing project directory'); }
|
|
const logPath = await determineLogPath(projectDir);
|
|
if (!logPath || !await exists(logPath)) {
|
|
log(`Skipping clearing logs, log file does not exist: ${logPath}.`);
|
|
return;
|
|
}
|
|
try {
|
|
await unlink(logPath);
|
|
log(`Successfully cleared the log file at: ${logPath}.`);
|
|
} catch (error) {
|
|
die(`Failed to clear the log file at: ${logPath}. Reason: ${error}`);
|
|
}
|
|
}
|
|
|
|
export async function readAppLogFile(
|
|
projectDir: string,
|
|
): Promise<AppLogFileResult> {
|
|
if (!projectDir) { throw new Error('missing project directory'); }
|
|
const logPath = await determineLogPath(projectDir);
|
|
if (!logPath || !await exists(logPath)) {
|
|
log(`No log file at: ${logPath}`, LogLevel.Warn);
|
|
return {
|
|
logFilePath: logPath,
|
|
};
|
|
}
|
|
const logContent = await readLogFile(logPath);
|
|
return {
|
|
logFileContent: logContent,
|
|
logFilePath: logPath,
|
|
};
|
|
}
|
|
|
|
interface AppLogFileResult {
|
|
readonly logFilePath: string;
|
|
readonly logFileContent?: string;
|
|
}
|
|
|
|
async function determineLogPath(
|
|
projectDir: string,
|
|
): Promise<string> {
|
|
if (!projectDir) { throw new Error('missing project directory'); }
|
|
const logFileName = 'main.log';
|
|
const appName = await getAppName(projectDir);
|
|
if (!appName) {
|
|
return die('App name not found.');
|
|
}
|
|
const logFilePaths: {
|
|
readonly [K in SupportedPlatform]: () => string;
|
|
} = {
|
|
[SupportedPlatform.macOS]: () => {
|
|
if (!process.env.HOME) {
|
|
throw new Error('HOME environment variable is not defined');
|
|
}
|
|
return join(process.env.HOME, 'Library', 'Logs', appName, logFileName);
|
|
},
|
|
[SupportedPlatform.Linux]: () => {
|
|
if (!process.env.HOME) {
|
|
throw new Error('HOME environment variable is not defined');
|
|
}
|
|
return join(process.env.HOME, '.config', appName, 'logs', logFileName);
|
|
},
|
|
[SupportedPlatform.Windows]: () => {
|
|
if (!process.env.USERPROFILE) {
|
|
throw new Error('USERPROFILE environment variable is not defined');
|
|
}
|
|
return join(process.env.USERPROFILE, 'AppData', 'Roaming', appName, 'logs', logFileName);
|
|
},
|
|
};
|
|
const logFilePath = logFilePaths[CURRENT_PLATFORM]?.();
|
|
if (!logFilePath) {
|
|
log(`Cannot determine log path, unsupported OS: ${SupportedPlatform[CURRENT_PLATFORM]}`, LogLevel.Warn);
|
|
}
|
|
return logFilePath;
|
|
}
|
|
|
|
async function readLogFile(
|
|
logFilePath: string,
|
|
): Promise<string | undefined> {
|
|
const content = await readFile(logFilePath, 'utf-8');
|
|
return content?.trim().length > 0 ? content : undefined;
|
|
}
|