예제로 배우는 핵심 Spring Batch

Ch04. 배치 작업 실행 전, 후 로그 추가를 위한 리스너

webmaster 2023. 6. 7. 00:11
728x90

https://docs.spring.io/spring-batch/docs/current/reference/html/job.html#interceptingJobExecution

 

Configuring and Running a Job

Because the script launching the job must kick off a Java Virtual Machine, there needs to be a class with a main method to act as the primary entry point. Spring Batch provides an implementation that serves this purpose: CommandLineJobRunner. Note that thi

docs.spring.io

  • Listener를 추가하면 Job이 실행하기 전, 후로 동작시키고 싶은 행동을 작성할 수 있다.
  • 로그와 같은 것들을 찍을 수 있다.

JobListenerConfig

/**
 * desc: Job 앞뒤로 로그를 출력
 * run: --spring.batch.job.name=jobListenerJob
 */
@Configuration
@RequiredArgsConstructor
public class JobListenerJobConfig {
  private final JobBuilderFactory jobBuilderFactory;

  private final StepBuilderFactory stepBuilderFactory;

  @Bean
  public Job jobListenerJob(Step jobListenerStep){
    return jobBuilderFactory.get("jobListenerJob")
        .incrementer(new RunIdIncrementer())
        //.listener(new JobLoggerListener())
        .listener(multipleListener())
        .start(jobListenerStep)
        .build();
  }

  private CompositeJobExecutionListener multipleListener(){
    CompositeJobExecutionListener listener = new CompositeJobExecutionListener();
    listener.setListeners(Arrays.asList(new JobLoggerListener()));
    return listener;
  }

  @Bean
  @JobScope
  public Step jobListenerStep(Tasklet jobListenerTasklet) {

    return stepBuilderFactory.get("jobListenerStep")
        .tasklet(jobListenerTasklet)
        .build();
  }

  @Bean
  @StepScope
  public Tasklet jobListenerTasklet() {
    return new Tasklet() {
      @Override
      public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
          throws Exception {
        System.out.println("Job Listener Tasklet");
        return RepeatStatus.FINISHED;
        //throw new Exception("Failed"); //Job 실패를 확인하기 위해 예외를 일부로 발생시켰다.
      }
    };
  }
}

JobLoggerListener

@Slf4j
public class JobLoggerListener implements JobExecutionListener {

  private static String BEFORE_MESSAGE = "{} Job is Running";
  private static String AFTER_MESSAGE = "{} Job is Done. (Status: {})";

  @Override
  public void beforeJob(JobExecution jobExecution) {
    //Job 실행 전
    log.info(BEFORE_MESSAGE, jobExecution.getJobInstance().getJobName());
  }

  @Override
  public void afterJob(JobExecution jobExecution) {
    //Job 실행 후
    log.info(AFTER_MESSAGE, jobExecution.getJobInstance().getJobName(), jobExecution.getStatus());
    if (jobExecution.getStatus() == BatchStatus.FAILED) {
      //email or message 전송 가능
      log.info("Job is Failed");
    }
  }
}
  • JobFactory로 Job 생성 시, listener를 추가할 수 있다.
    • listener() 메서드 안에 listener를 넣어주면 된다.
    • 여기서는 JobLoggerListener 를 넣어주었다 -> Job 실행 앞뒤로 로그를 찍어주는 Listener
    • Validator와 마찬가지로 여러개의 listener를 추가하기 위해서는 CompositeJobExecutionListener에 listener 리스트를 추가하여 넣어주면 된다.
  • JobExecutionListener를 구현하여 Job 실행 이전, 이후 동작을 적어주면 된다.
    • Job 실행 전에는 jobExecution에서 job 인스턴스를 꺼내 이름을 출력했다.
    • Job 실행 후에는 jobExecution에서 job 인스턴스를 꺼내 이름을 출력하고, 만약 배치가 실패하였을 경우(BatchStatus.FAILED) 로그를 출력해 줬다.
      • 이를 확인하기 위해서는 Tasklet에서 강제로 오류를 발생시켜야 한다.
    • 실무라면 배치가 실패하였을경우 이메일을 전달하거나, 알림이 오도록 하였을 것이다.
728x90