Search code examples
javaspringquartz-schedulerschedulingexecutorservice

Log Caller Class/Job Context When Spring Quartz Task Execute


I am writing a java/spring library to include in other projects that are using quartz. I need it to log some information about the task/calling class everytime a job is executed.

For example, if a quartz job looks like this:

@Bean
public JobDetail jobADetail() {
    return JobBuilder.newJob(QuartzTaskA.class)
            .withIdentity("sampleJobA")
            .storeDurably().build();
}

@Bean
public Trigger jobATrigger(JobDetail jobADetail) {
    return TriggerBuilder.newTrigger()
            .forJob(jobADetail)
            .withIdentity("sampleTriggerA")
            .withSchedule(CronScheduleBuilder.cronSchedule("0/10 * * ? * * *"))
            .build();
}

public class QuartzTaskA implements Job {
    @Override
    public void execute(JobExecutionContext jobExecutionContext) {
        log.info("QuartzA - the time is now {}", dateFormat.format(new Date()));
    }
}

I want it to log something like:

Job [QuartzTaskA] with details [sampleJobA] and trigger [sampleTriggerA] is starting
QuartzA - the time is now 12:07:39

I customize the SchedulerFactoryBean with a custom TaskExecutor that does a log before the task.run(). This works and I am able print the additional first line, but I can't figure out how to get the details/context to pass into the log.

@Configuration
public class SchedulerFactoryCustomizer implements SchedulerFactoryBeanCustomizer {
    private static final Logger log = LogManager.getLogger(SchedulerFactoryCustomizer.class);

    @Override
    public void customize(SchedulerFactoryBean schedulerFactoryBean) {
        Executor executor = SchedulerFactoryBean.getConfigTimeTaskExecutor();
        schedulerFactoryBean.setTaskExecutor(new CustomExecutor(executor);
    }

    private static class CustomExecutor implements Executor {
        final Executor executor;

        private CustomExecutor(Executor executor) {
            this.executor = executor;
        }

        @Override
        public void execute(Runnable task) {
            // This line here. How can I get the details/context to pass in?
            //log.info("Job {} with details {} and trigger {} is starting");
            task.run();
        }
    }
}

how can I get the details/context to pass into the log?


Solution

  • You can implement a JobListener/TriggerListener

    public class LoggingTriggerListener implements TriggerListener {
    
        @Override
        public String getName() {
    
            return null;
        }
    
        @Override
        public void triggerFired(final Trigger trigger, final JobExecutionContext context) {
    
        }
    
        @Override
        public boolean vetoJobExecution(final Trigger trigger, final JobExecutionContext context) {
    
            return false;
        }
    
        @Override
        public void triggerMisfired(final Trigger trigger) {
    
        }
    
        @Override
        public void triggerComplete(final Trigger trigger, final JobExecutionContext context, final Trigger.CompletedExecutionInstruction triggerInstructionCode) {
    
        }
    }
    
    

    It injects jobExecutionContext also.