You are probably encountering https://issues.apache.org/jira/browse/LOG4J2-129. 
This has been fixed in trunk.  If you check it out and build it and then use 
2.0-beta4-SNAPSHOT as the version it should work.

Ralph


On Dec 24, 2012, at 7:48 AM, Michael Minella wrote:

> Ralph,
> 
> So we seem to be making progress.  Using the Routing appender, I am now 
> getting a log file named after one of the values I put on the ThreadContext.  
> However, it still seems to only be evaluated once.
> 
> What I currently have is a unit test that creates four threads.  In each 
> thread, I put an id on the ThreadContext and loop a number of times logging a 
> message.  The behavior I'm looking for is a log file per thread (technically 
> one per id I put on the ThreadContext) based on the id placed in the 
> ThreadContext (so for my test below, I would expect a Main.log, Thread_0.log, 
> Thread_1.log, and Thread_3.log).  What I am seeing is one file is created, 
> named after one of the threads and all of the output (regardless of the id) 
> goes to that one file.  Below are the classes/configuration involved:
> 
> UNIT TEST:
> =========================================================
> package org.somepackage.log4j;
> 
> import org.apache.logging.log4j.ThreadContext;
> import org.junit.Test;
> 
> public class Log4jThreadContextTests {
> 
>       @Test
>       public void testThreadContextLogging() throws Exception {
>               ThreadContext.put("id", "Main");
> 
>               new Thread(new BoringLoggingClass()).start();
>               new Thread(new BoringLoggingClass()).start();
>               new Thread(new BoringLoggingClass()).start();
>               new Thread(new BoringLoggingClass()).start();
> 
>               //This is needed because JUnit kills all processing once this 
> method returns.
>               Thread.sleep(2000);
>       }
> }
> 
> 
> RUNNABLE:
> =========================================================
> package org.somepackage.log4j;
> 
> import org.apache.logging.log4j.LogManager;
> import org.apache.logging.log4j.Logger;
> import org.apache.logging.log4j.ThreadContext;
> 
> public class BoringLoggingClass implements Runnable {
> 
>       private Logger logger = LogManager.getLogger(BoringLoggingClass.class);
>       private static int threadCount = 0;
> 
>       public void run() {
>               synchronized (this) {
>                       // This is to test the inheritance of a ThreadContext.  
>                       // The third thread will inherit the id Main from the 
> unit test.
>                       if(threadCount != 2) {
>                               ThreadContext.put("id", "Thread_" + 
> threadCount);
>                       }
>                       threadCount++;
>               }
> 
>               for(int i = 0; i < 1000; i++) {
>                       logger.error("I am logging: " + i);
>               }
> 
>               ThreadContext.clear();
>       }
> }
> 
> log4j.xml:
> =========================================================
> <?xml version="1.0" encoding="UTF-8"?>
> <configuration status="OFF">
>  <appenders>
>    <Console name="Console" target="SYSTEM_OUT">
>      <PatternLayout pattern="%X{id} %d{HH:mm:ss.SSS} [%t] %-5level 
> %logger{36} - %msg%n"/>
>    </Console>
>    <Routing name="Routing">
>      <Routes pattern="$${ctx:id}">
>        <Route>
>          <File name="File" fileName="/tmp/${ctx:id}.log">
>                     <PatternLayout pattern="%X{id} %d{HH:mm:ss.SSS} [%t] 
> %-5level %logger{36} - %msg%n"/>
>                 </File>
>        </Route>
>      </Routes>
>    </Routing>
> <!--     <File name="File" fileName="/tmp/$${ctx:id}.log">
>      <PatternLayout pattern="%X{id} %d{HH:mm:ss.SSS} [%t] %-5level 
> %logger{36} - %msg%n"/>
>    </File>
> -->  </appenders>
>  <loggers>
>    <root level="debug">
>      <appender-ref ref="Routing"/>
>    </root>
>  </loggers>
> </configuration>
> 
> From the above, I end up with one file named either Main.log or Thread_X.log 
> (X being the thread number set above), however the output in that file shows 
> the results from all of the threads (via the %X{id} at the beginning of each 
> line) as shown below:
> 
> Thread_0 09:30:52.519 [Thread-1] ERROR 
> org.somepackage.log4j.BoringLoggingClass - I am logging: 0
> Thread_3 09:30:52.519 [Thread-4] ERROR 
> org.somepackage.log4j.BoringLoggingClass - I am logging: 0
> Main 09:30:52.519 [Thread-3] ERROR org.somepackage.log4j.BoringLoggingClass - 
> I am logging: 0
> Thread_1 09:30:52.519 [Thread-2] ERROR 
> org.somepackage.log4j.BoringLoggingClass - I am logging: 0
> Thread_0 09:30:52.525 [Thread-1] ERROR 
> org.somepackage.log4j.BoringLoggingClass - I am logging: 1
> ...
> 
> Thanks, 
> Michael T Minella 
> 
> 
> ----- Original Message -----
> From: "Ralph Goers" <ralph.go...@dslextreme.com>
> To: "Log4J Users List" <log4j-user@logging.apache.org>
> Sent: Sunday, December 23, 2012 2:15:15 PM
> Subject: Re: Map Lookup Question
> 
> I started thinking about this and realized I have given you an incorrect 
> answer.
> 
> The file appender is initialized when the configuration is processed and is 
> not reevaluated for every event.  Thus giving it a variable with 2 '$' 
> characters doesn't make sense.  Likewise, when the configuration is processed 
> it is likely that your ThreadContext.put() call hasn't taken place yet and so 
> you are getting the variable expression as the value since it hasn't been 
> defined.  If you really want an appender that can write to a different file 
> based on a ThreadContext value then you would need to use the RoutingAppender.
> 
> Ralph
> 
> 
> On Dec 21, 2012, at 4:23 PM, Michael Minella wrote:
> 
>> 
>> I'm looking at the log4j 2 's thread specific features and had a question. 
>> In my code I set an id as follows: 
>> 
>> 
>> 
>> ThreadContext.put( "id" , "Main" ); 
>> 
>> 
>> and attempt to reference it in my configuration file as shown below: 
>> 
>> 
>> 
>> < File name = "File" fileName = "/tmp/myLog.log" > 
>> < PatternLayout pattern = "%X{id} %d{HH:mm:ss.SSS} [%t] %-5level %logger{36} 
>> - %msg ${ctx:id} %n" /> 
>> </ File > 
>> 
>> 
>> If I use the lookup in the pattern layout to test it, it works fine. 
>> However, if I move that lookup to the fileName attribute in the line above, 
>> the replacement doesn't occur (my file ends up being named 
>> /tmp/${ctx.id}.log for example). Is that a limitation of that lookup or am I 
>> missing something? Any insight that can be provided is appreciated. Thanks 
>> in advance! 
>> 
>> Thanks, 
>> Michael T Minella 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
> For additional commands, e-mail: log4j-user-h...@logging.apache.org
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org
> For additional commands, e-mail: log4j-user-h...@logging.apache.org
> 

Reply via email to