logging을 간편하게 해주는 Slf4j 정리와 사용법
- Overview
- Slf4j 정의
- Facade Pattern
-Slf4j Facade - Slf4j 사용
- 결론
📌 1. Overview
프로젝트에 log4j2 적용 및 Slf4j를 줄곧 사용해왔는데 문득 log4j2와 Slf4j 속에 담겨진 개념이라든가 특징에 대해서 찾아본 적이 없었던 것 같습니다. 그래서 해당 내용에 대해 여러 문서들을 찾아보며 정리한 내용을 기록하고자 합니다.
(log4j 및 log4j2 특징은 다른 게시글에 정리해보겠습니다.)
이번 게시글은 Slf4j에 대한 내용만 담아보려 합니다.
📌 2. Slf4j 정의
SLF4J는 Simple Logging Facade for Java 의 줄임말입니다. 어떤 단어나 개념을 접할 때 저는 늘 풀네임 자체에 주목을 해서 서칭을 해보는 편입니다.
"Simple".. 간단한, "Logging".. 로깅처리, "Facade".. (찾아봐야겠군), "for Java"... 자바에서 사용하는 - 이런 식으로 접근해보니 다른 것보다 Facade가 눈에 띄어 이와 관련해서 찾아봤습니다.
🔖 2-1. Facade Pattern
디자인 패턴에 대해서는 대표적인 케이스에 대해서만 공부했었는데 Facade가 수많은 디자인 패턴 중 하나라는 것을 이번에 처음알았습니다. 위의 링크는 여러 자료들을 봤을 때 제 개인적으로 Facade에 대해서 가장 잘 설명한 게시글이라 생각되어 링크를 걸었습니다.
Facade는 외관이라는 뜻을 가졌는데요. 말 그대로 어떤 복잡한 코드를 내부로 감추고 깔끔한 외관으로 보여줌으로써 사용자가 편리하게 이용할 수 있도록 해주는 디자인 패턴이라고 할 수 있습니다.
위키에서는 "클래스 라이브러리 같은 어떤 소프트웨어의 다른 커다란 코드 부분에 대한 간략화된 인터페이스를 제공하는 객체이다." 라고 정의했는데요. 소프트웨어 측면에서 Facade는 주로 복잡한 라이브러리를 대상으로 간편하게 사용할 수 있는 인터페이스라고 할 수 있습니다.
class CPU { public void freeze() { ... } public void jump(long position) { ... } public void execute() { ... } } class Memory { public void load(long position, byte[] data) { ... } } class HardDrive { public byte[] read(long lba, int size) { ... } } /* Façade */ class Computer { public void startComputer() { CPU cpu = new CPU(); Memory memory = new Memory(); HardDrive hardDrive = new HardDrive(); cpu.freeze(); memory.load(BOOT_ADDRESS, hardDrive.read(BOOT_SECTOR, SECTOR_SIZE)); cpu.jump(BOOT_ADDRESS); cpu.execute(); } } /* Client */ class You { public static void main(String[] args) throws ParseException { Computer facade = /* grab a facade instance */; facade.startComputer(); } }
Wiki에 제시된 예제를 그대로 가져왔습니다.
여기서 CPU, Memory, HardDrive는 3rd-party가 제공하는 라이브러리의 클래스 예시라고 생각하고 접근하면 이해가 쉽습니다. 라이브러리를 가져다 사용하는 입장에서 저희가 3rd-party library에 대해서 수정할 수는 없습니다.
(CPU, Memory, HardDrive 클래스에 대한 내용을 simplify할 수 없다는 의미이기도 합니다.)
cpu를 실행시키기 위해서는 해당 클래스들을 가져다가 복잡한 방법에 의한 코드를 작성해야할 것입니다. 문제는 여기에 있습니다.
만약 해당 라이브러리를 다른 것으로 교체했을 때 어떻게 될까요. 교체된 라이브러리 내부의 클래스들 또한 내용이 바뀌었기 때문에 기존에 cpu 실행 코드들을 전부다 수정해야할 것입니다. 단순히 라이브러리 하나 교체했을 뿐인데 모든 코드를 갈아엎어야하는 상황인 것입니다.
여기서 Computer(Facade) 클래스가 등장하는데 라이브러리에 담겨진 클래스들을 이용한 cpu 실행하는 복잡한 코드들을 하나의 메서드로 담았습니다. 이렇게 되면 Client에서는 Computer 클래스의 startComputer 메서드만 적용해도 해당 라이브러리 내부 코드를 몰라도 cpu를 실행시킬 수 있습니다.
즉 Facade 핵심은 공통된 토픽의 여러 라이브러리에 대해서 통일된 방식으로 사용할 수 있는 인터페이스를 제공해준다는 것입니다.
🔖 2-2. Slf4j Facade

Slf4j는 위에서 언급했듯이 Logging Facade입니다. 즉 Logging 관련된 여러 라이브러리에 대한 통일된 사용방식(통일된 API)을 제공해준다고 할 수 있습니다. 위 그림과 같이 log4j, logback, log4j2 어떤 라이브러리를 사용하든 Slf4j를 통해서 사용하면 기존 소스코드를 수정할 일이 전혀 없다는 것이 강점이라고 할 수 있습니다.
📌 3. Slf4j 사용
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class LoggingService { private static final Logger logger = LoggerFactory.getLogger(LoggingService.class); //... public void log() { logger.info("Logging"); } }
직접 Logger 객체를 생성해서 logging하는 방법이 있습니다.
compileOnly 'org.projectlombok:lombok'
import lombok.extern.slf4j.Slf4j; @Slf4j public class LoggingService { //... public void log() { log.info("Logging"); } }
Lombok을 이용해서 annotation으로 바로 적용한 내용입니다. 저는 주로 이 방법을 사용해서 logging을 하고 있습니다.
📌 4. 결론
주로 사용법보다 Slf4j의 개념과 왜 사용하는지에 대해 정리를 해보았습니다. 원래 log4j > log4j2 사용한 이유에 대해 포스팅을 하려고 했는데 여기서 Slf4j를 사용하다보니 갑작스런 궁금증에 먼저 포스팅을 하게 되었습니다.
제가 찾아본 내용을 이렇게 정리해보니 습관적으로 사용해왔던 Slf4j를 이제는 이유를 알고서 잘 사용하게 될 것 같네요.
틀린 내용이 있을 수 있습니다. 이에 대한 코멘트 언제나 환영입니다!
'Spring' 카테고리의 다른 글
Kotlin, Spring Validation 이용한 입력 데이터 유효성 검증 (2) | 2022.03.03 |
---|---|
[Spring Boot] H2 Database 설정(메모리방식) (0) | 2022.01.10 |
[Spring] 이벤트 처리를 위한 스케줄러 작업 조정(ShedLock 활용) (0) | 2021.09.22 |
MyBatis insert 구문 사용시 mapping 주의 사항 (0) | 2021.09.07 |
[Spring] Interceptor, Resolver 객체 전달을 통한 리팩토링 (0) | 2021.08.02 |
댓글
댓글(Github)
다른 글
-
Kotlin, Spring Validation 이용한 입력 데이터 유효성 검증
Kotlin, Spring Validation 이용한 입력 데이터 유효성 검증
2022.03.03어떤 요청에 대한 입력값에 대해서 코드상으로 하나하나 유효성 검증을 하는 것은 상당히 번거로운 일입니다. 예를들어, 어떤 날짜 입력이 주어졌는데 제대로된 날짜 형식으로 입력했는지 검증하는 코드를 로직상에 추가했다면 비즈니스 로직에 집중해야 될 코드가 오염될 수 있습니다. Spring에서 제공하는 Validation은 이와 같은 입력값에 대한 유효성 검증을 Controller단과 별개로 진행해 간편하게 진행할 수 있도록 기능을 제공하고 있습니다. Spring Validation에 대한 내용을 정리해보고자 합니다. 📌 1. gradle 설정 implementation 'org.springframework.boot:spring-boot-starter-validation' Spring Boot 2.3 버전 부터… -
[Spring Boot] H2 Database 설정(메모리방식)
[Spring Boot] H2 Database 설정(메모리방식)
2022.01.10Spring Boot로 개발할 때 간편하게 이용할 수 있는 h2 database에 대한 설정 내용을 기록하고자 합니다. 그 과정에서 에러 발생 및 처리에 대해서도 기록하고자 합니다. 해당 설정 내용은 github repository에서 확인할 수 있습니다. (Github Repo) GitHub - beaniejoy/test-project-repository: 🧪 Study & Test Repository, which manages and tests various frameworks, libraries 🧪 Study & Test Repository, which manages and tests various frameworks, libraries and modules, that consists of dire… -
[Spring] 이벤트 처리를 위한 스케줄러 작업 조정(ShedLock 활용)
[Spring] 이벤트 처리를 위한 스케줄러 작업 조정(ShedLock 활용)
2021.09.22사용 배경 문제 인식 - 1. outbox 테이블 전체 조회로 인한 문제 - 2. scale-out 상황에서 스케줄러 작업의 중복 실행의 가능성 문제 ShedLock을 위한 프로젝트 설정 ShedLock을 이용한 스케줄링 Lock 설정 - Scale-out 상황에서 스케줄러 중복 실행에 대한 해결 전체 조회 내용을 chunk로 나누어 작업 수행 - 처음에 작은 단위로 조회해보기 - 비동기 방식으로 메일 전송 작업하기 끝나지 않은 고민 - 작업을 꼭 수행해야하는 기능에 대해서는 어떻게 구현할 것인가 📌 1. 사용 배경 프로젝트를 진행하면서 패스워드 변경 요청을 위한 Email 전송 기능이 필요해졌습니다. Email은 spring boot starter mail 라이브러리를 사용하여 테스트용도로 개발을 진행… -
MyBatis insert 구문 사용시 mapping 주의 사항
MyBatis insert 구문 사용시 mapping 주의 사항
2021.09.07📌 MyBatis 사용함에 있어서 살짝의 아쉬움…. (그래도 좋다!) MyBatis를 사용하면서 SQL 구문과 객체 관점을 매핑해준다는 점에서 많은 장점이 있습니다. 지연 로딩 등의 여러 유용한 기능들도 제공해주기도 하고 JPA와 같이 사용하면서 성능 조절을 할 수 있다는 점도 장점이라고 할 수 있겠네요. 하지만 제가 사용하면서 느낀점은 개발할 때 Entity Class와 Mapper xml 설정 내용 둘다 유심히 잘 봐야한다는 점에서 번거로움이 있었습니다. 특히 xml 설정 내용은 철자 하나하나 정확하게 작성해야 하고 java 코드가 아니라 쌩 SQL 구문을 이용해야 한다는 점에서 살짝 불편함을 느꼈습니다. 그 중 제가 자주 에러를 마주했던 부분에 대해 기록하고자 합니다. 📌 기본적인 INSERT 쿼…
댓글을 사용할 수 없습니다.