ํฌ์ŠคํŠธ

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 ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋กœ๊น… ๊ตฌํ˜„์ฒด ( logback ๋˜๋Š” log4j ) ์™€ ์—ฐ๊ฒฐํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ ์—ญํ• 
  • SLF4J Bridging Modules
    • ๋‹ค๋ฅธ ๋กœ๊น… API ๋กœ Logger ํ˜ธ์ถœ์„ ํ•  ๋•Œ, SLF4J ์ธํ„ฐํŽ˜์ด์Šค๋กœ ์—ฐ๊ฒฐ ( redirect ) ํ•˜์—ฌ SLF4J API ๊ฐ€ ๋Œ€์‹  Logger ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ์–ด๋Œ‘ํ„ฐ ์—ญํ• ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
      • ๋‹ค๋ฅธ ๋กœ๊น… API ==> Bridge(redirect) ==> SLF4J API

๐Ÿ“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 ๋งŒ ๊ต์ฒดํ•ด์ฃผ๋ฉด๋˜๊ธฐ ๋•Œ๋ฌธ)
  • ๋น„๋™๊ธฐ ๋กœ๊ฑฐ๋Š” ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ•˜์ง€ ์•Š๊ณ  ๋ฐฉ๋Œ€ํ•œ ๋กœ๊ทธ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ• ๋•Œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„๊ฒƒ๊ฐ™๋‹ค.
  • ๋™๊ธฐ ๋กœ๊ฑฐ๋Š” ์ฝ”๋“œ์˜ ๋™์ž‘ ์ˆœ์„œ๊ฐ€ ์ค‘์š”ํ• ๋•Œ ( ๋””๋ฒ„๊น…์šฉ ) ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„๊ฒƒ๊ฐ™๋‹ค.
์ด ๊ธฐ์‚ฌ๋Š” ์ €์ž‘๊ถŒ์ž์˜ CC BY 4.0 ๋ผ์ด์„ผ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.