[grade=A] P1-3: replace 36 console.* calls in backup-manager.js with structured logger

Replaced all 36 console.log/warn/error calls in src/utilities/backup-manager.js
with log.info/log.warn/log.error from src/utils/logging. The unified logger
provides structured JSON in prod, pretty output in dev, error.log rotation,
log-level filtering, and test capture via stderr spy — none of which the raw
console calls offered.

Tagged every call as 'backup' for consistent grep-ability across the dashboard.
Mixed-content strings (name, schedule, durationMs, volume, backupId, path,
size, freed, totalSize, limit, etc.) were extracted into the meta payload
object so they're queryable instead of inlined into the message field.

1539/1539 Jest tests pass. ESLint clean for the file (10 pre-existing
warnings unchanged, zero new).
This commit is contained in:
Hermes
2026-08-10 20:10:08 -07:00
parent 0bf4406253
commit c55abdab87
+37 -36
View File
@@ -9,6 +9,7 @@ const { execSync } = require('child_process');
const crypto = require('crypto');
const EventEmitter = require('events');
const platformPaths = require('../../platform-paths');
const { log } = require('../utils/logging');
// Format bytes to human readable string
function formatBytes(bytes) {
@@ -38,7 +39,7 @@ class BackupManager extends EventEmitter {
start() {
if (this.running) return;
console.log('[BackupManager] Starting backup scheduler');
log.info('backup', 'Starting backup scheduler');
this.running = true;
// Schedule all configured backups
@@ -55,7 +56,7 @@ class BackupManager extends EventEmitter {
stop() {
if (!this.running) return;
console.log('[BackupManager] Stopping backup scheduler');
log.info('backup', 'Stopping backup scheduler');
this.running = false;
// Clear all scheduled jobs
@@ -91,7 +92,7 @@ class BackupManager extends EventEmitter {
if (!isNaN(minutes) && minutes > 0) {
intervalMs = minutes * 60 * 1000;
} else {
console.error(`[BackupManager] Invalid schedule for ${name}: ${backup.schedule}`);
log.warn('backup', 'Invalid schedule', { name, schedule: backup.schedule });
return;
}
}
@@ -100,17 +101,17 @@ class BackupManager extends EventEmitter {
// Schedule the job
const job = setInterval(() => {
this.executeBackup(name, backup).catch(error => {
console.error(`[BackupManager] Scheduled backup ${name} failed:`, error.message);
log.error('backup', error, { name });
});
}, intervalMs);
this.scheduledJobs.set(name, job);
console.log(`[BackupManager] Scheduled backup '${name}' every ${backup.schedule}`);
log.info('backup', 'Scheduled backup', { name, schedule: backup.schedule });
// Run immediately if configured
if (backup.runImmediately) {
this.executeBackup(name, backup).catch(error => {
console.error(`[BackupManager] Initial backup ${name} failed:`, error.message);
log.error('backup', error, { name, phase: 'initial' });
});
}
}
@@ -122,7 +123,7 @@ class BackupManager extends EventEmitter {
const startTime = Date.now();
const backupId = `${name}-${Date.now()}`;
console.log(`[BackupManager] Starting backup: ${name}`);
log.info('backup', 'Starting backup', { name });
this.emit('backup-start', { name, backupId, timestamp: new Date().toISOString() });
@@ -151,7 +152,7 @@ class BackupManager extends EventEmitter {
const location = await this.saveToDestination(finalData, dest, backupId);
savedLocations.push(location);
} catch (error) {
console.error(`[BackupManager] Failed to save to ${dest.type}:`, error.message);
log.error('backup', error, { destType: dest.type });
}
}
@@ -192,7 +193,7 @@ class BackupManager extends EventEmitter {
}
this.emit('backup-complete', historyEntry);
console.log(`[BackupManager] Backup ${name} completed in ${duration}ms`);
log.info('backup', 'Backup completed', { name, durationMs: duration });
return historyEntry;
} catch (error) {
@@ -263,7 +264,7 @@ class BackupManager extends EventEmitter {
return JSON.parse(fs.readFileSync(servicesFile, 'utf8'));
}
} catch (error) {
console.error('[BackupManager] Error backing up services:', error.message);
log.error('backup', error, { source: 'services' });
}
return null;
}
@@ -278,7 +279,7 @@ class BackupManager extends EventEmitter {
return JSON.parse(fs.readFileSync(configFile, 'utf8'));
}
} catch (error) {
console.error('[BackupManager] Error backing up config:', error.message);
log.error('backup', error, { source: 'config' });
}
return null;
}
@@ -291,7 +292,7 @@ class BackupManager extends EventEmitter {
const credentialManager = require('../managers/credential-manager');
return credentialManager.exportBackup();
} catch (error) {
console.error('[BackupManager] Error backing up credentials:', error.message);
log.error('backup', error, { source: 'credentials' });
}
return null;
}
@@ -304,7 +305,7 @@ class BackupManager extends EventEmitter {
const resourceMonitor = require('../managers/resource-monitor');
return resourceMonitor.exportStats();
} catch (error) {
console.error('[BackupManager] Error backing up stats:', error.message);
log.error('backup', error, { source: 'stats' });
}
return null;
}
@@ -374,7 +375,7 @@ class BackupManager extends EventEmitter {
});
}
} catch (volumeError) {
console.error(`[BackupManager] Error backing up volume ${volume.Name}:`, volumeError.message);
log.error('backup', volumeError, { volume: volume.Name });
backupResults.push({
name: volume.Name,
status: 'failed',
@@ -390,7 +391,7 @@ class BackupManager extends EventEmitter {
volumes: backupResults
};
} catch (error) {
console.error('[BackupManager] Error backing up volumes:', error.message);
log.error('backup', error, { source: 'volumes' });
return null;
}
}
@@ -461,9 +462,9 @@ class BackupManager extends EventEmitter {
timestamp: new Date().toISOString()
});
console.log(`[BackupManager] Volume ${volumeName} restored successfully`);
log.info('backup', 'Volume restored', { volume: volumeName });
} catch (restoreError) {
console.error(`[BackupManager] Error restoring volume ${volBackup.name}:`, restoreError.message);
log.error('backup', restoreError, { volume: volBackup.name });
restoreResults.push({
name: volBackup.name,
status: 'failed',
@@ -849,7 +850,7 @@ class BackupManager extends EventEmitter {
throw new Error('Backup verification failed: checksum mismatch');
}
console.log('[BackupManager] Backup verified successfully');
log.info('backup', 'Backup verified successfully');
return true;
}
@@ -860,7 +861,7 @@ class BackupManager extends EventEmitter {
* Restore from backup
*/
async restoreBackup(backupId, options = {}) {
console.log(`[BackupManager] Starting restore from backup: ${backupId}`);
log.info('backup', 'Starting restore', { backupId });
this.emit('restore-start', { backupId, timestamp: new Date().toISOString() });
@@ -922,7 +923,7 @@ class BackupManager extends EventEmitter {
timestamp: new Date().toISOString()
});
console.log('[BackupManager] Restore completed successfully');
log.info('backup', 'Restore completed successfully');
return { success: true, restored };
} catch (error) {
this.emit('restore-failed', {
@@ -940,7 +941,7 @@ class BackupManager extends EventEmitter {
restoreServices(services) {
const servicesFile = platformPaths.servicesFile;
fs.writeFileSync(servicesFile, JSON.stringify(services, null, 2));
console.log('[BackupManager] Services restored');
log.info('backup', 'Services restored');
}
/**
@@ -949,7 +950,7 @@ class BackupManager extends EventEmitter {
restoreConfig(config) {
const configFile = platformPaths.configFile;
fs.writeFileSync(configFile, JSON.stringify(config, null, 2));
console.log('[BackupManager] Config restored');
log.info('backup', 'Config restored');
}
/**
@@ -958,7 +959,7 @@ class BackupManager extends EventEmitter {
restoreCredentials(credentials) {
const credentialManager = require('../managers/credential-manager');
credentialManager.importBackup(credentials);
console.log('[BackupManager] Credentials restored');
log.info('backup', 'Credentials restored');
}
/**
@@ -967,7 +968,7 @@ class BackupManager extends EventEmitter {
restoreStats(stats) {
const resourceMonitor = require('../managers/resource-monitor');
resourceMonitor.importStats(stats);
console.log('[BackupManager] Stats restored');
log.info('backup', 'Stats restored');
}
/**
@@ -975,7 +976,7 @@ class BackupManager extends EventEmitter {
*/
async enforceStorageLimit(name, maxBytes) {
const maxStr = formatBytes(maxBytes);
console.log("[BackupManager] Enforcing storage limit: " + maxStr + " for \"" + name + "\"");
log.info('backup', 'Enforcing storage limit', { name, limit: maxStr });
const backups = this.history
.filter(b => b.name === name && b.status === 'success')
@@ -994,10 +995,10 @@ class BackupManager extends EventEmitter {
}
}
console.log("[BackupManager] Current total size: " + formatBytes(totalSize) + ", limit: " + maxStr);
log.info('backup', 'Current storage usage', { totalSize: formatBytes(totalSize), limit: maxStr });
if (totalSize <= maxBytes) {
console.log("[BackupManager] Storage limit OK (" + formatBytes(totalSize) + " <= " + maxStr + ")");
log.info('backup', 'Storage limit OK', { totalSize: formatBytes(totalSize), limit: maxStr });
return;
}
@@ -1013,10 +1014,10 @@ class BackupManager extends EventEmitter {
const sz = backup.size || 0;
totalSize -= sz;
freed += sz;
console.log("[BackupManager] Deleted " + formatBytes(sz) + ": " + path);
log.info('backup', 'Deleted old backup file', { size: formatBytes(sz), path });
}
} catch (error) {
console.error("[BackupManager] Error deleting " + path + ": " + error.message);
log.error('backup', error, { path });
}
}
@@ -1024,7 +1025,7 @@ class BackupManager extends EventEmitter {
}
this.saveHistory();
console.log("[BackupManager] Storage limit enforced. Freed " + formatBytes(freed) + ", now " + formatBytes(totalSize));
log.info('backup', 'Storage limit enforced', { freed: formatBytes(freed), totalSize: formatBytes(totalSize) });
}
/**
@@ -1051,9 +1052,9 @@ class BackupManager extends EventEmitter {
// Remove from history
this.history = this.history.filter(b => b.id !== backup.id);
console.log(`[BackupManager] Deleted old backup: ${backup.id}`);
log.info('backup', 'Deleted old backup', { backupId: backup.id });
} catch (error) {
console.error(`[BackupManager] Error deleting backup ${backup.id}:`, error.message);
log.error('backup', error, { backupId: backup.id });
}
}
@@ -1109,7 +1110,7 @@ class BackupManager extends EventEmitter {
return JSON.parse(fs.readFileSync(BACKUP_CONFIG_FILE, 'utf8'));
}
} catch (error) {
console.error('[BackupManager] Error loading config:', error.message);
log.error('backup', error, { operation: 'loadConfig' });
}
return {
@@ -1125,7 +1126,7 @@ class BackupManager extends EventEmitter {
try {
fs.writeFileSync(BACKUP_CONFIG_FILE, JSON.stringify(this.config, null, 2));
} catch (error) {
console.error('[BackupManager] Error saving config:', error.message);
log.error('backup', error, { operation: 'saveConfig' });
}
}
@@ -1138,7 +1139,7 @@ class BackupManager extends EventEmitter {
return JSON.parse(fs.readFileSync(BACKUP_HISTORY_FILE, 'utf8'));
}
} catch (error) {
console.error('[BackupManager] Error loading history:', error.message);
log.error('backup', error, { operation: 'loadHistory' });
}
return [];
}
@@ -1150,7 +1151,7 @@ class BackupManager extends EventEmitter {
try {
fs.writeFileSync(BACKUP_HISTORY_FILE, JSON.stringify(this.history, null, 2));
} catch (error) {
console.error('[BackupManager] Error saving history:', error.message);
log.error('backup', error, { operation: 'saveHistory' });
}
}
}