위 Spring Boot Logging 공식 문서를 살펴보면, 아래와 같은 문구가 맨 위에 나온다.
Spring Boot는 내부 로깅에 Commons Logging을 사용하지만, 실제 로깅 구현체는 사용자가 선택할 수 있도록 열려 있다. Java Util Logging, Log4j2, Logback에 대한 기본 설정이 제공되는데, 각각의 경우 로거는 기본적으로 콘솔 출력이 사용되며, 선택적으로 파일 출력도 가능하다.
기본적으로, Spring Boot 스타터를 사용하면 Logback이 로깅 프레임워크로 사용된다. 또한, Logback 라우팅이 적절히 구성되어 있어서 Java Util Logging, Commons Logging, Log4J, 또는 SLF4J 를 사용하는 의존 라이브러리들도 문제없이 동작하도록 보장한다.
[File Output]
위와 같이 Spring Boot는 세가지 방식의 로깅 방식을 제공하고 있고, 원하는 방식으로 로그를 출력 또는 저장할 수 있다. 기본 설정은 로그를 단순히 콘솔에 출력하게끔 하고, 별도의 파일 출력은 설정되어 있지 않다. 만약 콘솔 출력 외에 로그 파일로도 기록하고 싶다면, logging.file.name 또는 logging.file.path 속성을 설정해야 한다. 만약 두 속성을 모두 설정한 경우, logging.file.path는 무시되고 오직 logging.file.name만 사용된다.
[ Default Logging Behavior in Spring Boot - Logback ]
그리고, spring-boot-starter-web, spring-boot-starter-data-jpa 등 Spring Boot 스타터(starter)는 spring-boot-starter-logging을 전이적 의존성(transitive dependency)으로 포함하고 있어 별도로 추가하지 않아도 spring-boot-starter-logging이 프로젝트에 포함된다는 점을 알 수 있다. starter-logging 의존성은 Logback을 사용할 수 있도록 해주는데, 이는 곧 명시적인 설정 파일이 없는 경우 Spring Boot는 자체 기본 설정을 사용하여 Logback을 구성한다는 점을 알 수 있다.
그런데, Logback은 개발자가 커스터마이징 할 수가 있다. 커스터마이징 관련 내용은 아래 포스팅 참고 바란다.
https://persi0815.tistory.com/118
커스터마이징은 yml 혹은 xml 파일을 통해 할 수가 있다. 커스터마이징을 한 후, 스프링 부트의 동작 방식은 다음과 같다.
만일, 프로젝트의 src/main/resources 디렉토리에 logback-spring.xml 파일이 있으면, Spring Boot는 이 파일을 우선적으로 사용한다. 파일 이름에 -spring이 포함되어 있는 경우, Spring Boot는 프로파일(profile)을 활용하여 동적으로 설정을 적용할 수 있게된다. spring.profiles.active=dev가 설정되면, logback-spring.xml에서 dev 프로파일에 해당하는 설정을 사용할 수 있다는 말이다.
logback-spring.xml이 아닌 logback.xml이 제공된 경우 Spring Boot의 프로파일 동적 설정을 지원하지 않는다.
logback-spring.xml도 없고 logback.xml도 없다면, Spring Boot의 내부 클래스 경로에 정의되어 있는 default logback configuration 파일을 따른다.
즉, Spring Boot는 아래 순서로 설정 파일을 검색한다.
logback-spring.xml -> logback.xml -> Spring Boot 기본 설정
[ Introduce 3 Logging System & Custom Log Configuration]
세 가지 로깅 방식 중에서 Logback에 대한 설명도 없이 스프링 starter가 default로 구성한다! 커스터마이징 할 수 있다!라고 조금 급히 설명을 했는데, 이제 다른 로깅 방법과 함께 자세히 알아보자!
1. JDK 로깅 (Java Util Logging)
java.util.logging은 Java 표준 라이브러리에 포함된 기본 로깅 프레임워크이다. 추가적인 외부 라이브러리 없이 바로 사용할 수 있으며, 간단한 로깅 요구사항을 처리하기에 적합하다.
로깅 동작은 logging.properties 파일로 설정하며, 이를 통해 로그 레벨, 출력 형식, 로그 파일 경로 등을 지정할 수 있다. 설정 문법이 다소 복잡하고 직관적이지 않아 다른 로깅 프레임워크에 비해 사용자 친화적이지 않을 수 있다.
고급 기능이 부족해 대규모 애플리케이션에서는 한계가 있지만, 경량 애플리케이션이나 의존성을 최소화해야 하는 환경에서는 유용하게 활용될 수 있다. JDK에 내장된 로깅 프레임워크로 기본적인 로깅 요구를 충족할 수 있는 안정적인 선택지이다.
JDK 로깅을 사용하기 위해선..
1. Logback 비활성화
configurations.all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
2. JDK 로깅 설정 파일 추가
JDK 로깅은 기본적으로 logging.properties 파일을 통해 구성되는데, 해당 파일을 클래스패스에 추가하여 설정할 수 있다.
파일 경로: src/main/resources/logging.properties
예시 설정 (logging.properties)
handlers = java.util.logging.ConsoleHandler
.level = INFO
# ConsoleHandler 설정
java.util.logging.ConsoleHandler.level = INFO
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# 특정 로거 설정
com.example.myapp.level = FINE
3. Spring Boot 애플리케이션에 JDK 로깅 적용
Spring Boot 애플리케이션의 메인 클래스에서 SpringApplication을 실행하기 전에 JDK 로깅 설정을 명시적으로 적용할 수 있다.
import java.util.logging.LogManager;
import java.util.logging.Logger;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
// JDK 로깅 설정 파일 로드
System.setProperty("java.util.logging.config.file", "src/main/resources/logging.properties");
// Spring Boot 애플리케이션 실행
SpringApplication.run(MyApplication.class, args);
}
}
2. Logback
Logback은 Spring Boot의 "기본" 로깅 프레임워크로, 강력하고 유연한 설정을 지원하는 도구이다. 기본적으로 logback.xml 또는 logback-spring.xml 파일을 통해 설정을 구성하며, SLF4J(Simple Logging Facade for Java)를 통해 인터페이스 형태로 사용된다. Logback은 로그 레벨별 파일 분리, 롤링 파일과 같은 고급 기능을 제공하며, XML 기반으로 직관적인 설정이 가능하다. 다만, 외부 라이브러리에 의존하기 때문에 Spring Boot 스타터를 통해 자동 포함된다.
Spring Boot의 YAML 또는 application.properties 파일에서 logging.level.root와 같은 설정을 통해 루트 로거의 로그 레벨을 제어할 수 있다. Spring Boot는 기본적으로 Logback의 설정을 동적으로 생성해 이러한 설정을 반영한다. 그러나 클래스패스에 logback-spring.xml 또는 logback.xml 파일이 존재하면 해당 파일의 설정이 YAML이나 application.properties보다 우선 적용된다. 특히, logback-spring.xml은 Spring Boot의 동적 프로파일 설정을 지원하며, 작성 시 Spring Boot의 기본 로깅 설정이 무시되고 해당 파일의 설정이 우선 적용된다.
결론적으로, Logback은 강력한 로깅 기능과 유연한 커스터마이징 옵션을 제공하며, Spring Boot 환경에서 필요에 따라 기본 설정 또는 명시적인 설정 파일을 통해 로깅 동작을 제어할 수 있다.
3. Log4j / Log4j 2
Log4j는 Apache에서 개발한 인기 있는 로깅 프레임워크이다. Log4j 1은 더 이상 유지보수되지 않으며, Log4j 2가 최신 버전이다. 풍부한 기능과 확장성을 제공하며, 동적 설정 변경과 비동기 로깅과 같은 고급 기능을 지원한다. 다만, 초기 버전에서 취약점 문제가 보고된 적이 있어 항상 최신 버전을 사용하는 것이 중요하다.
log4j 사태가 궁금하다면?
https://www.boannews.com/media/view.asp?idx=105394
최악의 보안 취약점 ‘Log4j’, 남은 이슈와 보안담당자들의 과제
2021년 12월 처음 발견돼 사상 최악의 보안 취약점으로 불리는 Log4j 취약점(일명 Log4Shell)이 올해도 가장 큰 보안 위협 가운데 하나로 지목되고 있다. 이에 따라 Log4j 취약점에 있어 현재까지 제기되
www.boannews.com
Log4j 2를 사용하기 위해선..
1.1 Logback 비활성화
spring-boot-starter-logging을 제외하거나 비활성화한다.
configurations.all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
1.2 Log4j 2 의존성 추가
build.gradle에 Log4j 2 의존성을 추가한다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
}
1.3 Log4j 2 설정 파일 추가
클래스패스에 log4j2-spring.xml 파일을 생성한다. 이 파일은 Log4j 2의 설정을 정의하는 XML 파일이다.
ex) src/main/resources/log4j2-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
[ SLF4J & @Slf4j ]
프로젝트를 할 때 로그를 찍어봐야겠다!하면 yml에서 로깅 레벨 조정하고, 클래스에 Lombok에서 제공하는 애노테이션인 @Slf4j를 추가했었다. logback, jdk, log4j 이런 로깅 방식들에 대해 신경을 쓰지 않고 @Slf4j를 사용했었는데, 나와 같은 분이 있다면 이번 기회에 Slf4j이 무엇이고, 어떻게 작동하는지에 대해 알아보면 좋을 것 같다.
SLF4J란?
SLF4J(Simple Logging Facade for Java)는 로깅 프레임워크에 대한 추상화 계층을 제공하는 라이브러리이다. 이를 통해 개발자는 특정 로깅 프레임워크에 종속되지 않고도 일관된 방식으로 로깅을 구현할 수 있다. SLF4J의 주요 목적은 실행 시점에 사용할 로깅 프레임워크를 유연하게 선택할 수 있도록 하는 것이다.
@Slf4j란?
@Slf4j는 Lombok이 제공하는 애노테이션으로, SLF4J 로거 객체를 자동으로 생성한다. 애노테이션을 클래스에 추가하면, 해당 클래스에서 직접적으로 로거를 정의하거나 초기화할 필요 없이 '간편하게' 로깅 기능을 사용할 수 있다.
SLF4J의 작동 방식과 로깅 구현체 연결 과정
SLF4J는 자체적으로 로깅을 처리하지 않고, 단순히 로그 메시지를 실제 로깅 구현체로 전달하는 역할을 한다. 이를 통해 개발자는 특정 로깅 프레임워크에 종속되지 않고, 코드 작성과 실행 환경을 분리할 수 있다.
SLF4J의 작동 방식
- 추상화 계층 제공
SLF4J는 개발자가 로깅 API를 호출할 때, 이 요청을 바인딩된 로깅 구현체(Logback, Log4j2, java.util.logging 등)로 전달한다. 자체적으로 로깅을 처리하지 않으며, 추상화된 인터페이스만 제공한다. - 바인딩 라이브러리
SLF4J는 로깅 구현체와 연결하기 위해 바인딩 라이브러리를 제공한다. 예를 들어, slf4j-logback-classic은 SLF4J와 Logback을 연결하는 라이브러리이다. 클래스패스에 포함된 바인딩 라이브러리를 통해 SLF4J는 실행 시점에 로깅 구현체와 연결된다. - 프레임워크 독립성
SLF4J를 사용하여 작성된 코드는 특정 로깅 프레임워크에 의존하지 않는다. 실제 로깅 동작은 실행 시점에 연결된 구현체에 의해 결정되므로, 로깅 프레임워크를 교체하더라도 코드를 수정할 필요가 없다.
SLF4J와 로깅 구현체 연결 과정
- 코드 작성
개발자는 SLF4J API(ex. log.info, log.error)를 사용하여 로깅 코드를 작성한다. 이러한 API는 SLF4J 인터페이스를 통해 구현체로 전달된다. - 바인딩 라이브러리 추가
Spring Boot는 기본적으로 spring-boot-starter-logging을 통해 SLF4J와 Logback을 자동으로 연결한다. 만약 Logback 외의 다른 로깅 프레임워크를 사용하려면, 예를 들어 Log4j2를 사용하려면 slf4j-log4j2 바인딩 라이브러리를 추가해야 한다. - 실행 시점 결정
애플리케이션이 실행되면, SLF4J는 클래스패스에서 적절한 바인딩 라이브러리를 검색한다. 발견된 바인딩 라이브러리를 통해 SLF4J는 로깅 메시지를 실제 로깅 구현체로 전달한다.
SLF4J와 Spring Boot의 기본 동작
Spring Boot는 기본적으로 SLF4J와 Logback을 사용하여 로깅을 처리한다. spring-boot-starter-logging을 통해 SLF4J와 Logback 간의 연결이 자동으로 설정되며, 개발자가 별도로 설정하지 않아도 기본 로깅 환경이 구성된다. 이를 통해 Spring Boot 애플리케이션은 강력한 로깅 기능을 기본으로 제공하며, 필요에 따라 YAML, properties 파일 또는 Logback 설정 파일을 통해 로깅 동작을 세부적으로 제어할 수 있다.
SLF4J를 통해 구현된 이러한 구조는 개발자가 코드를 작성할 때 특정 로깅 프레임워크에 얽매이지 않도록 하고, 실행 환경에서 로깅 구현체를 유연하게 교체할 수 있도록 한다.
SLF4J Manual
SLF4J user manual The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks, such as java.util.logging, log4j 1.x, reload4j and logback. SLF4J allows the end-user to plug in the desired logging frame
www.slf4j.org
[File Rotation]
파일 로테이션(File Rotation)이란 로그 파일의 크기나 보관 기간이 특정 조건을 초과했을 때, 기존 로그 파일을 새 파일로 교체하거나 별도로 보관하는 관리 방법이다. 이를 통해 로그 파일이 무한히 커지는 것을 방지하고, 시스템 성능과 저장 공간을 효율적으로 관리할 수 있다.
Logback을 사용하는 경우, application.properties 또는 application.yaml 파일을 통해 로그 로테이션 설정을 세밀하게 조정할 수 있는데, 물론 xml 파일로도 가능하다. 다른 로깅 시스템(Logback 외)을 사용하는 경우, 로테이션 설정은 직접 구성해야 한다. ex. log4j2.xml 또는 log4j2-spring.xml
[Log Levels]
Spring Boot에서 지원되는 모든 로깅 시스템은 Spring Environment(ex. properties, yml)에서 로거 레벨을 설정할 수 있다. 아래와 같이 TRACE, DEBUG, INFO, WARN, ERROR, FATAL, 또는 OFF 중 하나를 사용할 수 있다.
logging:
level:
root: warn
org.springframework.web: debug
org.hibernate: error
위와 같은 logging.level 설정은 패키지 단위로 로깅 레벨을 설정한다.
개별 파일이나 클래스별로 로깅 레벨을 설정하려면, logback-spring.xml과 같은 Logback 설정 파일을 사용하는 것이 가장 적합하다.
<configuration>
<logger name="com.example.MyClass" level="DEBUG" />
<logger name="com.example.MyOtherClass" level="INFO" />
<root level="WARN">
<appender-ref ref="CONSOLE" />
</root>
</configuration>
로거 레벨 설명
- OFF (최상위): 모든 로그 출력을 비활성화. 로깅이 완전히 중단됨.
- FATAL: 치명적인 오류를 기록. 애플리케이션이 즉시 중단되거나 심각한 문제가 발생한 경우에만 사용.
- ERROR: 오류가 발생했음을 기록. 애플리케이션 일부 기능이 실패하거나 예외가 발생한 경우.
- WARN: 주의가 필요한 경고 수준의 메시지. 실행에는 문제가 없지만, 잠재적 문제를 경고.
- INFO: 일반적인 상태 정보를 기록. 애플리케이션 실행 흐름과 관련된 정보.
- DEBUG: 디버깅 정보를 기록. 애플리케이션의 내부 상태를 자세히 확인하기 위한 정보.
- TRACE (최하위): 가장 상세한 디버깅 정보를 기록. 메서드 호출, 루프 내부 상태 등.
각 레벨은 계층적으로 동작하며, 상위 레벨의 로그만 출력할 경우 하위 레벨 로그는 무시된다. 계층은 적혀있는 순이다.
[Log Groups]
관련된 로거들을 그룹으로 묶어서 동시에 설정할 수 있으면 유용할 때가 있다. 예를 들어, Tomcat과 관련된 모든 로거의 로깅 레벨을 변경하고 싶을 때, 최상위 패키지 이름들을 기억하지 못해도 쉽게 설정할 수 있도록 돕는다.
Spring Boot는 Spring 환경에서 로깅 그룹을 정의할 수 있는 기능을 제공한다. 이를 통해 특정 로거들을 그룹화하여 한 번에 설정할 수 있다.
참고한 공식 문서
https://docs.spring.io/spring-boot/reference/features/logging.html
Logging :: Spring Boot
By default, Spring Boot logs only to the console and does not write log files. If you want to write log files in addition to the console output, you need to set a logging.file.name or logging.file.path property (for example, in your application.properties)
docs.spring.io
'Backend > Spring Boot' 카테고리의 다른 글
[Spring/Java] 웹소켓 이용하여 간단하게 빠칭코(게임) 구현하기 (0) | 2024.11.14 |
---|---|
[Spring/Java] 민감한 개인정보 AES 알고리즘으로 암호화/복호화하기 (1) | 2024.11.14 |
[Spring/Java] FCM을 통해 Push 알림 보내기 (0) | 2024.07.08 |
[Spring/Java] CORS란? 해결법은? (0) | 2024.07.07 |
[Spring/Java] 동시성 제어 통한 게시물 좋아요 및 댓글 수 관리 (비관적 락, 반정규화, 세마포어) (0) | 2024.07.07 |