[Logger]

2025. 4. 4. 17:37·Web

SLF4J  &  Log4j

SLF4J는 "로깅 인터페이스(Facade)"고,
Log4j는 "로깅 구현체"임

역할 차이

구분                                      SLF4J                                                                                     Log4j

뭐임? 로깅의 껍데기 (추상화된 인터페이스) 실제 로그 찍는 놈 (구현체)
직접 로그 찍음? ❌ ✅
유연함? ✅ (뒤에 구현체 갈아끼기 쉬움) ❌ (자기 방식만 고집함)
목적 다양한 로깅 시스템에 대응 로깅 기능 자체 제공
종속성 구조 구현체가 필요함 (Log4j, Logback 등) 단독 사용 가능

비유하면?

SLF4J = 콘센트 인터페이스
Log4j, Logback = 실제 플러그를 꽂는 전자제품

내가 SLF4J를 쓰면, 뒤에 어떤 제품(Log4j든 Logback이든)을 꽂아도 작동함
그래서 "코드는 SLF4J로 짜고, 구현체는 갈아끼워라" 이런 말 나오는 거임


예전에는 Log4j만 썼음

Spring 2.x 시절엔 대부분 그냥 Log4j 직접 씀
근데 단점이 많았음:

  • 다른 로깅 시스템과 호환성 별로
  • 코드가 Log4j에 종속됨
  • 성능 이슈 있음

그래서 SLF4J가 나옴
“야, 공통 껍데기 하나 만들어서, 걍 그거 쓰게 하자”
그래서 Log4j도, Logback도, JUL도 다 SLF4J로 연결 가능해짐


SLF4J + Log4j 조합도 가능

"Logger는 SLF4J로 만들고, 실제 로그는 Log4j로 찍어라"
이렇게 설정할 수도 있음

Maven 예시

<!-- SLF4J API -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.36</version>
</dependency>

<!-- Log4j를 SLF4J용 구현체로 쓰는 브릿지 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.36</version>
</dependency>

<!-- 실제 Log4j 엔진 -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

이러면 코드에서 SLF4J만 써도, 뒤에서 Log4j가 로그 찍어줌

근데 Log4j는 지금은 좀 쓰지 마라

Log4j는 2021년에 심각한 보안 이슈 (Log4Shell) 터졌음

  • 악성 요청 하나로 서버 장악 가능
  • 이걸로 전세계 수많은 시스템 털렸음

그래서 지금은 대부분 Logback 쓰거나
Log4j 2.x (보안패치 된 버전) 씀

결론 요약

항목                                            SLF4J                                                       Log4j

뭐냐 로깅 인터페이스 로깅 구현체
직접 로그 찍냐 ❌ ✅
코드 종속성 낮음 (유연함) 높음 (바꾸기 힘듦)
실무 추천 SLF4J + Logback Log4j는 버전 2 이상만 고려

 

실무에서는 거의 대부분 이렇게 씀:

SLF4J + Logback 조합

 


SLF4J의 Logger & LoggerFactory

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

여기서 이 둘 다 SLF4J 패키지임
즉, Simple Logging Facade for Java라는 라이브러리에서 제공하는 클래스


구조 요약

클래스 역할

Logger 로그 찍는 객체 (인터페이스)
LoggerFactory Logger 객체 만들어주는 공장 클래스 (팩토리 패턴)

SLF4J?

SLF4J는 "로깅의 껍데기"임 (Facade)

  • 직접 로그를 찍는 게 아니라, 뒤에 어떤 로깅 구현체가 붙냐에 따라 실행됨
  • 예시로 붙일 수 있는 놈들:
    • Logback (SLF4J 공식 구현체)
    • Log4j
    • java.util.logging (JUL)
    • commons-logging 등등

즉,

  • 코드에서 SLF4J의 Logger만 쓰면 됨
  • 뒤에 붙는 실제 구현체는 네가 설정해서 고를 수 있음
  • 이게 SLF4J의 핵심

의존성은 어디서 ?

Maven이나 Gradle에서 이거 안 넣으면 못 씀

Maven 기준 (pom.xml)

<!-- SLF4J API (껍데기) -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.36</version>
</dependency>

<!-- 구현체 (Logback 사용 예시) -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.11</version>
</dependency>

이렇게 둘 다 넣어야 동작함

  • slf4j-api: Logger 인터페이스만 존재
  • logback-classic: 실제 로그를 찍는 구현체

구현체 없으면?

  • SLF4J는 그냥 인터페이스만 있어서,
  • 구현체가 없으면 "Logger는 있지만 찍을 방법이 없다"는 상태가 됨
  • 그래서 프로젝트에 logback-classic, log4j-slf4j-impl, jul-to-slf4j 중 하나는 무조건 있어야 로그가 나감

결론 요약

구분                                                                        내용

Logger, LoggerFactory SLF4J의 인터페이스 클래스
실질 로그 찍는 놈 logback, log4j 등 구현체가 찍음
왜 이렇게 분리함? 구현체 바꿔끼기 쉽게 하려고 (유지보수 유리)
의존성 필수 slf4j-api, 그리고 구현체 1개 이상 필요

SYSOUT vs LOGGER

그럼 System.out.println()이랑 비교해서 뭐가 좋은데?

항목 System.out.println() Logger

로그레벨 ❌ 없음 ✅ 있음 (info/debug/error 등)
로그 파일 저장 ❌ 불가 ✅ 가능
운영환경 제어 ❌ 불가 ✅ 레벨 조절 가능
성능 느림 (IO 직접) 빠름 (버퍼처리, 비동기 가능)

 


Logger란?

Logger는 로그를 찍기 위한 객체
개발할 때 System.out.println()으로 출력하는 습관이 있는데, 그거보다 훨씬 강력하고 실용적인 방식임
SLF4J(Simple Logging Facade for Java)는 로깅 추상화 라이브러리라서, 다양한 구현체(Logback, Log4j 등)를 내부적으로 선택해서 쓸 수 있게 해줌


Logger 쓰는 이유?

이유                                          설명

레벨별 로그 분리 info, debug, error 같은 레벨로 구분 가능
로그 관리 로그 파일 저장, 날짜별 분리, 용량 제한 등 가능
퍼포먼스 System.out보다 효율적임 (멀티스레드 환경에서도 안정적)
운영 환경 콘솔에 안 찍고 파일로 저장하는 게 일반적임

Logger 코드 분석

private static final Logger logger = LoggerFactory.getLogger(HomeController.class);

역할

  • SLF4J에서 제공하는 LoggerFactory를 이용해 Logger 객체 생성
  • 로그를 찍을 클래스 정보를 넘겨주면 됨 (HomeController.class)
  • static final로 선언해서 클래스 단위로 공용으로 사용

사용된 Logger 함수들

코드에서 사용한 메서드는 총 3가지임

1. logger.info(String msg)

  • 정보성 로그 찍을 때 사용
  • 운영 환경에서도 보통 이 레벨까지는 출력함
logger.info("서비스 실행됨");

 

this.logger.info(rs.getString("ctn")); // 결과값 출력
this.logger.info(con.toString());      // 커넥션 객체 정보 출력
this.logger.info("테스트 진행중");       // 상태 확인 로그

 

2. logger.debug(String msg)

  • 디버깅용 로그임
  • 개발 단계에서 디테일한 정보 볼 때 쓰임
  • 보통 운영 환경에서는 이 로그는 안 나감 (로그 레벨 설정에 따라 출력 여부 결정됨)
this.logger.debug("오류발생"); // 오류 디버깅 로그

 

3. logger.error(String msg)

  • 에러 로그 찍을 때 사용
  • 예외, 심각한 문제 발생 시 기록함
  • 운영 환경에서도 기본적으로 출력하게 설정함
this.logger.error(e.toString()); // 예외 객체의 메시지를 문자열로 출력

 

로깅 레벨 정리

레벨                                       설명                                                                                                    출력 대상 (운영 기준)

trace 가장 상세한 로그 (보통 안 씀) ❌
debug 개발 단계 디버깅용 ❌
info 일반 정보성 메시지 ✅
warn 경고 (문제 될 수 있는 상황) ✅
error 에러 발생 ✅

로그 설정은 어디서 ?

보통 logback.xml 또는 log4j.xml 파일에서 로그 레벨, 출력 포맷, 파일 저장 여부 등을 설정함
예시 (logback.xml):

<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

실무 팁

  • System.out.println()은 쓰지 마라 → 로거로 통일
  • 로깅 메세지는 항상 레벨 적절히 나눠서 사용
  • 로그 찍을 때는 가독성 좋게, 필요한 정보만 적절히 포함
  • Exception은 logger.error("에러내용", e);처럼 객체도 같이 넘겨주는 게 좋음 (스택트레이스까지 나옴)
저작자표시 비영리 변경금지 (새창열림)
'Web' 카테고리의 다른 글
  • [ECMA]
  • log4j.xml 에러 해결
  • [Javascript] 날짜 및 시간 체크
  • [Spring] Session
9na0
9na0
응애
  • 9na0
    구나딩
    9na0
  • 전체
    오늘
    어제
    • 분류 전체보기 (211)
      • Web (118)
      • Java (28)
      • 데이터베이스 (14)
      • 세팅 (12)
      • 과제 (3)
      • 쪽지시험 (2)
      • 정보처리기사 (4)
      • 서버 (25)
  • 블로그 메뉴

    • 링크

      • 포폴
      • 구깃
    • 공지사항

    • 인기 글

    • 태그

      re2
      file25
      spring-boot
      net1
      exam1_1~10
      noticewriteok
      net4
      file24
      notice_writer
      net3
      macbook pro m4
      datalist
      net2
      Oracle
      ab1
      java_io1~10
      io_dto
      file25_t
      re_java10
      net5~10
    • 최근 댓글

    • 최근 글

    • hELLO· Designed By정상우.v4.10.3
    9na0
    [Logger]
    상단으로

    티스토리툴바