course-maker / Course-Maker-BE

0 stars 4 forks source link

[BUG] 예외 발생시 로그가 RootException에서만 로깅되는 문제 #311

Open isaiahIM opened 2 weeks ago

isaiahIM commented 2 weeks ago

버그 개요

원하는 동작

원래는 예외 발생시 각 동작에 맞는 예외가 발생하고, 이를 로깅하고자 함. 그런데, 실제로는 커스텀 예외의 부모클래스인 RootException 로만 로깅되는 상황임. 이를 쌈@뽕하게 해결하려고 함.

코드 상세

기반 지식

RootException 은 다음과 같음

public class RootException extends RuntimeException{
    private ErrorCode errorCode;
    private String logMessage;
    private String clientMessage;
    private Exception e;

    public RootException(ErrorCode errorCode, String logMessage, String clientMessage) {
        super(logMessage);
        this.errorCode = errorCode;
        this.logMessage = logMessage;
        this.clientMessage = clientMessage;
        log.error("exception code: {}, message: {}", errorCode.getCode(), logMessage);
    }
}

보면 에러 코드(errorCode) , 서버에 남길 로그 메시지(logMessage), 프론트한테 보낼 메시지(clientMessage) 로 구성되고, 이를 error 레벨에서 로깅을 하고 있음. 즉, 예외가 발생하면 RootExcpetionerror 레벨에서 로그가 찍힘.

그리고, 우리는 이 RootException을 상속받는 커스텀 예외를 다음과 같이 만들었음.

@Getter
public class LoginRequiredException extends RootException {
    private String message;

    public LoginRequiredException(String message, String logMessage) {
        super(ErrorCode.LOGIN_REQUIRED, logMessage, message);
        this.message = message;
    }
}

이런식으로 RootException을 상속 받으면서 우리가 사용할 표준 예외를 쉽게 만들 수 있음.

문제가 되는 부분

문제는, 이 로그가 RootException 에서만 찍힌다는 거임. 실제 상황을 함 보자구.

public ResponseEntity<ResponseCourseDto> removeRecommend(@PathVariable("id") Long id, @AuthenticationPrincipal LoginedInfo logined) {
        if (logined == null) {
            throw new LoginRequiredException("로그인 후 이용 가능합니다.", "[CourseReview] 추천 취소 실패");
        }
        ...// 서비스 코드
    }

이거는 실제로 코스리뷰 도메인의 코드중 일부임. 분명 코스 리뷰 도메인에서 LoginRequiredException을 호출했는데 로그에 찍히는거는 RootException임. 즉, 내가 코스 리뷰 도메인에서 회원에서 관리하는 예외가 터져도 결국 로그가 찍히는 부분은 RootException 이라는거.

최종적으로는 어느 도메인에서 예외가 발생해도 RootException 에만 예외에 대한 로그가 찍히면서 결국 예외 로깅이 제대로 안됨. 왜냐하면 각 도메인에서 예외를 관리하면서 도메인별로 예외 로그를 모니터링 해야 하는데 전부 RootException이 있는 전체 예외 로그에만 찍히기 때문임.

그래서 각 도메인에서 예외가 발생하면 도메인별로 예외 로그를 찍어야 하는데, 이거는 너무 반복적인 작업이 될 수 있음. 그래서 이거를 쌈@뽕 하게 해결할 방법이 필요함

또 다른 문제

또 다른 문제는 예외를 관리하는 도메인과 예외를 호출하는 도메인이 다를 수 있다는 거임.

예를들어, 우리는 리뷰를 달기 위해서는 로그인을 해야 함. 그런데 만약 어떤 이상한 닝겐이 로그인 안하고 리뷰를 달려고 했다고 가정해보자구.

그러면 리뷰 도메인 에서 "로그인 안했으니 로그인 해주세염~><" 라는 의미의 LoginRequiredException을 발생 시키겠지? 근데 생각해보면 이 예외는 auth 도메인에서 관리함. 그러면, 해당 예외를 관리하는 auth 와 해당 예외를 호출하는 리뷰 에서 모두 로그를 찍어야 함?

만약 이렇게 되면 또 비슷한 로직의 코드들이 엄청 많이 들어갈거임. 다들 알겠지만 하나의 서비스 로직(하나의 API)에는 여러 예외들이 다 들어가고, 이것들을 일일히 다 수작업으로 로그를 찍는다? 쉽지 않음ㅇㅇ 이런 공통 관심사를 처리하는 방법이 필요함.


그래도, 이 내용은 로깅하기 좀 ㅈ같긴 해도 예외 로깅이 아예 안되는것도 아니긴 하니 다들 한번씩 생각해서 담주에 이야기 해보져ㅇㅇ