每个线程

时间:2016-06-08 22:48:10

标签: logging concurrency routing log4j2

我使用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个文件。我想这可能是我的代码中的并发问题。

任何人都可以帮助我?

1 个答案:

答案 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,而不仅仅是信息。