Thanks for letting me know about that. i will check into that today. Ralph
On Dec 26, 2012, at 7:52 AM, Michael Minella wrote: > Progress continues... > > Using beta-4-SNAPSHOT now generates a file per thread (as expected) which is > great. However, I do have one other issue with the new version. The > inheritance of ThreadContext values does not seem to be working. If I set a > value in a parent thread and do not override it in the child, the child is > not picking it up (this was working in the previous version). Using the > example I previously provided, the third instance of BoringLoggingClass > should be logging with the ThreadContext's id set to "Main". With the latest > version of log4j, it is null. > > Thanks, > Michael T Minella > > > ----- Original Message ----- > From: "Ralph Goers" <[email protected]> > To: "Log4J Users List" <[email protected]> > Sent: Monday, December 24, 2012 12:03:43 PM > Subject: Re: Map Lookup Question > > 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" <[email protected]> >> To: "Log4J Users List" <[email protected]> >> 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: [email protected] >> For additional commands, e-mail: [email protected] >> >> --------------------------------------------------------------------- >> To unsubscribe, e-mail: [email protected] >> For additional commands, e-mail: [email protected] >> > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [email protected] > For additional commands, e-mail: [email protected] > --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
