import { Worker, Job } from 'bullmq'; import logger from './logging'; const jobStartTimes = new Map(); export function attachWorkerEvents(worker: Worker) { worker.on('active', (job: Job) => { const jobId = job.id?.toString() || 'unknown'; jobStartTimes.set(jobId, Date.now()); logger.info({ event: 'job_active', jobId, name: job.name, data: job.data }); }); worker.on('completed', (job: Job) => { const jobId = job.id?.toString() || 'unknown'; const start = jobStartTimes.get(jobId) || Date.now(); const durationMs = Date.now() - start; jobStartTimes.delete(jobId); logger.info({ event: 'job_complete', jobId, durationMs, timestamp: new Date().toISOString() }); }); worker.on('failed', (job: Job | undefined, err: Error | undefined) => { const jobId = job?.id; const start = jobId ? jobStartTimes.get(jobId) : undefined; const durationMs = start ? Date.now() - start : undefined; if (jobId) jobStartTimes.delete(jobId); logger.error({ event: 'job_failed', jobId, error: err?.message, stack: err?.stack, durationMs }); }); worker.on('progress', (job: Job, progress) => { logger.info({ event: 'job_progress', jobId: job.id, progress }); }); worker.on('error', (err: Error) => { logger.error({ event: 'worker_error', error: err?.message, stack: err?.stack }); }); } export default attachWorkerEvents;