const { Worker } = require('worker_threads'); const fs = require('fs'); const path = require('path'); let totalSuccess = 0; let totalError = 0; const startTime = Date.now(); const logsDir = path.join(__dirname, 'logs'); if (!fs.existsSync(logsDir)) { fs.mkdirSync(logsDir); } const logFilePath = path.join(logsDir, `app-${new Date().toISOString().replace(/:/g, '-')}.log`); const logger = () => { const timestamp = new Date().toISOString(); return { info: (message) => fs.appendFileSync(logFilePath, `[${timestamp}] INFO:\t${message}\n`), error: (message) => fs.appendFileSync(logFilePath, `[${timestamp}] ERROR:\t${message}\n`), warn: (message) => fs.appendFileSync(logFilePath, `[${timestamp}] WARN:\t${message}\n`) } }; module.exports = { logger, workerFactory: ( workerData, onMessage = ({ id, payload }) => console.log("onMessage", id, payload), onError = ({ id, error }) => console.error("onError", id, error), onExit = ({ id, status }) => console.log("onExit", id, status)) => { return new Worker('./worker.js', { workerData }) .on('message', (payload) => onMessage({ id: workerData.id, payload })) .on('error', (error) => onError({ id: workerData.id, error })) .on('exit', (status) => onExit({ id: workerData.id, status })); }, onMessage: ({ id, payload }) => { switch (payload.status) { case 'starting': console.log(`${payload.id}\t⌛ Starting with url: ${payload.url}`); logger().info(`Worker ${payload.id} starting with url: ${payload.url}`); return; case 'success': totalSuccess++; break; case 'recoverable-error': totalError++; // Log recoverable errors to file logger().warn(`Worker ${id}: ${payload.error}`); break; } const totalRequests = totalError + totalSuccess; const timeDelta = Date.now() - startTime; const rps = totalRequests / (timeDelta / 1000); const successRate = (totalSuccess / totalRequests) * 100; process.stdout.write(`\r${id}\t🕒 Started: ${new Date(startTime).toISOString()} 📄 Requests: ${totalSuccess}/${totalRequests}. 📊 Success rate: ${successRate.toFixed(2)}%. ⚡ Req/s: ${rps.toFixed(2)}. ⏲️ Req/h: ${(rps * 3600).toFixed(2)}`); }, onError: ({ id, error }) => { console.error(`\r${id}\t❌ ${error}. Total Successful Requests: ${totalSuccess}`); logger().error(`Worker ${id} critical error: ${error}`); }, onExit: ({ id, status }) => { if (status !== 0) { console.error(`${id}\t❌ Exit status: ${status}`); logger().error(`Worker ${id} exited with status: ${status}`); return; } console.log(`${id}\t✅ Gracefully terminated.`); logger().info(`Worker ${id} gracefully terminated`); } };