Log4j2 란?
log4j(Log for Java)란 이전 버전인 Log4j 1.x에 비해 크게 개선된 Log4j로의 업그레이드이며 Logback 아키텍처의 몇 가지 고유한 문제를 수정하면서 Logback에서 사용할 수 있는 많은 개선 사항을 제공하는 대표적인 자바 로깅 프레임워크이다.
og4j 2.13.0 이상에는 Java 8이 필요합니다. 버전 2.4~2.12.1에는 Java 7이 필요합니다(Log4j 팀은 더 이상 Java 7을 지원하지 않습니다). 일부 기능에는 선택적 종속성이 필요합니다. 이러한 기능에 대한 설명서는 필요한 종속성을 지정합니다.
## 중요: 보안 취약점 CVE-2021-44832
요약: Apache Log4j2는 공격자가 구성을 제어할 때 JDBC Appender를 통해 RCE에 취약합니다.
참고: [Java] Log4j 원격코드실행 이슈 JNDI injection
- Log4j2를 사용하기 위해서는 아래와 같이 2단계로 프로젝트에 추가할 수 있다.
1. 자바 스프링 부트의 Default 자바 로깅 프레임워크는 logback이다. 아래와 같이 'org.springframework.boot:spring-boot-starter-web'에는 logback이 기본적으로 구현되어있다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
}
기존 자바 로깅 프레임워크인 logback의 종속성을 제거해주어야한다.
configurations {
all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
2. Log4j2 프레임워크의 종속성을 추가해준다.
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
}
log4j2 설정 파일
/src/main/resources 경로에 log4j2.xml 파일을 만들어 아래와 같이 기본적인 설정을 해준다.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" monitorInterval="5">
<!--공통 속성 설정 -->
<Properties>
<Property name="logFileName">log4jFile</Property>
<Property name="consoleLayout">[%d{yyyy-MM-dd HH:mm:ss}] [%-5p] [%c{1}:%L] - %m%n</Property>
<Property name="fileLayout">%d [%t] %-5level %c(%M:%L) - %m%n</Property>
</Properties>
<!-- Log Appender 설정 -->
<Appenders>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="${consoleLayout}" />
</Console>
<!--ConsoleAppender, RollingFileAppneder -->
<RollingFile name="file"
fileName="logs/${logFileName}.log"
filePattern="logs/${logFileName}.%d{yyyy-MM-dd-hh}.log">
<PatternLayout pattern="${fileLayout}" />
<Policies>
<TimeBasedTriggeringPolicy
modulate="true"
interval="1" /><!-- 시간별 로그 파일 생성-->
</Policies>
<DefaultRolloverStrategy max="5" fileIndex="min" > <!-- 롤링 파일 5개 까지 생성 -->
<Delete basePath="/logs" maxDepth="3">
<IfLastModified age="10d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="daily_error"
fileName="logs/error/error.log"
filePattern="logs/error/error.%d{yyyy-MM-dd}.log">
<PatternLayout pattern="${fileLayout}" />
<!--LevelRangeFilter필터를 사용할때에 단일 level의 필터만 허용한다. -->
<LevelRangeFilter minLevel="WARN" maxLevel="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB" />
</Policies>
<DefaultRolloverstrategy>
<Delete basePath="/logs" maxDepth="3">
<IfLastModified age="10d" />
</Delete>
</DefaultRolloverstrategy>
</RollingFile>
</Appenders>
<!--TRACE > DEBUG > INFO > WARN > ERROR > FATAL -->
<!--Log가 찍힐 대상 설정.-->
<Loggers>
<!-- 스프링 프레임워크에서 찍는건 level을 info로 설정 -->
<logger name="org.springframework" level="info" additivity="false" >
<AppenderRef ref="console" />
<AppenderRef ref="file" />
</logger>
<!-- rolling file에는 debug, console에는 info 분리하여 처리 가능하다. -->
<logger name="kr.pe.study.logforjava2" level="warn" additivity="true" >
<AppenderRef ref="daily_error" />
</logger>
<!-- ROOT logger-->
<Root level="info"></Root>
</Loggers>
</Configuration>
위 설정 파일에 대해 설명하자면
크게 3가지로 이루어져 있다.
- <Property/> : xml파일에서 사용할 공용 속성 값을 정의한다.
- <Appender/> : StringBuilder에서 사용되는 append와 비슷한 개념이다, 실제로 로그를 작성하는 객체를 정의한다고 생각하면 된다.
- <Logger/> : Appender가 작성한 대상들을 명시해준다.
Appender를 정의 ( 콘솔에 찍는 Appender, 파일에 찍는 Appender )하고 Logger대상들을 명시해주고 어떤 Appender가 일을 할지 정의한다.
1. <Configuration/>
<Configuration status="debug" monitorInterval="5">
Configuration은 설정 파일의 시작 태그를 나타낸다. status속성 값은 log4j2가 xml 설정 파일을 읽으면서 적용하는 단계에 출력할 log Level를 뜻한다.
Configuration의 status를 "info" level로 설정할 경우 아무런 로그가 나오지 않는다.
log4j2의 로그는 기본적으로 모두 "debug" + Console Log 로 이루어져 있다. "info", "debug" 둘 다 설정해보고 실행보면 이해가 편하다.
"monitorInterval"는 logback에서와 마찬가지로 xml 설정 파일을 주기적으로 모니터링을 하여 설정 값이 변경되면 변경된 값을 적용시킨다 log4j2 설정 파일에서 Interval은 분(Min)단위 이다.
Logback과 달리 재구성이 발생하는 동안 로그 이벤트를 잃지 않고 수행합니다.
2. <Property/>
<Properties>
<Property name="logFileName">log4jFile</Property>
<Property name="consoleLayout">[%d{yyyy-MM-dd HH:mm:ss}] [%-5p] [%c{1}:%L] - %m%n</Property>
<Property name="fileLayout">%d [%t] %-5level %c(%M:%L) - %m%n</Property>
</Properties>
Property는 말 그대로 해당 xml에서 사용할 속성 값을 정의하는 부분이다. 뒤에 나올 Layout을 속성 값으로 정의해주었다. 표현식은 아래에 자세히 나오니 넘어가자.
3. <Appender/>
<Appenders>
<!--ConsoleAppender, RollingFileAppneder -->
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="${consoleLayout}" />
</Console>
<RollingFile name="file"
fileName="logs/${logFileName}.log"
filePattern="logs/${logFileName}.%d{yyyy-MM-dd-hh}.log">
<PatternLayout pattern="${fileLayout}" />
<Policies>
<TimeBasedTriggeringPolicy
modulate="true"
interval="1" /><!-- 시간별 로그 파일 생성-->
</Policies>
<DefaultRolloverStrategy max="5" fileIndex="min" > <!-- 롤링 파일 5개 까지 생성 -->
<Delete basePath="/logs" maxDepth="3">
<IfLastModified age="10d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile ....>
<PatternLayout .... />
<!--LevelRangeFilter필터를 사용할때에 단일 level의 필터만 허용한다. -->
<LevelRangeFilter minLevel="WARN" maxLevel="WARN" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<SizeBasedTriggeringPolicy size="20 MB" />
</Policies>
<DefaultRolloverstrategy .....> ....
</DefaultRolloverstrategy>
</RollingFile>
</Appenders>
Appender에는 Adapter의 종류로 대표적으로 2가지가 존재한다.
1. Console. : Console에 Log를 작성하는 Appender, 어떻게 작성할지 패턴을 명시해준다.
2. RollingFile. : File에 Log를 작성하는 Appender, 파일의 이름, 파일명의 패턴, Log내용을 어떻게 작성할지에 대한 패턴, 파일을 어떻게 Rolling(회전)시킬지에 대한 정책(size?, TimeRange?.....), 파일 삭제 정책 등을 명시해준다.
소스 내에 주석으로 대략적인 설명은 되어있으니 이해는 충분할 것이다. 추가적인 내용은 정리가 잘 된 글을 참고하면 된다.
Logger 로그 작성
import ...... 생략.
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@Controller
public class WebController {
@Autowired
Sales SalesService;
// Log4j Logger
private final Logger logger = LogManager.getLogger(WebController.class);
@ResponseBody
@RequestMapping("/allCustomer")
public String getAllCustomer() {
//info Level Log write
logger.warn("getAllCustomer");
List<Customer> customerList = SalesService.getAllCustomer();
for(Customer customer : customerList)
System.out.println(customer.toString());
return "aa";
}
}
사용법은 정말 정말 간단하다. LogManager에게 해당 클래스가 속한 Logger를 얻어 로그를 작성하기만 하면 된다
WebController는 "kr.pe.study.logforjava2" 하위 패키지에 속하고 해당 logger는 "daily_error" Appender를 이용해 로그를 남기게 된다.
'Java > SpringBoot' 카테고리의 다른 글
[SpringBoot] JPA Entity Listener 엔티티 이벤트 리스너 (2) | 2022.04.26 |
---|---|
[SpringBoot] Exception Handler 예외를 통합관리 하자.!!! (0) | 2022.04.15 |
[SpringBoot] SOP, CORS 이야기 (0) | 2022.02.03 |
[SpringBoot] Security 인증 절차 시 DB Access 여러번 일어나는 이슈. (0) | 2022.01.12 |
[SpringBoot] UserDetailsService UserNotFoundException 안되는 이유 (0) | 2022.01.11 |