> For the complete documentation index, see [llms.txt](https://byulseop-til.gitbook.io/sinheeseop_til/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://byulseop-til.gitbook.io/sinheeseop_til/spring/mvc/logging_slf4j_logback.md).

# LoggingSLF4JLogback

## 1. 자바 로깅 시스템 개요

### SLF4J(Simple Logging Facade for Java) 이해하기

* **SLF4J란?**
  * 다양한 로깅 구현체를 위한 **추상화 인터페이스(Facade)**
  * 로깅 라이브러리들의 **공통 API**를 제공하는 브릿지 역할
  * 애플리케이션 코드는 SLF4J API만 사용하고, 실제 로깅 구현체는 필요에 따라 교체 가능
* **SLF4J 버전**
  * SLF4J 1.x: 현재 가장 널리 사용되는 버전
  * SLF4J 2.x: 자바 8 이상 지원, 새로운 기능 추가

### Logback: SLF4J의 대표적 구현체

* **Logback이란?**
  * SLF4J의 **기본 구현체**로 설계됨
  * Log4j의 창시자(Ceki Gülcü)가 개발한 더 발전된 로깅 프레임워크
  * Spring Boot의 **기본 로깅 구현체**로 채택됨

### 다른 로깅 구현체와 비교

| 로깅 라이브러리                    | 특징                   | SLF4J와의 관계 |
| --------------------------- | -------------------- | ---------- |
| **Logback**                 | 고성능, 자동 리로드, 필터링     | 네이티브 구현체   |
| **Log4j2**                  | 비동기 로깅, 멀티스레드 환경 최적화 | 어댑터 필요     |
| **JUL** (java.util.logging) | JDK 내장, 기본 기능만 제공    | 어댑터 필요     |

## 2. SLF4J + Logback 설정 방법

### 의존성 추가

#### Maven

```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>
```

#### Gradle

```groovy
implementation 'org.slf4j:slf4j-api:1.7.36'
implementation 'ch.qos.logback:logback-classic:1.2.11'
```

### 로깅 구성 파일 (logback.xml)

`src/main/resources/logback.xml` 파일 생성:

```xml
<configuration>
    <!-- 콘솔 출력 설정 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <!-- 파일 출력 설정 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/application.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/application.%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    
    <!-- 로그 레벨 설정 -->
    <logger name="com.myapp" level="DEBUG" />
    
    <!-- 루트 로거 설정 -->
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>
</configuration>
```

## 3. SLF4J 사용 방법

### 기본 사용법

```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class UserService {
    // 클래스별 로거 생성
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);
    
    public void processUser(User user) {
        // 다양한 로그 레벨 사용
        logger.trace("사용자 처리 시작: {}", user);
        logger.debug("사용자 ID: {}", user.getId());
        
        try {
            // 비즈니스 로직
            logger.info("사용자 {} 처리 중", user.getName());
            
            if (hasWarning(user)) {
                logger.warn("사용자 데이터에 문제가 있습니다: {}", user.getId());
            }
            
            // 처리 완료
            logger.info("사용자 처리 완료");
            
        } catch (Exception e) {
            // 예외 로깅 (스택 트레이스 포함)
            logger.error("사용자 처리 중 오류 발생", e);
        }
    }
    
    private boolean hasWarning(User user) {
        // 검증 로직
        return false;
    }
}
```

### 로그 레벨

* **TRACE**: 가장 상세한 디버깅 정보 (개발 환경)
* **DEBUG**: 개발 중 디버깅용 메시지 (개발 환경)
* **INFO**: 일반적인 실행 정보 (기본 설정)
* **WARN**: 잠재적 문제 경고
* **ERROR**: 오류 정보

상위 레벨이 설정되면 하위 레벨은 출력되지 않음 (INFO 설정 시 TRACE, DEBUG는 출력되지 않음)

## 4. SLF4J의 핵심 장점

### 1. 파라미터화된 로깅 (성능 최적화)

#### 비효율적인 방식

```java
logger.debug("사용자 정보: " + user.getName() + ", 나이: " + user.getAge());
```

#### 효율적인 방식

```java
logger.debug("사용자 정보: {}, 나이: {}", user.getName(), user.getAge());
```

**장점:**

* 로그 레벨이 비활성화(예: INFO 레벨에서 실행)되어도 문자열 연결 연산이 발생하지 않음
* 로그 출력 시에만 평가되어 성능 저하 방지

### 2. 구현체 교체 자유도

* 코드 변경 없이 로깅 구현체(Logback, Log4j2 등) 교체 가능
* 클래스패스에 원하는 구현체만 추가하면 SLF4J가 자동으로 감지

### 3. 브릿지 모듈을 통한 통합

* 다양한 로깅 라이브러리를 SLF4J로 통합 가능
* 여러 라이브러리가 각자 다른 로깅 시스템을 사용해도 하나로 통합

## 5. Spring Boot에서의 SLF4J와 Logback

### 기본 사용법

Spring Boot는 기본적으로 SLF4J + Logback을 사용하므로 별도 설정 없이 바로 사용 가능:

```java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {
    private static final Logger logger = LoggerFactory.getLogger(MyController.class);
    
    @GetMapping("/hello")
    public String hello() {
        logger.info("Hello 엔드포인트 호출됨");
        return "Hello World";
    }
}
```

### application.properties/yml에서 설정

```properties
# 로그 레벨 설정
logging.level.root=INFO
logging.level.com.myapp=DEBUG
logging.level.org.springframework.web=DEBUG

# 로그 파일 설정
logging.file.name=logs/application.log
```

```yaml
logging:
  level:
    root: INFO
    com.myapp: DEBUG
    org.springframework.web: DEBUG
  file:
    name: logs/application.log
```

## 6. 로깅 모범 사례

### 로깅 시 고려사항

1. **적절한 로그 레벨 사용**
   * 개발: DEBUG/TRACE
   * 테스트: INFO
   * 운영: INFO/WARN/ERROR
2. **의미 있는 로그 메시지 작성**
   * 문맥 정보 포함
   * 식별자(ID) 추가
   * 명확한 원인과 결과 표시
3. **성능 고려**

   * 파라미터화된 로깅 사용
   * 디버그 로깅 전 레벨 확인

   ```java
   if (logger.isDebugEnabled()) {
       logger.debug("복잡한 연산 결과: {}", expensiveOperation());
   }
   ```
4. **민감 정보 로깅 제외**

   * 비밀번호, 개인정보 등 마스킹 처리

   ```java
   logger.info("사용자 로그인: 이메일={}, 비밀번호=*****", email);
   ```

## 7. 결론

### SLF4J + Logback을 선택하는 이유

* **편리한 API**: 파라미터화된 로깅, 다양한 헬퍼 메서드
* **우수한 성능**: Logback의 최적화된 로깅 처리
* **유연한 구성**: 환경별 설정, 조건부 로깅
* **Spring Boot 통합**: 기본 로깅 시스템으로 채택됨
* **생태계 지원**: 다양한 도구와의 통합 용이
