1

In Spring Batch it would be great to keep track of the execution thread through logging. However, MDC does not seem to work.

MDC.put("process", "batchJob"); logger.info("{}; status={}", getJobName(), batchStatus.name());

Anyone got MDC working in Spring Batch?

nsdiv
  • 912
  • 12
  • 30

1 Answers1

0

I solved it by adding a JobExecutionListener like that:

public class Slf4jBatchJobListener implements JobExecutionListener {

    private static final String DEFAULT_MDC_UUID_TOKEN_KEY = "Slf4jMDCFilter.UUID";
    private final Logger logger = LoggerFactory.getLogger(getClass());

    public void beforeJob(JobExecution jobExecution) {
        String token = UUID.randomUUID().toString().toUpperCase();
        MDC.put(DEFAULT_MDC_UUID_TOKEN_KEY, token);
        logger.info("Job {} with id {} starting...", jobExecution.getJobInstance().getJobName(), jobExecution.getId());
    }

    public void afterJob(JobExecution jobExecution) {
        logger.info("Job {} with id {} ended.", jobExecution.getJobInstance().getJobName(), jobExecution.getId());
        MDC.remove(DEFAULT_MDC_UUID_TOKEN_KEY);
    }
}

Because some jobs are multi-threaded, I had to add also a TaskDecorator in order to copy the DMC from the parent thread to the subthread like this:

public class Slf4JTaskDecorator implements TaskDecorator {

    @Override
    public Runnable decorate(Runnable runnable) {
        Map<String, String> contextMap = MDC.getCopyOfContextMap();
        return () -> {
            try {
                MDC.setContextMap(contextMap);
                runnable.run();
            } finally {
                MDC.clear();
            }
        };
    }
}

Set the TaskDecorator to the TaskExecutor:

@Bean
public TaskExecutor taskExecutor(){
    SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("spring_batch");
    taskExecutor.setConcurrencyLimit(maxThreads);
    taskExecutor.setTaskDecorator(new Slf4JTaskDecorator());
    return taskExecutor;
}

And lastly, update the logging pattern in properties:

logging:
  pattern:
    level: "%5p %X{Slf4jMDCFilter.UUID}"
Chris Sekas
  • 69
  • 1
  • 4