아무도 궁금해하지 않겠지만, 눈팅으로 하는 웹 어플리케이션 서버 실습의 요구사항을 구현하면서 Logger를 사용하다보니 문득, slf4j의 Logger의 구현체는 어떻게 선택되는가 하는 의문이 들었다. (왜 항상 이런게 궁금한걸까...)
자바에서는 Logging을 slf4j의 인터페이스인 Logger를 이용하여 남기기를 권장한다.
그렇게 하면 좋은 점은 classpath에 Logger구현체가 존재하면 해당 구현체를 이용하여 로깅하고, classpath의 구현체(라이브러리. logback이나 log4j)를 바꾸더라도 프로덕트 코드에는 영향이 없게 된다.
즉, 자바의 추상화 기능을 잘 이용한 사례가 된다고 볼 수 있다.
그럼 한 번 알아보자.
slf4j를 통해 Logger를 사용하는 방법은
slf4j의 LoggerFactory에서 getLogger()를 이용해 Logger 객체를 가져오고 해당 객체를 이용해 로깅을 남기면 된다.
그렇다면 당연히 LoggerFactory.getLogger(Class) 메소드를 확인해보면 구현체를 가져오는 코드가 있을 것이다.
한 번에 많이 타고 왔지만 별 것 없다. 위에서부터 차례대로 천천히 코드를 읽어보면 getLogger() 메서드를 2번 거치고, getILoggerFactory() 메서드까지 온다는 것을 알 수 있다. 그리고 이곳에서 slf4j가 구현체를 선택하는 방법을 확인할 수 있다.
StaticLoggerBinder.getSingleton().getLoggerFactory() 바로 이 부분이 slf4j에서 logback으로 넘어가는 순간이다.
코드를 보면 if문에서 초기화를 하고 switch문으로 넘어간다.
초기화가 성공하면, case SUCCESSFULL_INITIALIZATION로 넘어가는데, StaticLoggerBinder.getSingleton().getLoggerFactory() 이 코드는 slf4j 라이브러리에 없는 코드이다.
저 StaticLoggerBinder클래스는 org.slf4j.impl 패키지에 존재해야하는데, slf4j 라이브러리에는 impl패키지가 존재하지 않는다.
여기서 logback의 코드를 보면 실마리를 찾을 수 있다. 저 코드는 logback이나 log4j와 같은 로깅라이브러리에서 작성해서 제공해야하는 코드인 것이다.
이와 같이 로깅 라이브러리에서 StaticLoggerBinder를 제공해주고, slf4j의 인터페이스에 맞게 구현체들을 제공해주면, Logging을 할 수 있게 된다.
이렇게 되는 것이다.
그러면 이것을 이용해 Logger를 만들어볼 수 있지 않을까?
우선 logback의존성을 제거한다.
그렇게 해주면, classpath에 StaticLoggerBinder를 찾을 수 없기 때문에, 바로 알려준다.
이제 StaticLoggerBinder를 만들어보자.
필요한 getSingleton()과 getLoggerFactory() 메서드를 구현해준다.
다음은 ILoggerFactory 구현체이다.
필요한 getLogger()메서드를 구현한다.
마지막 Logger
Logger 인터페이스를 구현해야해서, 오버라이드 메서드들이 많다. 여기선 편의상 Systme.out의 메서드들을 사용해서 구현하도록 하겠다.
이렇게 info 메서드처럼 나머지 trace, debug, warn, error 메서드들도 구현해준다.
그리고 서버를 실행시키면
Custom Logger가 사용되는 모습을 확인할 수 있다.
이렇게 slf4j가 구현체를 선택하는 방법을 알아보고 이를 이용해 Logger를 만들어 보았다.
당장에 써먹을 곳이 있을까 싶지만, 개발은 즐거워야하지 않을까? 궁금한 점을 풀 수 있어 좋은 시간이었다.
'spring' 카테고리의 다른 글
Tip. 자동으로 getLogger 코드 작성 당하기(feat. IntelliJ File and Code Templates) (0) | 2022.08.30 |
---|---|
눈팅으로 하는 웹 어플리케이션 서버 실습 (0) | 2022.08.23 |
AcceptanceTest 정리(1) - SpringBootTest (0) | 2022.06.24 |