DevLog ๐ถ
[Spring] ์๋ฌ ๋ก๊น ํ๊ธฐ - Logback์ ์ฌ์ฉํด์ ERROR ๋ ๋ฒจ๋ง ํ์ผ๋ก ๋ก๊ทธ๋ฅผ ๋จ๊ฒจ๋ณด์! ๋ณธ๋ฌธ
[Spring] ์๋ฌ ๋ก๊น ํ๊ธฐ - Logback์ ์ฌ์ฉํด์ ERROR ๋ ๋ฒจ๋ง ํ์ผ๋ก ๋ก๊ทธ๋ฅผ ๋จ๊ฒจ๋ณด์!
dolmeng2 2023. 6. 5. 19:36๐ฑ ๋ค์ด๊ฐ๊ธฐ ์
์ด๋ฒ ์ฅ๋ฐ๊ตฌ๋ ๋ฏธ์ ์์๋ ํ๋ก ํธ ํฌ๋ฃจ๋ค๊ณผ ํ์ ์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์์ผ๋ก ์๋ฌ ๋ก๊ทธ๋ฅผ ๋ณผ ์ผ์ด ๋ง์์ง ๊ฒ ๊ฐ๋ค๊ณ ์๊ฐํ๋ค.
๋ฐฐํฌ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๋ฉด์ ์คํ๋ง์ด ๋์์ง ๋์ ๋ก๊ทธ๋ ๋ณผ ์ ์์์ง๋ง, ์๋ฌ์ ๋ํ ๋ก๊ทธ๋ง ๋น ๋ฅด๊ฒ ํ์ธํ๋ฉด ์ข์ ๊ฒ ๊ฐ์์ ์ด๋ฒ ๋ฏธ์ ์ ๋๋ฆ์ ์ฝ์ง์ ๊ณ๋ค์ฌ๊ฐ๋ฉฐ ์ ์ฉํด๋ณด์๋ค ๐
๐ฑ ๋ฌธ์ ์ํฉ
๋ฐฐํฌ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํ๋ฉฐ ์๋์ ๋ฌธ์ฅ์ด ๋๋ฅผ ํผ๋์ค๋ฝ๊ฒ ํ๋ค.
nohup sudo java -jar $JAR_NAME >> $REPOSITORY/deploy.log 2> $REPOSITORY/deploy-err.log &
nohup : ํฐ๋ฏธ๋์ ์ข ๋ฃํด๋ ๊ณ์ ์คํํ๊ธฐ.
java -jar $JAR_NAME : jar ํ์ผ ์คํํ๊ธฐ.
>> : ์ถ๋ ฅ ๋ฆฌ๋ค์ด๋ ์ . jar์ ์คํ ๊ฒฐ๊ณผ๋ฅผ ํ์ผ๋ก ์ ์ฅํ๊ณ ์ถ์ด! (deploy.log ํ์ผ๋ก ์ ์ฅ)
- ์ฐธ๊ณ ๋ก, >>์ ๊ฒฝ์ฐ ๊ธฐ์กด์ ํ์ผ์ ๋ด์ฉ์ ์ถ๊ฐํ๋ ๊ฒ์ด๊ณ ์๋กญ๊ฒ ๋ฎ์ด์์ฐ๊ณ ์ถ๋ค๋ฉด >์ ์ฌ์ฉํ์.
โญ๏ธ 2> : ํ์ค ์ค๋ฅ ์ถ๋ ฅ ๋ฆฌ๋ค์ด๋ ์ . jar์ ์คํ ๊ฒฐ๊ณผ ์ค 'ํ์ค ์ค๋ฅ'์ ๋ํด์ deploy-err.log ์ ์ฅํ๊ธฐ
& : ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํํ๊ธฐ. ๊ธฐ๋ณธ์ ์ผ๋ก ์์ ๋ช ๋ น์ด๊ฐ ์ข ๋ฃ๋ ๋๊น์ง ๊ณ์ ๋๊ธฐํ๊ธฐ ๋๋ฌธ์ ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํํ์ฌ ๋ค๋ฅธ ์์ ๋ ์งํํ ์ ์๋๋ก ๋ง๋ค๊ธฐ.
๋๋ ์ฌ๊ธฐ์ 2> $REPOSITORY/deploy-err.log ์ด ์น๊ตฌ ๋๋ฌธ์ ์คํ๋ง์์ ์๋ฌ ๋ก๊ทธ๊ฐ ๋ฐ์ํ๋ฉด deploy-err.log๋ก ์ ์ฅ๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ๋ค. ํ์ง๋ง... ์๋ฌด๋ฆฌ ํด๋ ์๋ฌด๊ฒ๋ ์ ์ฅ์ด ๋์ง ์์์ ์ ๋งํ๊ณ ์์๋ค.
์ด๋, 2>๊ฐ 'ํ์ค ์ค๋ฅ ์ถ๋ ฅ'์ ๋ํด์ ๋ฆฌ๋ค์ด๋ ์ ์ ํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
๐ฌ ํ์ค ์ค๋ฅ ์ถ๋ ฅ์ด ๋ญ๊น?
๋ณดํต ์์์ ๋ช ๋ น์ด๋ฅผ ์คํํ๊ฒ ๋๋ฉด, ํด๋น ๋ช ๋ น์ด์ ๋ํ ์ถ๋ ฅ์ ํ์ค ์ถ๋ ฅ (STDOUT)์ ํตํด ๋์ค๊ฒ ๋๋ค.
ํ์ง๋ง, ํด๋น ๋ช ๋ น์ด๋ฅผ ์คํํ๋ ๋์ค์ ๋ฐ์ํ๋ ์ค๋ฅ๋ ๊ฒฝ๊ณ , ์์ธ ๋ฉ์์ง์ ๊ฒฝ์ฐ ํ์ค ์ถ๋ ฅ (STDERR)์ ํตํด ๋์ค๊ฒ ๋๋๋ฐ, ์๋ฅผ ๋ค์ด ํ์ผ์ ์ฐพ์ ์ ์๊ฑฐ๋, ์๋ชป๋ ๋ช ๋ น์ด๋ฅผ ์ ๋ ฅํ๋ ๊ฒ ๊ฐ์, '๋ช ๋ น์ด๋ฅผ ์คํํ๋ ๋์ค'์ ๋ฐ์ํ ์ค๋ฅ์ ๋ํด์ ๊ด๋ฆฌํ๊ฒ ๋๋ค.
๋๋ ์คํ๋ง์์ ์๋์ ๊ฐ์ด ์๋ฌ์ ๋ํ ๋ก๊ทธ ํธ๋ค๋ง์ ํ๊ณ ์์๋ค.
@ControllerAdvice
public class ControllerExceptionHandler {
private final Logger log = LoggerFactory.getLogger(getClass());
@ExceptionHandler(Exception.class)
public ResponseEntity<Void> exception(Exception e) {
log.error(e.getMessage(), e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
}
๋ฌผ๋ก , ์ถํ ๊ธฐ๋ฅ์ ๊ฐ๋ฐํ๋ฉด์ ๊ณ ๋ํํ๊ฒ ์ง๋ง ์ฐ์ ๋ชจ๋ ์์ธ์ ๋ํด ๋ก๊ทธ ์ฒ๋ฆฌ๋ฅผ ํ๊ธฐ ์ํด์ ์ด๋ ๊ฒ ์งํํ์๋ค.
์ฌ๊ธฐ์ log.error()๋ฅผ ์ฌ์ฉํ์ฌ ์ถ๋ ฅํ ๊ฒ์ ๋จ์ํ ๋ก๊น ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ ํตํด ์ค๋ฅ ๋ ๋ฒจ์ ๋ก๊ทธ๋ฅผ ๊ธฐ๋กํ๊ฒ ๋๋ฉฐ, ์ค์ ์ถ๋ ฅ ๋์์ ๋ณ๋์ ์ค์ ์ ํตํด์ ์ฒ๋ฆฌํด์ค์ผ ํ๋ ๊ฒ์ด์๋ค.
๊ทธ๋์, ๋ง์ฝ ์คํ๋ง์์ ํ์ค ์๋ฌ๋ก ์ถ๋ ฅํ๊ณ ์ถ๋ค๋ฉด ์๋์ ๊ฐ์ด ์งํํ๋ฉด ๋๋ค.
@ControllerAdvice
public class ControllerExceptionHandler {
private final Logger log = LoggerFactory.getLogger(getClass());
@ExceptionHandler(Exception.class)
public ResponseEntity<Void> exception(Exception e) {
System.err.println(e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
}
The "standard" error output stream.
This stream is already open and ready to accept output data.
err์ ๋ํด์ ์์ ๊ฐ์ด 'ํ์ค ์๋ฌ' ์ถ๋ ฅ ์คํธ๋ฆผ์ผ๋ก ์ง์ ํ๋ค๊ณ ๋์ด ์๋ค.
ํ์ง๋ง... System.out.println์ ํตํด์ ๋ก๊น ์ฒ๋ฆฌ๋ฅผ ์ ํ๋ฏ์ด, ์๋ฌ ์ญ์ ์ ๋ฐ ์์ผ๋ก ์ฒ๋ฆฌํ๋ ๊ฒ์ ๋๊ณ ๋ณผ ์ ์๋ค.
๐ฌ ๊ทผ๋ฐ ์ System.out.println์ ์ฐ๋ฉด ์ ๋ ๊น?
๋ก๊น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ก๊ทธ ์ถ๋ ฅ ๋ ๋ฒจ์ ํตํด ๊ฐ๋ฐ ํ๊ฒฝ์ ๋ฐ๋ฅธ ๋ก๊ทธ ๋ ๋ฒจ์ ์ ์ฉํ ์ ์์ง๋ง, System.out.println์ ๊ทธ๋ฐ ๊ฒ ์ ๋๋ค.
๋ชจ๋ ๋์ผํ ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋๋ค ๋ณด๋ ๋ก์ปฌ ํ๊ฒฝ์์๋ debug ๋ ๋ฒจ๋ถํฐ, ํ๋ก๋์ ํ๊ฒฝ์์ warn ๋ ๋ฒจ๋ถํฐ ๋ณผ ์ ์๋๋ก ์กฐ์ ํ ์ ์๋ค๋ ๊ฒ์ด๋ค.
๋ํ, ๋ด๋ถ์ ์ผ๋ก synchorized๋ฅผ ํตํด ๋ฉํฐ ์ค๋ ๋ ํ๊ฒฝ์์๋ ๋ฝ์ด ๊ฑธ๋ฆฌ๊ธฐ ๋๋ฌธ์ ์ฑ๋ฅ์ ์ผ๋ก๋ ๋ฌธ์ ๊ฐ ์๊ธด๋ค๊ณ ํ๋ค.
์์ธํ ๊ฑด ์ด ๋ ํผ๋ฐ์ค์์ ๋ ์ฐธ๊ณ ํด๋ ์ข์ ๊ฒ ๊ฐ๋ค ๐
๊ทธ๋ ๋ค๋ฉด, ์ฐ๋ฆฌ๋ ์ด๋ป๊ฒ ์๋ฌ์ ๋ํ ๋ก๊น ์ ์งํํด์ผ ํ ๊น?
๐ฑ Logback ํ์ฉํ๊ธฐ
๋ฐ๋ก, Logback์ด๋ผ๋ ์น๊ตฌ๋ฅผ ํ์ฉํ๋ ๊ฒ์ด๋ค.
Logback์ ๋ํ์ ์ธ ๋ก๊น ํ๋ ์์ํฌ ์ค ํ๋๋ก, Log4j๋ฅผ ๋์ฒดํ๊ธฐ ์ํด์ ๋์๋ค๊ณ ํ๋ค.
์คํ๋ง๋ถํธ์ ๊ฒฝ์ฐ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๋ณ๋์ dependency๋ฅผ ์ค์ ํด์ค ํ์๊ฐ ์์ด์ ๊ฐํธํ๋ค.
๊ธฐ๋ณธ์ ์ผ๋ก Logback์ ๊ฒฝ์ฐ Logger, Appender, Layout์ด๋ผ๋ 3๊ฐ์ง์ ํด๋์ค๋ก ๊ตฌ์ฑ๋์ด ์๋ค.
Logger: ๋ก๊ทธ ๋ฉ์์ง์ ๋ํ ์ผ์ข ์ ์ปจํ ์คํธ๋ก, ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ก๊ทธ ๋ฉ์์ง๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ํธ์์ฉํ๋ ํด๋์ค์ด๋ค.
Appender: ๋ก๊ทธ ๋ฉ์์ง๋ฅผ ๋ฐฐ์นํ๋ ์ญํ ๋ก, Logger๋ ๋ ์ด์์ Appender๋ฅผ ๊ฐ์ง ์ ์๋ค.
Layout: ์ถ๋ ฅ๋ ๋ฉ์์ง๋ฅผ ์ค๋นํ๋ฉฐ, ๋ฉ์์ง ํฌ๋งคํ ์ ์ํ ํด๋์ค ์์ฑ์ ์ง์ํ๋ค.
๋ํ, '๋ก๊ทธ ๋ ๋ฒจ'์ด๋ผ๋ ๊ฐ๋ ์ ์ดํดํด์ผ ํ๋๋ฐ, Logback์ ๋ก๊ทธ ๋ ๋ฒจ์ ์ด 5๋จ๊ณ๋ก ๊ตฌ์ฑ๋์ด ์๋ค.
Trace - Debug - info - Warn - Error ์์ด๋ฉฐ, ๋ณดํต ๋ค์๊ณผ ๊ฐ์ ์๋ฏธ๋ฅผ ๊ฐ์ง๋ค.
TRACE: ์ ํ๋ฆฌ์ผ์ด์ ๋ด๋ถ์ ์์ ๋จ์ ๋์์ด๋ ๋ฉ์๋ ํธ์ถ, ๋ณ์ ๊ฐ ๋ฑ์ ๋ํ ์ ๋ณด๋ฅผ ๋ชจ๋ ํฌํจํ๋ค. (์์ฒญ ๋ฐฉ๋ํ ์์ ๋ก๊ทธ๊ฐ ์์ด๊ฒ ๋๋ค.) ๋ก์ปฌ ๊ฐ๋ฐ ํ๊ฒฝ์์ ๋ง์ด ์ฌ์ฉํ๋ค.
DEBUG: Trace๋ณด๋ค ์กฐ๊ธ ๋ ์์ ์์ค์ ๋ ๋ฒจ์ด๋ฉฐ, SQL์ ๋ํ ๋ก๊น ์ ์งํํ ์ ์๋ค. (๊ฒฝํ์ ๋ก์ปฌ, ๊ฐ๋ฐ ์๋ฒ๊น์ง debug ๋ ๋ฒจ์ ๋ง์ด ์ฌ์ฉํ๋ ๊ฒ ๊ฐ๋ค.)
INFO: ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฃผ์ ๋์์ด๋ ์ด๋ฒคํธ, ์์ฒญ ์ฒ๋ฆฌ ์ ๋ณด๋ฅผ ํฌํจํ์ฌ ์คํ๋ง ๋ถํธ์์๋ ๋ํดํธ๋ก INFO ๋ ๋ฒจ๋ถํฐ ๋ณด์ธ๋ค.
WARN: ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ๊ธฐ๋กํ๋ฉฐ, ์๋น์ค ์ด์ ์์ฒด์๋ ์ํฅ์ด ์์ง๋ง, ์ฃผ์๊ฐ ํ์ํ ๋ถ๋ถ์ ๋ค์ด๊ฐ๋ค.
ERROR: ๊ฐ์ฅ ์ฌ๊ฐํ ๋จ๊ณ์ด๋ค. ์ฆ์ ์กฐ์น๋ฅผ ์ทจํด์ผ ํ๋ ์์ค์ ๋ ๋ฒจ์ด๋ผ๊ณ ํ๋ค.
์ฌ์ค ๊ฐ์ธ์ ์ผ๋ก ExceptionHandler์์ ์ฒ๋ฆฌํ๋ ๋ก๊น ์ ์ด๋ ๋ ๋ฒจ์์ ์ฒ๋ฆฌํด์ผ ํ ์ง ๊ณ ๋ฏผ์ธ๋ฐ...
๊ฐ์ธ์ ์ผ๋ก ํด๋ผ์ด์ธํธ์ ๊ณ์ ๊ฐ๋ฐํ๋ ๋จ๊ณ์์๋ ERROR๋ก ํธ๋ค๋งํด์ผ ์ด๋ค ์ํฉ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋์ง ํด๋ผ์ด์ธํธ ๊ฐ๋ฐ์์๊ฒ ์ ํด์ฃผ๊ธฐ ์ข์ ๊ฒ ๊ฐ์์ ExceptionHandler์ ๋ก๊น ๋ ๋ฒจ์ ERROR๋ก ์ค์ ํ์๋ค.
@ControllerAdvice
public class ControllerExceptionHandler {
private final Logger log = LoggerFactory.getLogger(getClass());
@ExceptionHandler(AuthenticationException.class)
public ResponseEntity<Void> handlerAuthenticationException(AuthenticationException e) {
log.error(e.getMessage(), e);
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).build();
}
@ExceptionHandler(CartItemException.IllegalMember.class)
public ResponseEntity<Void> handleException(CartItemException.IllegalMember e) {
log.error(e.getMessage(), e);
return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Void> exception(Exception e) {
log.error(e.getMessage(), e);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
}
}
๊ทธ๋์ ์ฐ์ , ๋ฐ์ํ ์ ์๋ ๋ชจ๋ ์์ธ ์ํฉ์ ๋ํด์ log.error๋ก ๋ก๊น ์ฒ๋ฆฌ๋ฅผ ์งํํด์ฃผ์๋ค.
๋ก๊ทธ๋ฐฑ์ ํ์ฉํด์ ๋ด๊ฐ ํ๊ณ ์ถ์ ๋ด์ฉ์ ๋ค์๊ณผ ๊ฐ๋ค.
1. ๊ธฐ๋ณธ์ ์ผ๋ก info ํ์ ๋ ๋ฒจ์ ๋ก๊ทธ๋ console์ ์ถ๋ ฅํ๊ธฐ
2. โญ๏ธ ์ด๋, error ๋ ๋ฒจ์ ๋ก๊ทธ๋ ์ฝ์ ๋ฐ ๋ณ๋์ ํ์ผ์ ํจ๊ป ์ถ๋ ฅํ๊ธฐ
3. error ๋ ๋ฒจ์ ๋ก๊ทธ๋ ๋ ์ง๋ณ๋ก ๊ด๋ฆฌํ๊ธฐ
๐ฑ Logback ๋ถ์ํ๊ธฐ
์ฒ์ฒํ ๋ฐ๋ผํด๋ณด์.
src/resources ํ์์ logback-spring.xml์ด๋ผ๋ ํ์ผ์ ์์ฑํ๋ค.
<configuration>
<property resource="logback-variables.properties"/>
<timestamp key="ToDay" datePattern="yyyy-MM-dd"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
${LOG_PATTERN}
</Pattern>
</layout>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>error</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<file>${LOG_PATH}/${ToDay}/${LOG_FILE_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
${LOG_PATH}/%d{yyyy-MM-dd}/${LOG_FILE_NAME}_%i.log
</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
๊ทธ๋ฆฌ๊ณ , logback-variables.properties๋ผ๋ ํ์ผ์ ์์ฑํ๋ค.
LOG_PATH=./logs
LOG_FILE_NAME=jwp-shopping-order
LOG_PATTERN=%d{yyyy-MM-dd HH:mm:ss.SSS} [%level] [%thread] [%logger{36}] - %msg%n
์ ์ญ์ ์ผ๋ก ๊ด๋ฆฌํ๋ฉด ์ข์ ๊ฒ ๊ฐ์ ๋ถ๋ถ์ ๋ํด ๋ณ์๋ก ๋ถ๋ฆฌํด๋์๋ค.
๐ฌ ํ๋กํผํฐ์ ํ์์คํฌํ ์ ์ธํด์ฃผ๊ธฐ
์ฝ๋๊ฐ ๊ธธ๊ธฐ ๋๋ฌธ์ ํ๋์ฉ ๋ถ๋ฆฌํด์ ์ฐจ๋ก๋๋ก ํ์ ํด๋ณด์.
๋จผ์ ํ๋กํผํฐ๋ฅผ ๋ถ๋ฌ์จ ๋ค์, 3๋ฒ ์กฐ๊ฑด (๋ ์ง๋ณ๋ก ๋ก๊ทธ ๊ด๋ฆฌ) ๊ตฌํ ์ ์ฌ์ฉํ๊ธฐ ์ํด ๋ ์ง ํจํด์ ์ ์ํด๋์๋ค.
๐ฌ ์ฝ์ ์ถ๋ ฅ์ ์ํ ๋ก๊น ์ค์ ์งํํ๊ธฐ
๋ค์์ผ๋ก ์ฝ์ ์ถ๋ ฅ์ ๋ํ appender๋ฅผ ์ ์ํ์๋ค.
์ฝ์ ์ถ๋ ฅ ์ ์ด๋ค ํจํด์ ์ฌ์ฉํ์ฌ ๋ก๊น ์ ํ ๊ฒ์ธ์ง ์ ์ํ ๊ฒ์ธ๋ฐ, ์ค์ ๋ก ์ฝ์ ์ถ๋ ฅ๊ณผ ๋น๊ตํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
๋ฐ์ ์๊ฐ - ๋ก๊ทธ ๋ ๋ฒจ - ์ค๋ ๋ ์ด๋ฆ - ๋ก๊ทธ ๋ฐ์ ์ฃผ์ฒด์ ์ด๋ฆ - ๋ฉ์์ง
ํ๋์ฉ ๋ผ์ด์ ๋ณด๋๊น ์ดํดํ๊ธฐ ์ฝ์ฃ ...? ๐
๐ฌ ํ์ผ ์ถ๋ ฅ์ ์ํ ๋ก๊น ์ค์ ์งํํ๊ธฐ
์ฌ๊ธฐ๋ ๊ฝค ๊ธธ๊ธฐ ๋๋ฌธ์ ํ๋์ฉ ํ์ ํด๋ณด์.
์ฝ์ ๋์ ๋ง์ฐฌ๊ฐ์ง๋ก appender๋ฅผ ์ ์ํด์ค๋ค.
์ด๋, ์ฐ๋ฆฌ๋ 2๋ฒ ์กฐ๊ฑด (error ๋ ๋ฒจ์ ๋ก๊ทธ๋ ํ์ผ๋ก ์ ์ฅ)์ ๋ง์กฑํ๊ธฐ ์ํด ๋ณ๋์ filter๋ฅผ ์ ์ํด์ฃผ์๋ค.
๋ง์ฝ ERROR ๋ ๋ฒจ์ด๋ผ๋ฉด ํ์ฉ, ์๋๋ผ๋ฉด ๊ฑฐ์ ํ๋๋ก ๋ง๋ค์ด์ค ๋ถ๋ถ์ด๋ค.
๊ฐ๋จํ๊ฒ ์๊ฐํ๋ฉด ์ ์ํ fileSize์ maxHistory์ ๋ฐ๋ผ์ ์๋ก์ด ๋ก๊ทธ ํ์ผ์ด ์์ฑ๋๋๋ก ์ ์ํ๋ ๋ถ๋ถ์ด๋ค.
๊ทธ๋ฆฌ๊ณ , ์๋ก์ด ๋ก๊ทธํ์ผ์ _0, _1์ด๋ผ๋ postfix์ ํจ๊ป ๊ณ์ ์์ฑ๋๊ฒ ๋๋ค.
์ฌ๊ธฐ์ file๊ณผ fileNamePattern์ ์ ๋๋์๋ ์ถ์ ๊ฒ์ด๋ค.
์ฐ์ , rollingPolicy๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด์๋ fileNamePattern ์ต์ ์ ๊ผญ ๋ฃ์ด์ค์ผ ํ๋ค. (์๋๋ฉด ์ค๋ฅ๋จ)
ํ์ง๋ง, fileNamePattern๋ง ์ฌ์ฉํ๊ฒ ๋๋ฉด ๋กค๋ง ์ ์ฑ ์ ์ํด ์๋ก์ด ๋ก๊ทธ ํ์ผ์ด ์์ฑ๋๊ธฐ ์ , ์ฒซ ๋ฒ์งธ ํ์ผ์ ์์ฑํ ๋ ์์ ๊ฐ์ด _0๋ผ๋ postfix๊ฐ ๋ถ์ด์ ์์์ง ์๋ค.
์์จ ์ฃผ๋ ๊ฐ๋ฐ์ ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ฐธ์ ์ ์๋ค. (ํ์ฌ ๊ฐ๋ฐ ์์ค์์๋ 10MB๊ฐ ์ฑ์์ง๋ ค๋ฉด ์์ฒญ๋ ์์ฒญ์ด ๋ค์ด์์ผ ํ๊ธฐ ๋๋ฌธ์ ๋กค๋ง ์ ์ฑ ์ด ์ ์ฉ๋๋ ๊ฑด ๊ฑฐ์ ๋ณด์ง ๋ชปํ๋ค.)
๊ทธ๋์ ์ ์ญ์ ์ผ๋ก ์ฒซ ํ์ผ์ด ์์ฑ๋ ๋๋ _0์ ์ ๊ฑฐ์ํค๊ธฐ ์ํด ๋ณ๋์ file ํ๊ทธ๋ฅผ ํตํด ์ ์ํด์ฃผ์๋ค.
์๋ฌดํผ, file๋ก ์ค์ ํด์ฃผ๋ฉด ์๋ก์ด ๋ก๊ทธ ํ์ผ์ด ์์ฑ๋ ๋ _0์ ํตํด ๋ก๊ทธ ํ์ผ์ด ์์ฑ๋๋ค.
๐ฌ ๋ฃจํธ ๋ก๊ฑฐ์ ์ค์ ํด์ฃผ๊ธฐ
All loggers are descendants of the predefined root logger
๋ชจ๋ ๋ก๊ทธ์ ๊ฒฝ์ฐ ์ฌ์ ์ ์ ์๋ root logger์ ์์์ด๋ค.
์ฐ๋ฆฌ๊ฐ ์์์ ์ด์ฌํ ์ ์ํ ์ ์ฑ ์ ์ฌ์ฉํ๊ธฐ ์ํด์๋ ๋ฃจํธ ๋ก๊ฑฐ๋ฅผ ์ค์ ํด์ผ ๋๋ค๋ ๊ฒ์ด๋ค.
โญ๏ธ ๋ฃจํธ ๋ก๊ฑฐ์ ๊ฒฝ์ฐ ํ๋๋ง ์ง์ ์ด ๊ฐ๋ฅํ๋ฉฐ, ๋ค์ค์ผ๋ก ์ค์ ํ๋๋ผ๋ ๋ง์ง๋ง์ ์ ์ธํ ๊ฒ๋ง ์ฒ๋ฆฌ๋๋ค.
์ฐธ๊ณ ๋ก, ์ด ์ค์ ์ ๋นผ๋ฉด ์คํ๋ง์ ์ผค ๋ ์๋ฌด๊ฒ๋ ์ ๋ฌ๋ค.
์๋ฌดํผ! ์ต์ข ์ ์ผ๋ก ์ด๋ ๊ฒ ์งํํ๊ณ ๋๋ฉด, ๋ค์๊ณผ ๊ฐ์ด ์๋ฌ ๋ ๋ฒจ์ ๋ก๊น ์ ๋ํด์๋ง ํธํ๊ฒ ๊ด๋ฆฌํ ์ ์๊ฒ ๋๋ค.
์ด๊ฑด ์ฝ์์์ INFO ๋ ๋ฒจ ์ด์์ ๋ก๊ทธ๊ฐ ์ถ๋ ฅ๋๋ ๊ฒ์ด๊ณ !
์๋ ๊ฒ ํ์ผ๋ก๋ ํ์ธ์ด ๊ฐ๋ฅํ๊ฒ ๋๋ค ๐
๊ฝค๋ ์ฌ๋ฐ์๋ ์ฝ์ง์ด์๋ค~~!