我正在運行一個Java應用程序,其中我調用多個線程,每個線程都有一些唯一的名稱。現在我想爲它們中的每一個創建多個日誌文件,並且日誌文件的名稱應該作爲線程名稱。這可能使用log4j2。請幫我寫log4j2配置文件。使用log4j2的多線程的不同日誌文件
預先感謝您。
我正在運行一個Java應用程序,其中我調用多個線程,每個線程都有一些唯一的名稱。現在我想爲它們中的每一個創建多個日誌文件,並且日誌文件的名稱應該作爲線程名稱。這可能使用log4j2。請幫我寫log4j2配置文件。使用log4j2的多線程的不同日誌文件
預先感謝您。
這可以通過RoutingAppender完成。常見問題頁面有一個很好的示例配置。
我同意一個RoutingAppender是要走的路。我最初將路由appender與$ {ctx:threadName}查找結合使用,其中'ctx'使用ThreadContext。我發現,我會在代碼中灑這樣一行:
ThreadContext.put("threadName", Thread.currentThread().getName());
雖然該代碼的工作是不是在代碼的設計可擴展性。如果我要在代碼庫中添加新的java.lang.Runnable
,那麼我還必須包含該行。
相反,解決方案似乎是實施 'org.apache.logging.log4j.core.lookup.StrLookup',並與PluginManager
像這樣註冊@Plugin
:
類:ThreadLookup
package my.logging.package
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.lookup.StrLookup;
@Plugin(name = "thread", category = StrLookup.CATEGORY)
public class ThreadLookup implements StrLookup {
@Override
public String lookup(String key) {
return Thread.currentThread().getName();
}
@Override
public String lookup(LogEvent event, String key) {
return event.getThreadName() == null ? Thread.currentThread().getName()
: event.getThreadName();
}
}
配置:log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" packages="my.logging.package">
<Appenders>
<Routing name="Routing">
<Routes pattern="$${thread:threadName}">
<Route>
<RollingFile name="logFile-${thread:threadName}"
fileName="logs/concurrent-${thread:threadName}.log" filePattern="logs/concurrent-${thread:threadName}-%d{MM-dd-yyyy}-%i.log">
<PatternLayout pattern="%d %-5p [%t] %C{2} - %m%n" />
<Policies>
<SizeBasedTriggeringPolicy size="50 MB" />
</Policies>
<DefaultRolloverStrategy max="100" />
</RollingFile>
</Route>
</Routes>
</Routing>
<Async name="async" bufferSize="1000" includeLocation="true">
<AppenderRef ref="Routing" />
</Async>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="async" />
</Root>
</Loggers>
0123(該
Configuration
的
packages
屬性與
PluginManager
註冊
@Plugin
)
我認爲RoutingAppender適用於我們有一些先前定義的記錄器,並且動態地選擇我們想要轉儲日誌的記錄器。但在我的情況下,我必須爲每個線程創建多個記錄器,並且日誌文件名將基於線程調用時間和進程ID或線程名稱等。請幫助我解決這個問題。如果這可以使用RoutingAppender來完成,那麼給出一些提示來繼續。 謝謝 – user1890780
說實話,你的要求聽起來很複雜。有沒有更簡單的方法?但是,假設您無法控制設計,我仍然認爲您可以按照您對RoutingAppender的描述進行操作。請再次查看FAQ中的RoutingAppender示例。最後一個Route使用基於ThreadContext值的名稱動態創建一個日誌文件。 ThreadContext映射具有線程本地值,因此每個線程都可以根據您提到的方面(時間,pid,tid)放置一些值。這個值然後成爲文件名的一部分,所以你得到一個單獨的日誌文件。 –