2015-10-05 77 views
1

我正在將我的應用程序從log4j遷移到log4j2。請在下面的應用程序當前線程中輸入需要輸入的類(例如模式爲mode1),並將其附加到日誌文件名(例如log_mode1.log)並創建appender並更新日誌文件。如何在log4j2中實現多文件appender

類:

public class MultiFileAppender extends AppenderSkeleton { 
    ... 

@Override 
    protected void append(LoggingEvent event) { 
    ... 
} 
@Override 
    public void close() { 
} 
@Override 
    public boolean requiresLayout() { 
    ... 
} 
} 

中的log4j.xml Appender的內容:

<appender name="TEST_MULTIFILE" class="com.test.it.logging.MultiFileAppender"> 
<param name="File" value="${LOGS}/test/test_%id%.log"/> 
<param name="Append" value="true"/> 
<param name="MaxFileSize" value="500KB"/> 
<param name="MaxBackupIndex" value="5"/> 
<param name="Encoding" value="UTF-8"/> 
</appender> 

如何獲得在Java中這些參數,創建多文件的appender像log4j2上面的配置?請幫忙。謝謝。

+0

請問這個'MultiFileAppender'的目的是什麼?按照名稱,聽起來好像您要將相同的日誌條目寫入多個文件。如果是這樣,你不需要一個自定義類來完成它,它可以通過在log4j和log4j2中配置標準appender來完成。但是,也許你有一個無法解決的特殊要求? –

+0

非常感謝回覆。有不同的模式(比如mode1,mode2,mode3 ..)將從當前正在運行的線程中獲取,並且日誌內容將轉到名稱中包含模式(例如test_mode1.log)的相應日誌文件。 – sridhar

+0

您可以根據模式創建不同的Logger對象名稱,並使用它來控制將日誌語句寫入哪個文件?如果您通常使用'LogManager.getLogger()'獲取名爲'my.package.Test'的記錄器,則可以執行LogManager.getLogger(Test.class.getName()+「.mode1」)'來獲取一個名爲logger 'my.package.Test.mode1'等等。 –

回答

1

採取以下方案:

一個類實例化了幾次,每個實例都有一個不同的id。記錄相應的ID應該到它自己的文件。每個ID有一個文件。編寫代碼時不知道id的值(它當然是在本例中編寫Main類時)。

public class Test implements Runnable { 
    private static final Logger LOG = LogManager.getLogger(); 
    private final String id; 

    public Test(String id) { 
     this.id = id; 
    } 

    @Override 
    public void run() { 
     ThreadContext.put("id", id); //org.apache.logging.log4j.ThreadContext 
     while (true) { 
      try { Thread.sleep(10000); } catch (InterruptedException e) { break; } 
      LOG.info("{}: I have been sleeping for 10 seconds", id); 
     } 
    } 
} 

public class Main { 
    private static final Logger LOG = LogManager.getLogger(); 

    public static void main(String[] args) { 
     LOG.info("Starting thread 1"); 
     Thread t1 = new Thread(new Test("mode1")); 
     t1.start(); 
     LOG.info("Starting thread 2"); 
     Thread t2 = new Thread(new Test("mode2")); 
     t2.start(); 
     LOG.info("Starting thread 3"); 
     Thread t3 = new Thread(new Test("mode3")); 
     t3.start(); 
    } 
} 

以下是log4j2配置。

<?xml version="1.0" encoding="UTF-8"?> 
<Configuration status="warn"> 
    <Appenders> 
     <Routing name="Routing"> 
      <Routes pattern="$${ctx:id}"> 
       <!-- If a special id should be treated differently 
       <Route key="mymode"> 
        ... 
       </Route> --> 
       <!-- Threads that don't have the id value set --> 
       <Route key="$${ctx:id}"> 
        <File name="File" 
          fileName="normal.log"> 
         <PatternLayout pattern="%d{HH:mm:ss} [%p] %c %msg%n" /> 
        </File> 
       </Route> 
       <!-- Threads with the id value set, and is not one of the special ones above --> 
       <Route> 
        <File name="File-${ctx:id}" 
          fileName="id-${ctx:id}.log"> 
         <PatternLayout pattern="%d{HH:mm:ss} [%p] %c %msg%n" /> 
        </File> 
       </Route> 
      </Routes> 
     </Routing> 
    </Appenders> 
    <Loggers> 
     <Root level="info"> 
      <AppenderRef ref="Routing" /> 
     </Root> 
    </Loggers> 
</Configuration> 

這個想法是從log4j2 FAQ拍攝。另見Lookups


如果您仍然需要得到您的自定義的appender與log4j2工作,也許this question with answer爲您提供如何進行一些很好的提示。

+0

感謝您的迴應..羅傑。但是,模式是動態的而不是常量。這些值是從當前正在運行的線程獲得的。因此,模式被用作log42中的佔位符或變量。在appender定義中的xml,並需要在java中替換並創建一個appender日誌文件。 – sridhar

+0

還有另一種方法,我會很快更新我的答案。 –

+0

非常感謝..羅傑 – sridhar

相關問題