我使用Log4j 2中的Routing功能在运行时动态创建appender。当我知道那些appender已经完成时,我想告诉Log4j以便它可以整理相关资源(刷新和关闭文件,释放与这些appender相关的内部对象等)。如果不这样做,Log4j仍然具有打开的文件句柄,并且我无法操纵它所写的文件(来自对后处理和归档日志的外部进程)。
如何告诉Log4j一个appender不会再次使用?
我包含我的Log4j配置以确保完整性。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %level{ERROR=!, WARN=?, INFO=-, DEBUG=., TRACE=.} %msg%n"/>
</Console>
<Routing name="MatchLogs">
<Routes pattern="$${ctx:matchID}">
<Route>
<RandomAccessFile name="MatchLog-${ctx:matchID}" fileName="logs/${ctx:matchID}.log">
<PatternLayout pattern="%d{ISO8601} %-5level %-30.30logger{1} %msg%n"/>
</RandomAccessFile>
</Route>
</Routes>
</Routing>
<Async name="AsyncWrapper">
<AppenderRef ref="MatchLogs" level="debug"/>
<AppenderRef ref="Console" level = "info"/>
</Async>
<Routing name="MatchStatsLogs">
<Routes pattern="$${ctx:matchID}">
<Route>
<RandomAccessFile name="MatchStatsLog-${ctx:matchID}" fileName="logs/${ctx:matchID}_stats.log">
<PatternLayout pattern="%msg"/>
</RandomAccessFile>
</Route>
</Routes>
</Routing>
<Async name="AsyncStatsWrapper">
<AppenderRef ref="MatchStatsLogs" level="debug"/>
</Async>
</Appenders>
<Loggers>
<Logger name="stats" level="trace" additivity="false">
<AppenderRef ref="AsyncStatsWrapper"/>
</Logger>
<Root level="debug">
<AppenderRef ref="AsyncWrapper"/>
</Root>
</Loggers>
</Configuration>
当比赛开始时,我从该比赛中涉及的每个线程中调用ThreadContext.put("matchID", theMatchID);
。比赛结束后,我清除ThreadContext
。显然,Log4j并不足以知道我不会重复使用该匹配ID,因此它会使Appender保持不变。但是,我知道我不会重复使用匹配ID,所以如何告诉Log4j整理?
答案 0 :(得分:1)
Log4J尚未提供该功能。您可能希望在Log4J2问题跟踪器(https://issues.apache.org/jira/browse/LOG4J2)中提出功能请求。