programing

Spring Boot 응용 프로그램에서 커스텀 예외 스택트레이스 로깅 방지

telecom 2023. 3. 31. 21:34
반응형

Spring Boot 응용 프로그램에서 커스텀 예외 스택트레이스 로깅 방지

Spring Boot(MVC; 스프링 부트)에서는 커스텀 예외를 기록하고 로그 파일에 스택트레이스가 표시되지 않게 하는 방법이 있나요?그러나 다른 예외에 대해서는 스택트레이스를 참조해 주세요.

긴 설명:

간단한 휴식 서비스를 만들기 위해 스프링 부츠를 사용하고 있습니다.커스텀 예외는 기본적으로 로그에 스택트레이스가 없고 JSON 응답은 기본 예외 상세(상태, 오류, 메시지)로 작성됩니다.

문제는 로그 엔트리가 전혀 생성되지 않기 때문에 수동으로 수행해야 한다는 것입니다.

커스텀 예외

@ResponseStatus(value = HttpStatus.CONFLICT)
public class DuplicateFoundException extends RuntimeException {
    public DuplicateFoundException(String message) {
        super(message);
    }
}

서비스 메서드에 예외 투입(@RestController)

if (!voteDao.findByItemAndUser(item, voteDto.getUserId()).isEmpty()) {
    log.warn("... already voted ...");   //TODO: don't do this for every throw
    throw new DuplicateFoundException("... already voted ...");
}

예외가 더 많으면 던질 때마다 로그 문구를 넣게 되는데, 이는 잘못된 접근법이라고 생각합니다.서비스 메서드에서 모든 로그 문을 삭제하고@ControllerAdvice모든 커스텀 예외를 로그에 기록하고 재투입하면 이전과 같은 멋진 JSON을 얻을 수 있습니다.

@ControllerAdvice
public class RestExceptionHandler {
    private static final Logger log = Logger.getLogger(RestExceptionHandler.class);

    @ExceptionHandler
    public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e) throws Exception {
        if (AnnotationUtils.findAnnotation(e.getClass(), ResponseStatus.class) != null) {
            log.warn(e.getMessage());
        } else {
            log.error("...");
        }
        throw e;
    }
}

문제는 로그 엔트리뿐만 아니라 스택트레이스에서도 커스텀 예외에 대한 정보가 표시되며 이를 방지하는 방법을 찾을 수 없다는 것입니다.다시 던져서 문제가 생긴 것 같아요.가능한 해결책은 예외용 커스텀클래스를 만드는 것입니다.대신 반환하겠습니다만, 예외 마샬링은 정상적으로 동작하고 있는 것 같기 때문에, 이 생각은 마음에 들지 않습니다.

힌트 있나요?

Spring Boot 2+ 를 사용하고 있는 경우는, 다음의 행을 애플리케이션에 추가합니다.properties:

server.error.error-stacktrace=never

https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/autoconfigure/web/ErrorProperties.IncludeStacktrace.html

Spring Boot DevTools에 주의하십시오.

불구하고NEVER디폴트가 되다server.error.include-stacktraceSpring Boot DevTools를 포함하면 그 위에ALWAYS.

상세한 것에 대하여는, Spring Boot 2.1.0+의 일부가 된 이 커밋을 참조해 주세요.

스택 트레이스가 필요 없는 경우 오버라이드하여 스택트레이스를 억제할 수 있습니다.fillInStackTrace예외 클래스에서 사용합니다.

public class DuplicateFoundException extends RuntimeException {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

호출할 때e.printStackTrace()스택 트레이스는 인쇄되지 않습니다.

이 블로그 투고도 참조해 주세요.

오버로드된 슈퍼 컨스트럭터를 호출하여 응답 스택트레이스가 표시되지 않도록 합니다.

public class ProductCustomException extends Exception{
    
    private static final long serialVersionUID = -291211739734090347L;

    public ProductCustomException(String message) {
        super(message,null,false,false);
    }

}

예외 클래스의 슈퍼 로드된 생성자

 protected Exception(String message, Throwable cause,
                        boolean enableSuppression,
                        boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
    
}

해결책은 예외처리를 스프링부트에 맡기고 커스텀 예외가 기록되지 않고 기본적으로 다른 예외가 기록되도록 하는 이었습니다.나머지 컨트롤러에서 @ControllerAdvice와 logging 문을 삭제하고 logging 문을 커스텀 예외 컨스트럭터에 추가했습니다.

public DuplicateFoundException(String message) {
    super(message);
    LOGGER.warn(message);
}

이것이 최선의 방법인지는 잘 모르겠습니다만, 커스텀 예외 로깅이 1개소 밖에 없기 때문에 예외마다 log 문을 반복하거나 해당 스택트레이스 또는 로그 내의 기타 오류 메시지를 표시할 필요가 없습니다.

언급URL : https://stackoverflow.com/questions/31250598/prevent-stack-trace-logging-for-custom-exception-in-spring-boot-application

반응형