fix(crash-logging): migrate filesystem persistence to smartfs and stabilize crash log tests

This commit is contained in:
2026-03-24 19:00:14 +00:00
parent 0f794f76e8
commit 70c925a780
15 changed files with 2408 additions and 3611 deletions

View File

@@ -3,6 +3,8 @@ import * as paths from '../paths.js';
import type { IProcessLog } from '../shared/protocol/ipc.types.js';
import type { ProcessId } from '../shared/protocol/id.js';
const smartfs = new plugins.smartfs.SmartFs(new plugins.smartfs.SmartFsProviderNode());
/**
* Manages crash log storage for failed processes
*/
@@ -54,7 +56,7 @@ export class CrashLogManager {
});
// Write crash log
await plugins.smartfile.memory.toFs(crashReport, filepath);
await smartfs.file(filepath).encoding('utf8').write(crashReport);
// Rotate old logs if needed
await this.rotateOldLogs();
@@ -193,7 +195,7 @@ export class CrashLogManager {
* Ensure crash logs directory exists
*/
private async ensureCrashLogsDir(): Promise<void> {
await plugins.smartfile.fs.ensureDir(this.crashLogsDir);
await smartfs.directory(this.crashLogsDir).create();
}
/**
@@ -202,17 +204,18 @@ export class CrashLogManager {
private async rotateOldLogs(): Promise<void> {
try {
// Get all crash log files
const files = await plugins.smartfile.fs.listFileTree(this.crashLogsDir, '*.log');
const entries = await smartfs.directory(this.crashLogsDir).list();
const files = entries.filter(e => e.name.endsWith('.log'));
if (files.length <= this.MAX_CRASH_LOGS) {
return; // No rotation needed
}
// Get file stats and sort by modification time (oldest first)
const fileStats = await Promise.all(
files.map(async (file) => {
const filepath = plugins.path.join(this.crashLogsDir, file);
const stats = await plugins.smartfile.fs.stat(filepath);
files.map(async (entry) => {
const filepath = plugins.path.join(this.crashLogsDir, entry.name);
const stats = await smartfs.file(filepath).stat();
return { filepath, mtime: stats.mtime.getTime() };
})
);
@@ -222,7 +225,7 @@ export class CrashLogManager {
// Delete oldest files to stay under limit
const filesToDelete = fileStats.length - this.MAX_CRASH_LOGS;
for (let i = 0; i < filesToDelete; i++) {
await plugins.smartfile.fs.remove(fileStats[i].filepath);
await smartfs.file(fileStats[i].filepath).delete();
console.log(`Rotated old crash log: ${plugins.path.basename(fileStats[i].filepath)}`);
}
} catch (error) {
@@ -236,8 +239,9 @@ export class CrashLogManager {
public async getCrashLogsForProcess(processId: ProcessId): Promise<string[]> {
try {
await this.ensureCrashLogsDir();
const files = await plugins.smartfile.fs.listFileTree(this.crashLogsDir, `*_${processId}_*.log`);
return files.map(file => plugins.path.join(this.crashLogsDir, file));
const entries = await smartfs.directory(this.crashLogsDir).list();
const files = entries.filter(e => e.name.endsWith('.log') && e.name.includes(`_${processId}_`));
return files.map(entry => plugins.path.join(this.crashLogsDir, entry.name));
} catch (error) {
console.error(`Failed to get crash logs for process ${processId}:`, error);
return [];
@@ -250,16 +254,17 @@ export class CrashLogManager {
public async cleanupAllCrashLogs(): Promise<void> {
try {
await this.ensureCrashLogsDir();
const files = await plugins.smartfile.fs.listFileTree(this.crashLogsDir, '*.log');
for (const file of files) {
const filepath = plugins.path.join(this.crashLogsDir, file);
await plugins.smartfile.fs.remove(filepath);
const entries = await smartfs.directory(this.crashLogsDir).list();
const files = entries.filter(e => e.name.endsWith('.log'));
for (const entry of files) {
const filepath = plugins.path.join(this.crashLogsDir, entry.name);
await smartfs.file(filepath).delete();
}
console.log(`Cleaned up ${files.length} crash logs`);
} catch (error) {
console.error('Failed to cleanup crash logs:', error);
}
}
}
}