IT/development

[์ „์ž์ •๋ถ€ํ”„๋ ˆ์ž„์›Œํฌ/egovframework] log4j 2 ์„ค์ •(log4j2.xml ๋“ฑ)

์•Œ ์ˆ˜ ์—†๋Š” ์‚ฌ์šฉ์ž 2022. 11. 24.

    egovframework log4j 2 ์„ค์ •๐Ÿง‘

    log4j 2๋Š” ๊ธฐ์กด Properties ํŒŒ์ผ ํ˜•์‹์˜ ํ™˜๊ฒฝ ์„ค์ •์„ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฉฐ, XML(log4j2.xml) ํ˜น์€ JSON(log4j2.json or log4j2.jsn) ํŒŒ์ผ ํ˜•์‹์˜ ํ™˜๊ฒฝ ์„ค์ •๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

    Log4j2 xml configuration๐Ÿ‘ง

    Xml ํŒŒ์ผ(log4j 2.xml)์„ ์ž‘์„ฑํ•˜๊ณ , WEB-INF/classes ํ•˜์œ„์— ํฌํ•จ ๋  ์ˆ˜ ์žˆ๋„๋ก ์œ„์น˜์‹œํ‚ด

    Log4j 2๊ฐ€ ์ดˆ๊ธฐํ™”๋  ๋•Œ ์ž๋™์œผ๋กœ ์œ„ ์„ค์ • ํŒŒ์ผ์„ ์ฝ์Œ.

    XML ํŒŒ์ผ ์ •์˜

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
     
     <!-- Appender, Layout ์„ค์ • -->
     <Appenders>
      <Console name="console" target="SYSTEM_OUT">
       <PatternLayout/>
      </Console>
      <!-- ๋กœ๊ทธ๋ฅผ ํŒŒ์ผ๋กœ ๋‚จ๊น€-->
      <File name="file" fileName="./logs/file/sample.log" append="false">
       <PatternLayout pattern="%d %5p [%c] %m%n"/>
      </File>
     </Appenders>
     
     <!-- Logger ์„ค์ • -->
     <Loggers>
      <Logger name="egovLogger" level="DEBUG" additivity="false">
       <AppenderRef ref="console"/>
       <AppenderRef ref="file"/>
      </Logger>
      <Rootlevel="ERROR">
       <AppenderRef ref="console"/>
      </Root>
     </Loggers>
     
    </Configuration>

    Logger ์„ค์ •๐Ÿ‘ฉ‍๐Ÿฆฐ

    Logger๋Š” ๋กœ๊น… ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” Log4j ์ฃผ์ฒด๋กœ, Logger ์„ค์ •์„ ์ œ์™ธํ•œ ๋ชจ๋“  ๋กœ๊น… ๊ธฐ๋Šฅ์ด ์ด Logger๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌ๋จ.

    ๊ฐœ๋ฐœ์ž๋Š” ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์—์„œ ์‚ฌ์šฉํ•  Logger๋ฅผ ์ •์˜ํ•ด์•ผ ํ•˜๋ฉฐ, Log Level๊ณผ Appender ์„ค์ •์— ๋”ฐ๋ผ ์ถœ๋ ฅ ๋Œ€์ƒ๊ณผ ์œ„์น˜๊ฐ€ ๊ฒฐ์ •๋จ

    Logger ์„ ์–ธ๊ณผ ์ •์˜

    Root Logger๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  Logger๋Š” ์ƒ์œ„ ์š”์†Œ์ธ <Loggers> ์•„๋ž˜์— ์„ ์–ธํ•ด์•ผ ํ•จ.

    <Loggers>
      <Logger>...</Logger>
      <Root>...</Root>
     </Loggers>

    Root Logger๋Š” <Root> ์š”์†Œ๋กœ, ์ผ๋ฐ˜ Logger๋Š” <Logger> ์š”์†Œ๋กœ ๋ถ„๋ฅ˜ํ•ด์„œ ์ •์˜ํ•œ๋‹ค.
    Logger๋Š” ํ•˜๋‚˜ ์ด์ƒ ์ •์˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, Root ์š”์†Œ๋ฅผ ๋ฐ˜๋“œ์‹œ ์ •์˜ํ•ด์•ผํ•œ๋‹ค.

     <Loggers>
      <!-- attribute: name(Logger๋ช…), level(Log Level), additivity(์ค‘๋ณต๋กœ๊น…์—ฌ๋ถ€, true or false) -->
      <!-- element: AppenderRef(Appender๋ช…) -->
      <Logger name="X.Y" level="INFO" additivity="false">
       <AppenderRef ref="console"/>  
      </Logger>
      <Logger name="X" level="DEBUG" additivity="false">
       <AppenderRef ref="console"/>  
      </Logger>
      <Rootlevel="ERROR">
       <AppenderRef ref="console"/>
      </Root>
     </Loggers>

    ์œ„์—์„œ AppenderRef ์š”์†Œ์— ์ง€์ •ํ•œ "console" Appender๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ, ์ •์ƒ์ ์ธ ๋กœ๊น…์ด ์ˆ˜ํ–‰๋  ์ˆ˜ ์—†์Œ.

    Logger ํ˜ธ์ถœ

    Logger๋Š” ์ฝ”๋“œ ๋‚ด์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ฐฉ๋ฒ•์œผ๋กœ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ์Œ.

      // ์˜ˆ์‹œ
      package egovframe.sample;
     
      import org.apache.logging.log4j.LogManager;
      import org.apache.logging.log4j.Logger;
     
      public class LoggerTest {
     
       // (1) Logger Name์ด "egovframe.sample.LoggerTest"์ธ Logger ์„ค์ •์„ ๋”ฐ๋ฅด๋Š” Logger ๊ฐ์ฒด ์ƒ์„ฑ
       Logger logger1 = LogManager.getLogger();     
       // (2) ์œ„์™€ ๋™์ผ             
       Logger logger2 = LogManager.getLogger(LoggerTest.class);  
       // (3) Logger Name์ด "X"์ธ Logger์„ค์ •์„ ๋”ฐ๋ฅด๋Š” Logger ๊ฐ์ฒด ์ƒ์„ฑ
       Logger logger3 = LogManager.getLogger("X");   
     
      }

    (1), (2)๊ณผ ๊ฐ™์ด Logger Name์— ํ•ด๋‹นํ•˜๋Š” Logger๊ฐ€ ์„ค์ • ํŒŒ์ผ(log4j2.xml)์— ์—†๋Š” ๊ฒฝ์šฐ, ๋‹ค์Œ Logger Hierarchy ๊ทœ์น™์— ๋”ฐ๋ผ ๊ฒฐ์ •๋œ๋‹ค.
    ๊ฒฐ๊ณผ์ ์œผ๋กœ (1), (2)์—์„œ ์ƒ์„ฑ๋œ Logger ๊ฐ์ฒด๋Š” Root Logger ์„ค์ •์„ ๋”ฐ๋ฅธ๋‹ค.

    Logger Hierarchy

    ์‚ฌ์šฉ์ž๊ฐ€ ํ˜ธ์ถœํ•œ Logger ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค ์„ค์ •์„ ๋”ฐ๋ฅด๋Š”์ง€ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Logger Hierarchy๋ฅผ ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•œ๋‹ค.
    ๋‚ด๋ถ€์ ์œผ๋กœ ์„ค์ • ํŒŒ์ผ์— ์ •์˜๋œ ๊ฐ Logger ์„ค์ •์— ๋”ฐ๋ผ LoggerConfig ์˜ค๋ธŒ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๋ฉฐ,
    Logger Name์— ๋”ฐ๋ผ ์˜ค๋ธŒ์ ํŠธ ๊ฐ„ ๋ถ€๋ชจ-์ž์‹ ๊ด€๊ณ„๊ฐ€ ์„ฑ๋ฆฝํ•œ๋‹ค. ์ฆ‰ ๋ถ€๋ชจ Logger์˜ ์„ค์ •์„ ์ž์‹ Logger๊ฐ€ ์ƒ์†๋ฐ›๋Š”๋‹ค.
    ์˜ˆ๋ฅผ ๋“ค์–ด “X.Y” Logger์˜ ๋ถ€๋ชจ๋Š” “X”์ด๊ณ , “X” Logger์˜ ๋ถ€๋ชจ๋Š” Root Logger(์ตœ์ƒ์œ„)์ด๋‹ค.

    ๋‹ค์Œ์€ Hierarchy ๊ทœ์น™๊ณผ ์˜ˆ์‹œ์ด๋‹ค.

    1) ํ˜ธ์ถœํ•œ Logger Name๊ณผ ๋™์ผํ•œ Logger๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น Logger ์„ค์ •์„ ๋”ฐ๋ฅธ๋‹ค.
    2) ๋™์ผํ•œ Logger๋Š” ์—†์ง€๋งŒ, Parent Logger๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ฒฝ์šฐ, Parent Logger ์„ค์ •์„ ๋”ฐ๋ฅธ๋‹ค.
    3) Parent Logger๋„ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ, Root Logger ์„ค์ •์„ ๋”ฐ๋ฅธ๋‹ค.

    log level

    Log4j 2๋Š” FATAL, ERROR, WARN, INFO, DEBUG, TRACE์˜ Log Level์„ ์ œ๊ณตํ•จ.
    ๊ฐ๊ฐ trace(), debug(), info(), warn(), error(), fatal()๋ผ๋Š” ๋กœ๊น… ๋ฉ”์„œ๋“œ๋ฅผ ์ด์šฉํ•ด ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.
    ๋กœ๊ทธ ๋ ˆ๋ฒจ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค. (FATAL > ERROR > WARN > INFO > DEBUG > TRACE)

    ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ˆ˜ํ–‰ ์ค‘ Log Level์„ ๋ณ€๊ฒฝํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ ์ด ๋•Œ Logger Configuration์„ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ, Logger ์„ค์ • ์ •๋ณด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก org.apache.logging.log4j.Logger๋ฅผ org.apache.logging.log4j.core.Logger๋กœ ์บ์ŠคํŒ…ํ•ด์•ผ ํ•œ๋‹ค.

    Log Level ๋ณ€๊ฒฝํ•˜๋ ค๋ฉด ๋ณ€๊ฒฝํ•  Level๊ฐ’์„ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ setLevel() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
    setLevel() ํ˜ธ์ถœ ์ดํ›„๋ถ€ํ„ฐ Log Level์ด ๋ณ€๊ฒฝ๋˜๋ฉฐ, ์ง€์ •๋œ ๋กœ๊ทธ๋ ˆ๋ฒจ ์ดํ•˜์˜ Log Event๋Š” ๋ฌด์‹œ๋œ๋‹ค.

    // ์˜ˆ์‹œ
    package egovframe.sample;
     
     import org.apache.logging.log4j.LogManager;
     import org.apache.logging.log4j.Logger;
     
     public class LoggerTest {
      Logger logger = LogManager.getLogger(); // Root Logger ์„ค์ •์„ ๋”ฐ๋ฆ„, Log Level: ERROR
      org.apache.logging.log4j.core.Logger targetLogger = (org.apache.logging.log4j.core.Logger) logger;
     
      targetLogger.debug("๋ณ€๊ฒฝ ์ „ - debug"); // ์ถœ๋ ฅ๋จ
      targetLogger.error("๋ณ€๊ฒฝ ์ „ - error"); // ์ถœ๋ ฅ ์•ˆ๋จ
     
     
      targetLogger.setLevel(Level.DEBUG); // DEBUG, INFO, WARN, ERROR, FATAL ์ถœ๋ ฅ ๊ฐ€๋Šฅ
      targetLogger.debug("๋ณ€๊ฒฝ ํ›„ - debug"); // ์ถœ๋ ฅ๋จ
      targetLogger.error("๋ณ€๊ฒฝ ํ›„ - error"); // ์ถœ๋ ฅ๋จ	
    }

    ์ž๋ฐ”์—์„œ๋Š” C์™€ ๊ฐ™์ด ์ „์ฒ˜๋ฆฌ๊ธฐ์˜ ๊ธฐ๋Šฅ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— #ifdef DEBUG์™€ ๊ฐ™์€ ํ˜•ํƒœ์™€ ๊ฐ™์ด ๋””๋ฒ„๊น… ๋•Œ์™€ ๋ฆด๋ฆฌ์ฆˆ ๋•Œ์˜ ๋””๋ฒ„๊น…์ฝ”๋“œ๋ฅผ ๊ฐ๊ฐ ๋ณ„๋„๋กœ ์ƒ์„ฑํ•  ์ˆ˜๊ฐ€ ์—†๋‹ค. ๋”ฐ๋ผ์„œ Log4j์˜ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์€ ๋กœ๊ทธ๊ด€๋ฆฌ์— ์žˆ์–ด์„œ ์ƒ๋‹นํžˆ ํŽธ๋ฆฌํ•˜๋‹ค.

    Appender ์„ค์ •๐Ÿคด

    Appender๋Š” ๋กœ๊ทธ๊ฐ€ ์ถœ๋ ฅ๋˜๋Š” ์œ„์น˜๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.
    XXXAppender๋กœ ๋๋‚˜๋Š” ํด๋ž˜์Šค๋“ค์˜ ์ด๋ฆ„์„ ๋ณด๋ฉด, ์ถœ๋ ฅ ์œ„์น˜๋ฅผ ์–ด๋А ์ •๋„ ์ง์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

    Log4j 2๋Š” Console, File, RollingFile, Socket, DB ๋“ฑ ๋‹ค์–‘ํ•œ ๋กœ๊ทธ ์ถœ๋ ฅ ์œ„์น˜๊ณผ ๋ฐฉ๋ฒ•์„ ์ง€์›ํ•œ๋‹ค.
    ๊ธฐ์กด Log4j 1.x์™€ ํฌ๊ฒŒ ๋‹ฌ๋ผ์ง„ ์ ์€ Appender ์ข…๋ฅ˜๋ฅผ class ์†์„ฑ๊ฐ’์œผ๋กœ ๊ตฌ๋ถ„ํ•œ ๊ฒƒ๊ณผ ๋‹ฌ๋ฆฌ, Log4j 2์—์„œ๋Š” ํƒœ๊ทธ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.

    Appender ์„ ์–ธ๊ณผ ์ •์˜

    ๋ชจ๋“  Appender ์š”์†Œ๋Š” ์ƒ์œ„ ์š”์†Œ์ธ <Appenders> ์•„๋ž˜์— ์„ ์–ธํ•œ๋‹ค.

     <Appenders>
      <Console>...</Console>
      <File>...</File>
      <RollingFile>...</RollingFile>
      <JDBC>...</JDBC>
     </Appenders>

    Appender ์š”์†Œ๋Š” name ์†์„ฑ๊ฐ’์„ ๊ฐ€์ง€๋ฉฐ, name ์†์„ฑ์— Appender ์ด๋ฆ„์„ ์ง€์ •ํ•œ๋‹ค. name ์†์„ฑ๊ฐ’์€ Logger๊ฐ€ ๋กœ๊ทธ ์ถœ๋ ฅ์— ์‚ฌ์šฉํ•  Appender๋ฅผ ์ฐธ์กฐํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค. ๋˜ํ•œ Appender ์š”์†Œ์˜ ํ•˜์œ„ ์š”์†Œ๋กœ ๋กœ๊ทธ ์ถœ๋ ฅ ํŒจํ„ด์ธ Layout์„ ์ •์˜ํ•œ๋‹ค.
    ์•„๋ž˜๋Š” ConsoleAppender์™€ PatternLayout์„ ์‚ฌ์šฉํ•œ ์ƒ˜ํ”Œ์ฝ”๋“œ์ด๋‹ค.

     <Appenders>
       <Console name="console" target="SYSTEM_OUT">
        <PatternLayout /> <!-- ๋””ํดํŠธ ํŒจํ„ด ์ ์šฉ, %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n -->
      </Console>
     </Appenders>
     <Loggers>
      <Logger name="egovLogger" level="DEBUG" additivity="false">
       <AppenderRef ref="console" />
      </Logger>
      <Rootlevel="ERROR">
       <AppenderRef ref="console" />
      </Root>
     </Loggers>

    Appender ์ข…๋ฅ˜

    ConsoleAppender

    FileAppender

    RollingFileAppender

    JDBCAppender

    Layout ์„ค์ •๐Ÿ‘ฒ

    Layout์€ ๋ฐœ์ƒํ•œ ๋กœ๊ทธ ์ด๋ฒคํŠธ์˜ ํฌ๋งท์„ ์ง€์ •ํ•˜๊ณ , ์›ํ•˜๋Š” ํ˜•์‹์œผ๋กœ ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ๋‹ค.
    Appenders ์„ค์ •๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Log4j 2์—์„œ๋Š” Layout์„ class ์†์„ฑ์ด ์•„๋‹Œ ํƒœ๊ทธ๋กœ ๊ตฌ๋ถ„ํ•œ๋‹ค.

    ์ถœ๋ ฅ ํ˜•์‹์— ๋”ฐ๋ผ Layout์˜ ์ข…๋ฅ˜๊ฐ€ ๋‹ฌ๋ผ์ง€๋ฉฐ, ์•„๋ž˜์™€ ๊ฐ™์€ Layouts์„ ์ œ๊ณตํ•œ๋‹ค.

    PatternLayout ์„ ์–ธ๊ณผ ์ •์˜

    ์ฐธ์กฐ : egovframework:rte3:fdl:logging:log4j_2:์„ค์ •_ํŒŒ์ผ์„_์‚ฌ์šฉํ•˜๋Š”_๋ฐฉ๋ฒ•

     

    egovframework:rte3:fdl:logging:log4j_2:์„ค์ •_ํŒŒ์ผ์„_์‚ฌ์šฉํ•˜๋Š”_๋ฐฉ๋ฒ• [eGovFrame]

    Log4j 2๋Š” ๊ธฐ์กด Properties ํŒŒ์ผ ํ˜•์‹์˜ ํ™˜๊ฒฝ ์„ค์ •์„ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฉฐ, XML (log4j2.xml) ํ˜น์€ JSON (log4j2.json or log4j2.jsn) ํŒŒ์ผ ํ˜•์‹์˜ ํ™˜๊ฒฝ ์„ค์ •๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค. ์•„๋ž˜๋Š” XML ํŒŒ์ผ์„ ์ด์šฉํ•œ ํ™˜๊ฒฝ ์„ค์ •์— ๋Œ€ํ•ด์„œ๋งŒ

    www.egovframe.go.kr

    ๋Œ“๊ธ€