Accessing Job information for MDC

2019-08-25 02:47发布

I'm trying to log job info with MDC. I've got a file called CommonBatchConfiguration that handles threading and logging job info. I want to log things like jobName and executionId for any job that may run.

I've got a launcher like this:

@Bean(name = "AsyncMccJobLauncher")
    public JobLauncher simpleJobLauncher(JobRepository jobRepository) {
        SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
        jobLauncher.setJobRepository(jobRepository);
        SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
        taskExecutor.setTaskDecorator(new TaskDecorator() {

            @Override
            public Runnable decorate(Runnable runnable) {
//                MDC.put("execId", jobExecution.getJobId());
//                MDC.put("jobName", "test jobName");

                return new Runnable() {

                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
                        // This adds batch logging info while the job is running
//                        MDC.put("execId", "here");
//                        MDC.put("jobName", "here");
                        runnable.run();
                    }
                };
            }
        });
        jobLauncher.setTaskExecutor(taskExecutor);
        return jobLauncher;
    }

how can I access the job info here? When I try using JobExecution it always comes up null

1条回答
做自己的国王
2楼-- · 2019-08-25 03:34

The job execution should be already created when your decorated runnable is invoked. The question is how to get access to it at this point? I'm not sure if this would be easy unless you are able to introspect a final variable in a method of an anonymous inner class instance (the runnable created by Spring Batch) wrapped in an anonymous inner class instance (your decorator) :-)

I want to log things like jobName and executionId for any job that may run.

You probably don't need to have a task decorator. What you can do is subclass SimpleJobLauncher and override run, something like:

@Bean(name = "AsyncMccJobLauncher")
public JobLauncher simpleJobLauncher(JobRepository jobRepository) {
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher() {
        @Override
        public JobExecution run(Job job, JobParameters jobParameters) throws JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException {
            JobExecution jobExecution = super.run(job, jobParameters);
            // jobExecution is created and accessible here
            //MDC.put("execId", String.valueOf(jobExecution.getJobId()));
            //MDC.put("jobName", jobExecution.getJobInstance().getJobName());
            return jobExecution;
        }
    };
    jobLauncher.setJobRepository(jobRepository);
    SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
    jobLauncher.setTaskExecutor(taskExecutor);
    return jobLauncher;
}
查看更多
登录 后发表回答