我使用log4j 2,我需要根据存储在ThreadContext Map中的特定键的值来编写不同的日志文件。每个线程将键设置为特定值(可以重复...)。 这是log4j2.xml
<Configuration status="warn">
<Appenders>
<Routing name="Routing">
<Routes pattern="$${ctx:KEY}">
<Route>
<RollingFile name="Rolling-${ctx:KEY}" fileName="logs/${ctx:KEY}.log"
filePattern="logs/${date:yyyy-MM}/${ctx:KEY}-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout>
<pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="6"
modulate="true" />
<SizeBasedTriggeringPolicy size="10 MB" />
</Policies>
</RollingFile>
</Route>
</Routes>
</Routing>
<Async name="Async">
<AppenderRef ref="Routing" />
</Async>
</Appenders>
<Loggers>
<Root level="info" additivity="false">
<AppenderRef ref="Async" />
</Root>
</Loggers>
</Configuration>
这是Main类:
public class TestClass {
public static void main (String[] args){
/**FILTER OPERATION*/
CorrelationBag corr = new CorrelationBag();
corr.setID("AD65MASDAD654DF5SDF235SFD651SDFSDF321DSF");
corr.setUsername("Username");
for (int i= 0; i<6; i++){
(new Thread(new MyService(i))).start();
}
}
}
这最终是线程实现:
public class MyService extends ServiceBase implements Runnable {
int counter;
public MyService (){}
public MyService (int counter){
this.counter = counter;
}
@Override
public void run() {
ThreadContext.put("KEY", Thread.currentThread().getID());
String param1 = "param1";
String param2 = "param2";
String param3 = "param3";
String param4 = "param4";
String param5 = "param5";
info("WITH MARKER AND HEADERS,{},{}{},{},{}",param1,param2,param3,param4,param5);
ThreadContext.remove("threadName");
}
}
使用此代码,Log4j只创建1个与1个线程ID相关的日志文件。
如果我在调试模式下运行代码,逐步执行每一条指令... log4j会根据需要创建6个文件。我想这可能是我的代码中的并发问题。
任何人都可以帮助我?
答案 0 :(得分:1)
您当前的代码有可能在创建下一个线程之前创建,开始和完成每个线程,因此线程对象可能会被重用。我建议你改变你的代码:
Thread[] threads = new Thread[6];
for (int i= 0; i < 6; i++) {
threads[i] = new Thread(new MyService(i));
}
for (int i= 0; i < 6; i++){
threads[i].start();
}
此外,您已添加&#34; KEY&#34;到线程上下文但删除&#34; threadName&#34;。这将导致问题。您上面的示例实际上也没有记录器调用。我假设它应该是logger.info,而不仅仅是信息。