All checks were successful
Deploy to Test Environment / deploy-to-test (push) Successful in 12m3s
55 lines
2.2 KiB
TypeScript
55 lines
2.2 KiB
TypeScript
// src/services/systemService.ts
|
|
import { exec as nodeExec, type ExecException } from 'child_process';
|
|
import { promisify } from 'util';
|
|
import { logger } from './logger.server';
|
|
|
|
// Define a type for the exec function for better type safety and testability.
|
|
// It matches the signature of a promisified child_process.exec.
|
|
export type ExecAsync = (
|
|
command: string,
|
|
) => Promise<{ stdout: string; stderr: string }>;
|
|
|
|
export class SystemService {
|
|
private execAsync: ExecAsync;
|
|
|
|
constructor(execAsync: ExecAsync) {
|
|
this.execAsync = execAsync;
|
|
}
|
|
|
|
async getPm2Status(): Promise<{ success: boolean; message: string }> {
|
|
try {
|
|
const { stdout, stderr } = await this.execAsync('pm2 describe flyer-crawler-api');
|
|
|
|
// If the command runs but produces output on stderr, treat it as an error.
|
|
// This handles cases where pm2 might issue warnings but still exit 0.
|
|
if (stderr) {
|
|
throw new Error(`PM2 command produced an error: ${stderr}`);
|
|
}
|
|
|
|
const isOnline = /│\s*status\s*│\s*online\s*│/m.test(stdout);
|
|
const message = isOnline
|
|
? 'Application is online and running under PM2.'
|
|
: 'Application process exists but is not online.';
|
|
return { success: isOnline, message };
|
|
} catch (error: ExecException | any) {
|
|
// If the command fails (non-zero exit code), check if it's because the process doesn't exist.
|
|
// This is a normal "not found" case, not a system error.
|
|
// The error message can be in stdout or stderr depending on the pm2 version.
|
|
const output = error.stdout || error.stderr || '';
|
|
if (output.includes("doesn't exist")) {
|
|
logger.warn('[SystemService] PM2 process "flyer-crawler-api" not found.');
|
|
return {
|
|
success: false,
|
|
message: 'Application process is not running under PM2.',
|
|
};
|
|
}
|
|
// For any other error, log it and re-throw to be handled as a 500.
|
|
logger.error({ error: error.stderr || error.message }, '[SystemService] Error executing pm2 describe:');
|
|
throw error;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Instantiate the service with the real dependency for the application
|
|
const realExecAsync = promisify(nodeExec);
|
|
export const systemService = new SystemService(realExecAsync); |