Spring - SlF4j / Logback & Log4j2
๐Log๋ ๋ฌด์์ธ๊ฐ?
๋ก๊ทธ๋ ์ํํธ์จ์ด ์ด๋ฒคํธ๋ฅผ ์์คํ ์ ์ํ ๋ฐ ๋์ ์ ๋ณด๋ฅผ ์๊ฐ ๊ฒฝ๊ณผ์๋ฐ๋ผ ๊ธฐ๋กํ๋ ๊ฒ์ด๋ค. ์ํํธ์จ์ด ๊ฐ๋ฐ ๊ณผ์ ํน์ ๊ฐ๋ฐ ํ ๋์์ํ๋ฅผ ํ์ ํ์ฌ ๋ฌธ์ ์ง๋จ ๋ฐ ํด๊ฒฐ์ ๋์์ ์ค๋ค. ์ด์๊ณผ ๊ด๋ฆฌ์ ๋์์ ์ฃผ๋ ์ข์ ๋ฐ์ดํฐ๊ฐ ๋ ์์๋ค. ๋ก๊ทธ๋ฅผ ๊ธฐ๋กํ๋ ํ์๋ฅผ ๋ก๊น (logging)์ด๋ผ๊ณ ํ๋ฉฐ JAVA ์์๋ ๋ค์ํ ๋ก๊น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ง์ํ๋ค. ํ์ง๋ง ๊ฐ๊ฐ ๋ก๊น ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ด๋ถ๋์์ ์ดํดํ์ง ๋ชปํ๋ฉด ์ฑ๋ฅ์ ์ด์๊ฐ ๋ฐ์ํ ์ ์๊ธฐ๋๋ฌธ์ ๋ด๋ถ๋์์ ์ดํดํ๋๊ฒ์ด ์ค์ํ๋ค.
๋๋ฒ๊น ์ด๋ System.out.println ์ด๋ ๋น๊ตํ์๋ ๋ก๊น ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์ฅ์
- ์ํฉ๋ณ Log Level ์ ์ง์ ํด Level ๋ณ๋ก ๋ก๊น ์ด ๊ฐ๋ฅํ๋ค
- ํ๋ก๊ทธ๋จ ์คํ์ ๋ํ ํ๋ฆ๊ณผ ์๋ฌ ํ์ธ๊ฐ๋ฅ
- sysout ์ ๋นํด ํ์ผ,ํด๋ผ์ฐ๋,DB ๋ฑ ์ถ๋ ฅ ์์น ๋ฐ ๋ค์ํ ์ถ๋ ฅ ํ์ ์ง์
- ๋ชจ๋,ํ์ผ,๋ฉ์๋,ํด๋์ค๋ณ๋ก ์ ์ฐํ๊ฒ ๋ฉ์ธ์ง ์ถ๋ ฅ ๊ฐ๋ฅ
๋ก๊น ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ข ๋ฅ
- java.util.logging.Logger
- Log4j,Log4j2
- LogBack
- SLF4j
-> ์๋ฐ์์๋ Log4j -> Logback -> Log4j2 ์๊ฐ ์์ผ๋ก ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๊ฐ๋ฐ๋จ
Log Level ๋ณ ์ผ๋ฐ์ ์ธ ์ฉ๋ ( ํ์ด๋ ํ์ฌ์ ๊ท์น์ ๋ฐ๋ฅผ์๋์์ )
- ๐Trace : ๊ฐ์ฅ ์์ธํ ๋ก๊ทธ ๋ ๋ฒจ๋ก,์ฝ๋์ ํ๋ฆ์ ๋ฐ๋ผ๊ฐ๋ฉฐ ๋๋ฒ๊น ์ ๋ณด๋ฅผ ๊ธฐ๋ก
- ๐งกDebug : ๋๋ฒ๊น ์ ์ํ ๋ก๊ทธ ๋ ๋ฒจ๋ก, ํ๋ก๊ทธ๋จ์ ์ํ ๋ฐ ์คํ์ค์ ๋ฐ์ํ๋ ์ค์ํ ์ด๋ฒคํธ๋ฅผ ๊ธฐ๋ก
- ๐Info : ์ผ๋ฐ์ ์ธ ์ ๋ณด๋ฅผ ๊ธฐ๋กํ๋ ๋ก๊ทธ ๋ ๋ฒจ๋ก, ํ๋ก๊ทธ๋จ์ ์ฃผ์ ์ด๋ฒคํธ ๋ฐ ์ํ ๋ณ๊ฒฝ์ ๊ธฐ๋ก / ์๋ฌ๋ ์๋์ง๋ง ์ฃผ์ํด์ผ ํ ๊ฒ์ ๊ธฐ๋ก
- ๐Warning : ์์ธ์ ์ธ ์ํฉ์ ๊ธฐ๋กํ๋ ๋ก๊ทธ ๋ ๋ฒจ๋ก, ์ ์ฌ์ ์ธ ๋ฌธ์ ๋๋ ์์์ด๋ชปํ ๋์์ ๊ธฐ๋ก / ์๋ฌ๋ ์๋์ง๋ง ์์ธ์ํฉ์ธ ๊ฒฝ์ฐ๋ฅผ ๊ธฐ๋ก
- ๐Error : ์ฌ๊ฐํ ์๋ฌ๋ฅผ ๊ธฐ๋กํ๋ ๋ก๊ทธ ๋ ๋ฒจ๋ก, ์๋ชป๋ ๋์์ ๊ธฐ๋ก
- ๐Fatal : ๊ฐ์ฅ ์ฌ๊ฐํ ๋ก๊ทธ ๋ ๋ฒจ๋ก, ์ค๋ฅ๋ฅผ ๊ธฐ๋กํ๊ณ ํ๋ก๊ทธ๋จ์ ์ค๋จ ๋๋ ๋น์ ์ ์ข ๋ฃ๋ฅผ ์๋ฆผ
๐ฅ System.out.println()์ ๋ก๊น ์ ์ฌ์ฉํ๋ฉด ์์ข์ ์ด์ ๊ฐ ๋ฌด์์ผ๊น?
- sysout ์ด ๋ด๋ถ์ ์ผ๋ก ์ฌ์ฉํ๋ wirte()์ newLine()์ด ๋๊ธฐํ ๋ฉ์๋์ด๋ค
- Blocking I/O์ด๋ค ( ํด๋น I/O๊ฐ ๋ฐ์ํ๋ ์์ ์๊ฐ๋์ cpu ๊ฐ ๋๊ธฐ๋๊ธฐ ๋๋ฌธ)
- ์ฆ ์ฑ๋ฅ์ ์ข์ง ์๋ค.
๐SLF4J ( Simple Logger Facade For Java)
SLF4J๋ java.util.logging, logback ๋ฐ log4j์ ๊ฐ์ ๋ค์ํ ๋ก๊น ํ๋ ์ ์ํฌ์ ๋ํ ์ถ์ํ(์ธํฐํ์ด์ค) ์ญํ ์ ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. logger ์ ์ถ์์ฒด๋ก์จ, ์ธํฐํ์ด์ค ์ด๋ฏ๋ก SLF4j ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํด์ ๋ก๊น ํ๊ฒ ๋๋ฉด ๊ตฌํ์ฒด๋ง ๊ฐ์ ๋ผ์ฐ๋ฉด logback์ด๋ log4j๋ฑ์ผ๋ก ๋ง์ด๊ทธ๋ ์ด์ ํ ์ ์์ต๋๋ค. ๊ตฌํ์ฒด๋ก๋ logback, log4j2 ๋ฑ์ด ์์ต๋๋ค.
SLF4J์ ๊ตฌ์ฑ์์
SLF4J๋ ์ธ๊ฐ์ง์ ๊ตฌ์ฑ์์๋ฅผ ๊ฐ๋๋ค.
- SLF4J API
- SLF4J๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณต - slf4j-api-{version}.jar ๋ฅผ ํตํด ์ฌ์ฉ - ๋ฐ๋์ ํ๋์ ๋ฐ์ธ๋ฉ๋ง์ ์ฌ์ฉํด์ผํ๋ค ( ์๋๋ฉด ์๋ฌ๋จ )
- SLF4J๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ ๊ณต - slf4j-api-{version}.jar ๋ฅผ ํตํด ์ฌ์ฉ - ๋ฐ๋์ ํ๋์ ๋ฐ์ธ๋ฉ๋ง์ ์ฌ์ฉํด์ผํ๋ค ( ์๋๋ฉด ์๋ฌ๋จ )
- SLF4J ๋ฐ์ธ๋ฉ
- SLF4J ์ธํฐํ์ด์ค๋ฅผ ๋ก๊น
๊ตฌํ์ฒด ( logback ๋๋ log4j ) ์ ์ฐ๊ฒฐํ๋ ์ด๋ํฐ ์ญํ
- SLF4J ์ธํฐํ์ด์ค๋ฅผ ๋ก๊น
๊ตฌํ์ฒด ( logback ๋๋ log4j ) ์ ์ฐ๊ฒฐํ๋ ์ด๋ํฐ ์ญํ
- SLF4J Bridging Modules
- ๋ค๋ฅธ ๋ก๊น
API ๋ก Logger ํธ์ถ์ ํ ๋, SLF4J ์ธํฐํ์ด์ค๋ก ์ฐ๊ฒฐ ( redirect ) ํ์ฌ SLF4J API ๊ฐ ๋์ Logger ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋๋ก ํ๋ ์ด๋ํฐ ์ญํ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ๋ค๋ฅธ ๋ก๊น API ==> Bridge(redirect) ==> SLF4J API
- ๋ค๋ฅธ ๋ก๊น
API ๋ก Logger ํธ์ถ์ ํ ๋, SLF4J ์ธํฐํ์ด์ค๋ก ์ฐ๊ฒฐ ( redirect ) ํ์ฌ SLF4J API ๊ฐ ๋์ Logger ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋๋ก ํ๋ ์ด๋ํฐ ์ญํ ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
๐LogBack
- logback ์ด๋ log4j ์ดํ์ ๋์์ผ๋ฉฐ log4j ๋ณด๋ค ํฅ์๋๊ณ ๊ฐ์ฅ ๋๋ฆฌ ์ฌ์ฉ๋๊ณ ์๋ Java ๋ก๊น ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ๋๋ค.
- slf4j์ ๊ตฌํ์ฒด๋ก์จ ์คํ๋ง๋ถํธ์ ๊ธฐ๋ณธ log๋ก ์ฌ์ฉ๋๊ณ ์์ผ๋ฉฐ spring-boot-starter-web ์์ spring-boot-starter-logging์ logback์ด ๊ธฐ๋ณธ์ ์ผ๋ก ๋ด์ฅ๋์ด์์ด ๋ฐ๋ก ์ถ๊ฐํด์ค ํ์์๋ค.
- Automatic Reloading ๊ธฐ๋ฅ์ ์ ๊ณตํ์ฌ ๋ฐ๋ก ์ฌ์์์์ด ์ค์ ๋ณ๊ฒฝํ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค
์คํ๋ง๋ถํธ์์์ ์ฌ์ฉ์์
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
class LogbackLogger {
private static Logger logger = LoggerFactory.getLogger(LogbackLogger.class);
void method() {
logger.trace("Trace");
logger.debug("Debug");
logger.info("Info");
logger.warn("Warn");
logger.error("Error");
}
}
๐Log4j2
- Log4j2๋ Log4j๋ฅผ ๋ณด์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ Facade ํจํด์ผ๋ก ๊ตฌํ๋์ด ๋ค๋ฅธ Log ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค๊ณผ ์ฌ์ฉํ ์ ์์ต๋๋ค. ๊ทธ ์๋ก LogBack์ ์์์ Facade ํํ๋ก ์ฌ์ฉ๋์ด์ง ์ ์์ต๋๋ค.
- Log4j2์ ๊ฐ์ฅ ๋์ ๋๋ ๊ธฐ๋ฅ์ ๋น๋๊ธฐ ์ฑ๋ฅ ์ ๋๋ค ๋ํ LMAX ๋์ค๋ฝํฐ๋ฅผ ํ์ฉ ํ๋๋ฐ ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์ธํด 12๋ฐฐ ๊ฐํ ์ฑ๋ฅ์ ์ ๊ณตํ๋ค.
- ๋์ผ ํ๊ฒฝ์์ Log4j2๋ ์ด๋น 18,000,000๊ฐ์ ๋ฉ์ธ์ง๋ฅผ ๊ธฐ๋กํ ์ ์๋ ๋ฐ๋ฉด Logback๊ณผ Log4j๋ 1์ด๋น 2,000,000 ๊ฐ ๋ฏธ๋ง์ ๋ฉ์ธ์ง๋ฅผ ๊ธฐ๋ก ํ ์ ์๋ค.
- ์ฌ์ฉ์ ์ํด์๋ spring-boot-starter-logging ๋ชจ๋์ excludeํ๊ณ spring-boot-starter-logging-log4j2์ ์์กด์ฑ์ ์ฃผ์ ํด์ผ ํ๋ค
- ๋ฉํฐ ์ฐ๋ ๋ ํ๊ฒฝ์์ ์ฑ๋ฅ์ด ์ฐ์ํ๋ค.
๐Log4j2 - AsyncLogger
๊ณต์๋ฌธ์์ ์ํ๋ฉด ์ค๋ ๋๊ฐ ๋์ด๋จ์ ๋ฐ๋ผ ๋ ์ข์์ฑ๋ฅ์ ๋ณด์ด๋ ๋น๋๊ธฐ๋ก๊ฑฐ ์ฌ์ฉ์ ๊ถ์ฅํ๋ค.
๊ทธ๋ฌ๋ ๋ฌด์กฐ๊ฑด ๋น๋๊ธฐ ๋ก๊ฑฐ๊ฐ ์ข์ ๊ฒ์ ์๋๋ค.
์ฅ์
- ๋๊ธฐ ๋ก๊ฑฐ์ ๋นํด 6~68๋ฐฐ ๋น ๋ฅด๋ค
- ๋์ฉ๋ ๋ก๊น ์ ์ ํฉํ๋ค ( ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ๊ธฐ๋๋ฌธ )
๋จ์
- ์ฒ๋ฆฌ ๊ณผ์ ์ ์์ธ๊ฐ ๋ฐ์ํ์ฌ ๋ก๊น ์ ์คํจํ๊ฒฝ์ฐ ๋น๋๊ธฐ๋ก ์ฒ๋ฆฌํ๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ์ํฉ์ ์๋ฆฌ๊ธฐ ํ๋ค๋ค.
- ์๋ก์ด ์ค๋ ๋๋ฅผ ๊ณ์ ์์ฑํ๋ฏ๋ก CPU ์์์ด ๋ถ์กฑํ ํ๋์จ์ด์์๋ ์ฑ๋ฅ์ด์ ์ด ์์ ์ ์๋ค.
๐๋๊ธฐ + ๋น๋๊ธฐ ๋ฐฉ์์ ์ฌ์ฉํ์ ( Async + Sync Logger )
1
2
3
4
5
6
7
8
9
10
11
12
13
Configuration:
Loggers:
Root:
level: info
AppenderRef:
- ref: RollingFile_Appender
AsyncLogger:
name: asyncLogger
additivity: false
level: debug
includeLocation: false
AppenderRef:
- ref: RollingFile_Appender
๐๋ฌด์์ ์ฌ์ฉํด์ผํ ๊น?
- ๋ก๊น ํด์ผ ํ ์์ด ๋ง๊ณ ์ฑ๋ฅ์ด ์ค์ํ๋ค๋ฉด Log4j2๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค
- Logback,Log4j2 ๋ ๋ค SLF4j๋ฅผ ๊ตฌํํ๊ณ ์๊ธฐ ๋๋ฌธ์ ๊ต์ฒดํ๊ธฐ์ ํธ๋ฆฌํ๋ค -> ( ๋ด๋ถ์ ์ธ ์ฝ๋๋ฅผ ๋ณ๊ฒฝํ์ง์๊ณ dependency ๋ง ๊ต์ฒดํด์ฃผ๋ฉด๋๊ธฐ ๋๋ฌธ)
- ๋น๋๊ธฐ ๋ก๊ฑฐ๋ ์์๊ฐ ์ค์ํ์ง ์๊ณ ๋ฐฉ๋ํ ๋ก๊ทธ๋ฅผ ์์ฑํด์ผ ํ ๋ ์ฌ์ฉํ๋ฉด ์ข์๊ฒ๊ฐ๋ค.
- ๋๊ธฐ ๋ก๊ฑฐ๋ ์ฝ๋์ ๋์ ์์๊ฐ ์ค์ํ ๋ ( ๋๋ฒ๊น ์ฉ ) ์ฌ์ฉํ๋ฉด ์ข์๊ฒ๊ฐ๋ค.