Files
tspm/ts/daemon/logpersistence.ts

118 lines
3.3 KiB
TypeScript

import * as plugins from '../plugins.js';
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 persistent log storage for processes
*/
export class LogPersistence {
private logsDir: string;
constructor() {
this.logsDir = plugins.path.join(paths.tspmDir, 'logs');
}
/**
* Get the log file path for a process
*/
private getLogFilePath(processId: ProcessId): string {
return plugins.path.join(this.logsDir, `process-${processId}.json`);
}
/**
* Ensure the logs directory exists
*/
private async ensureLogsDir(): Promise<void> {
await smartfs.directory(this.logsDir).create();
}
/**
* Save logs to disk
*/
public async saveLogs(processId: ProcessId, logs: IProcessLog[]): Promise<void> {
await this.ensureLogsDir();
const filePath = this.getLogFilePath(processId);
// Write logs as JSON
await smartfs.file(filePath).encoding('utf8').write(JSON.stringify(logs, null, 2));
}
/**
* Load logs from disk
*/
public async loadLogs(processId: ProcessId): Promise<IProcessLog[]> {
const filePath = this.getLogFilePath(processId);
try {
const exists = await smartfs.file(filePath).exists();
if (!exists) {
return [];
}
const content = await smartfs.file(filePath).encoding('utf8').read() as string;
const logs = JSON.parse(content) as IProcessLog[];
// Convert date strings back to Date objects
return logs.map(log => ({
...log,
timestamp: new Date(log.timestamp)
}));
} catch (error) {
console.error(`Failed to load logs for process ${processId}:`, error);
return [];
}
}
/**
* Delete logs from disk after loading
*/
public async deleteLogs(processId: ProcessId): Promise<void> {
const filePath = this.getLogFilePath(processId);
try {
const exists = await smartfs.file(filePath).exists();
if (exists) {
await smartfs.file(filePath).delete();
}
} catch (error) {
console.error(`Failed to delete logs for process ${processId}:`, error);
}
}
/**
* Calculate approximate memory size of logs in bytes
*/
public static calculateLogMemorySize(logs: IProcessLog[]): number {
// Estimate based on JSON string size
// This is an approximation but good enough for our purposes
return JSON.stringify(logs).length;
}
/**
* Clean up old log files (for maintenance)
*/
public async cleanupOldLogs(): Promise<void> {
try {
await this.ensureLogsDir();
const entries = await smartfs.directory(this.logsDir).list();
const files = entries.filter(e => e.name.endsWith('.json'));
for (const entry of files) {
const filePath = plugins.path.join(this.logsDir, entry.name);
const stats = await smartfs.file(filePath).stat();
// Delete files older than 7 days
const ageInDays = (Date.now() - stats.mtime.getTime()) / (1000 * 60 * 60 * 24);
if (ageInDays > 7) {
await smartfs.file(filePath).delete();
}
}
} catch (error) {
console.error('Failed to cleanup old logs:', error);
}
}
}