Spring Batch 장애 알림 (슬랙)

na.ram·2024년 11월 29일

all in auction

목록 보기
14/14
post-thumbnail

이전 글에서 장애에 대비해 Retry와 Backoff 전략을 설계하고 적용해두었습니다.

이번 글에서는 장애가 발생했을 때 개발자가 바로 알고 대처할 수 있도록 알림 보내는 것을 적용해보았습니다.


알림 전송

배치가 실패했을 때, 개발자에게 알림을 보낼 수 있도록 Step이 끝났을 때 실행 상태가 FAILED인 경우에만 슬랙 알림을 전송합니다.

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        if (stepExecution.getStatus() == BatchStatus.FAILED) {
            SlackMessageRequestDto slackMessageRequestDto = SlackMessageRequestDto.of(
                    stepExecution.getJobExecution().getJobInstance().getJobName(),
                    stepExecution.getLastUpdated(),
                    stepExecution.getStepName(),
                    stepExecution.getExitStatus().getExitCode(),
                    stepExecution.getFailureExceptions().get(0).getCause().toString(),
                    "김나람"
            );

            slackUtils.sendMessage(slackMessageRequestDto);

            return ExitStatus.FAILED;
        } else {
            return ExitStatus.COMPLETED;
        }
    }

알림 데이터 변환

SlackUtils 클래스의 sendMessage(slackMessageRequestDto) 메서드를 호출하면 내부에서 DTO를 Payload로 변환해 슬랙 알림을 보내줍니다.

아래의 메서드가 DTO를 Payload로 변환해주는 부분입니다.

    /**
     * create slack payload
     *
     * @param slackMessageRequestDto
     **/
    private Payload createPayload(SlackMessageRequestDto slackMessageRequestDto) {
        return payload(p -> p
                .blocks(List.of(
                                HeaderBlock.builder()
                                        .text(PlainTextObject.builder()
                                                .text("[" + APP_NAME + "][" + SlackMessageType.FAIL.getType() + " :warning:]")
                                                .emoji(true)
                                                .build()
                                        ).build(),
                                SectionBlock.builder()
                                        .fields(
                                                List.of(
                                                        MarkdownTextObject.builder()
                                                                .text("*작업 이름:*\n" + slackMessageRequestDto.getBatchName())
                                                                .build(),
                                                        MarkdownTextObject.builder()
                                                                .text("*실패 시각:*\n" + slackMessageRequestDto.getFailureTime())
                                                                .build(),
                                                        MarkdownTextObject.builder()
                                                                .text("*Step 이름:*\n" + slackMessageRequestDto.getStepName())
                                                                .build(),
                                                        MarkdownTextObject.builder()
                                                                .text("*에러 메시지:*\n" + slackMessageRequestDto.getErrorMessage())
                                                                .build()
                                                )
                                        ).build(),
                                DividerBlock.builder().build(),
                                SectionBlock.builder()
                                        .text(
                                                MarkdownTextObject.builder()
                                                        .text("*조치 안내:*\n로그를 확인하고 재실행하세요. 문제가 지속되면 @" + slackMessageRequestDto.getContactPerson() + " 에게 문의하세요.")
                                                        .build()
                                        ).build()
                        )
                )
        );
    }

장애 발생 시, 알림 예시

만약 ItemProcessor에서 강제로 Exception을 발생시키면 아래와 같은 슬랙 알림을 받게 됩니다.

슬랙 알림으로 장애가 발생한 서비스명, 실패한 Job, 실패한 Step, 실패 시각, 에러 메시지, 오류 로그, 조치 안내와 같은 내용들을 확인할 수 있습니다.

0개의 댓글