fix(cli): Refactor logs command to use child_process spawn for real-time log tailing

This commit is contained in:
Philipp Kunz 2025-03-25 09:20:55 +00:00
parent 9bfb948e5c
commit 8431ef91a8
4 changed files with 41 additions and 3 deletions

View File

@ -1,5 +1,12 @@
# Changelog
## 2025-03-25 - 1.8.2 - fix(cli)
Refactor logs command to use child_process spawn for real-time log tailing
- Replaced execSync call with spawn to properly follow logs
- Forward SIGINT to the spawned process for graceful termination
- Await the child process exit to ensure clean shutdown of the CLI log command
## 2025-03-25 - 1.8.1 - fix(systemd)
Update ExecStart in systemd service template to use /opt/nupst/bin/nupst for daemon startup

View File

@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@serve.zone/nupst',
version: '1.8.1',
version: '1.8.2',
description: 'Node.js UPS Shutdown Tool for SNMP-enabled UPS devices'
}

View File

@ -131,8 +131,24 @@ export class NupstCli {
*/
private async logs(): Promise<void> {
try {
const logs = execSync('journalctl -u nupst.service -n 50 -f').toString();
console.log(logs);
// Use exec with spawn to properly follow logs in real-time
const { spawn } = await import('child_process');
console.log('Tailing nupst service logs (Ctrl+C to exit)...\n');
const journalctl = spawn('journalctl', ['-u', 'nupst.service', '-n', '50', '-f'], {
stdio: ['ignore', 'inherit', 'inherit']
});
// Forward signals to child process
process.on('SIGINT', () => {
journalctl.kill('SIGINT');
process.exit(0);
});
// Wait for process to exit
await new Promise<void>((resolve) => {
journalctl.on('exit', () => resolve());
});
} catch (error) {
console.error('Failed to retrieve logs:', error);
process.exit(1);

View File

@ -193,11 +193,15 @@ export class NupstDaemon {
console.log('Starting UPS monitoring...');
let lastStatus: 'online' | 'onBattery' | 'unknown' = 'unknown';
let lastLogTime = 0; // Track when we last logged status
const LOG_INTERVAL = 5 * 60 * 1000; // Log at least every 5 minutes (300000ms)
// Monitor continuously
while (this.isRunning) {
try {
const status = await this.snmp.getUpsStatus(this.config.snmp);
const currentTime = Date.now();
const shouldLogStatus = (currentTime - lastLogTime) >= LOG_INTERVAL;
// Log status changes
if (status.powerStatus !== lastStatus) {
@ -205,6 +209,17 @@ export class NupstDaemon {
console.log(`│ Power status changed: ${lastStatus}${status.powerStatus}`);
console.log('└──────────────────────────────────────────┘');
lastStatus = status.powerStatus;
lastLogTime = currentTime; // Reset log timer when status changes
}
// Log status periodically (at least every 5 minutes)
else if (shouldLogStatus) {
const timestamp = new Date().toISOString();
console.log('┌──────────────────────────────────────────┐');
console.log(`│ [${timestamp}] Periodic Status Update`);
console.log(`│ Power Status: ${status.powerStatus}`);
console.log(`│ Battery: ${status.batteryCapacity}% | Runtime: ${status.batteryRuntime} min`);
console.log('└──────────────────────────────────────────┘');
lastLogTime = currentTime;
}
// Handle battery power status