Throwable.printStackTrace()를 사용하면 안되는 이유

log.yunsik·2022년 10월 27일
0

사다리 게임 미션 진행 중 입력에 대한 예외처리를 해주기 위해 다음과 같이 코드를 작성했다.


	private People inputPeople() {
        try {
            return ladderService.people(InputView.personNameInput());
        } catch (Exception e) {
            e.printStackTrace();
            OutputView.inputPeopleException();
        }
        return inputPeople();
    }

리뷰어님께서 "printStackTrace() 는 사용하지 않는 것이 권장됩니다. 왜 그럴까요?" 리뷰를 남겨주셔서 이유를 찾아보았다.

Throwable.printStackTrace() 내부 구현

우선 Throwable.printStackTrace()의 내부 구현을 살펴보자

System.errPrintStream으로 사용하고 있다.

실제 출력 부분의 코드에서는 System.err의 출력 스트림에 ThrowableStackTraceElement를 가져와 출력하는 것을 볼 수 있다.


getOurStackTrace()의 경우 StackTraceElement.of를 통해 StackElement를 가져오는데


of메서드 내부에서 computeFormat()를 호출하는데 이 코드 내부를 보면


Reflection을 사용하는 것을 볼 수있다.

printStackTrace()를 사용하면 안되는 이유

내부 동작을 살펴봤으니 본격적으로 Throwable.printStackTrace()를 사용하면 안되는 이유를 알아보자

1. 오류 출력이 실제로 어디로 가는지 알 수 없다.
System.errSystem.setErr()를 통해 변경될 수 있으므로 이 오류가 어디에 출력되는 것인지 알 수 없다.
2. 많은 오버헤드가 발생한다.
내부에서 동기화를 위한 synchronized, Reflection 호출 등 많은 오버헤드가 발생한다.
3. 보존 정책을 설정할 수 없다.
보존 정책을 설정할 수 없으므로 기본적으로 Log가 Application 생명주기와 함께한다.
4. 보안성이 떨어진다
StackTrace를 통해 메서드 내부 동작 구조가 노출되기 때문에 보안성이 떨어지므로 외부에 노출해선 안된다.

결론

logback, slf4j, java.util.logging, log4j 등 로그가 기록되는 위치와 보존 정책을 설정할 수 있으므로 로깅 프레임워크를 사용하자

참고 문서

https://stackoverflow.com/questions/7469316/why-is-exception-printstacktrace-considered-bad-practice

0개의 댓글