logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Robert Pepersack" <RPepers...@mdinsurance.state.md.us>
Subject Re: Specify Repository
Date Thu, 10 Apr 2008 19:52:01 GMT
Thanks for your help so far.

I have a RepositorySelector that uses the MDC to get the Hierarchy for the currently running
job.

But, there is a problem because of the way the Spring container creates my jobs, initializes
the jobs' loggers, and runs the jobs.  The loggers for my jobs get created before the MDC
is ever set.  Here is the scenario:
1.  Application starts.
2.  log4j is initialized with LogManager.LogManager.setRepositorySelector(MySelector) and
PropertyConfigurator.
3.  Spring IOC container starts.
4.  Jobs and their dependencies are created by container.  Loggers, which are declared as
instance variables in Jobs, are created with Logger.getLogger(job.class.name).
5.  Container schedules jobs.
6.  Container starts new thread and executes a job, at which time, the MDC is set with a repository
name.
7.  Logger for the currently executing job uses the default repository (not its own), because
the logger for the job was already created before the job executed (oh no).
8.  Job finishes.
9.  Job's repository name is removed from the MDC.

Please help.

Thanks,

Robert Pepersack
Senior Lead Developer
Maryland Insurance Administration
410-468-2054

>>> "Jacob Kjome" <hoju@visi.com> 04/10/2008 11:53 AM >>>
On Thu, 10 Apr 2008 10:49:50 -0400
  "Robert Pepersack" <RPepersack@mdinsurance.state.md.us> wrote:
> I'm not confusing LogManager.setLoggerRepository(repository, guard) and 
>LogManager.getLoggerRepository().  I understand everything in Chapter 8.
> 

Then you understand why there's no point to LogManager.getLoggerRepository() 
taking arguments and why it's not generally necessary to actually call this 
from application code.

> I wouldn't be creating all that many repositories, just one for each of my 
>jobs (this is analogous to one repository per web application).  I currently 
>have six jobs, so would I have six instances of Hierarchy that get reused 
>again and again?
> 

If your threads are limted to a pool of 6, then you're correct; it wouldn't be 
that much overhead.  And, yes, you would cache each logger repository in a 
collection within your selector, keyed by whatever MDC value you selecting 
upon.

You'll have to come up with some way to determine how you configure each 
logger repository, though.  You could pre-initialize all the logger 
repositories based on the MDC value(s) you expect to select upon.   You could 
then run configure the repository either programmatically or via the 
appropriate *Configurator.doConfgure(url/stream/file/etc.., repository) 
methods.  In fact, you could do this all in a static initializer of the 
selector class.  That way, the selector is ready to go very shortly after it 
is loaded by the classloader.


Jake

> Robert Pepersack
> Senior Lead Developer
> Maryland Insurance Administration
> 410-468-2054
> 
>>>> Jacob Kjome <hoju@visi.com> 04/10/2008 10:34 AM >>>
> Are you confusing LogManager.setLoggerRepository(repository, guard) with 
> LogManager.getLoggerRepository()?  In whatever environment you are in, you 
>just 
> need to make sure that you set your custom repository selector first thing, 
>before 
> doing any logging.  A servlet context listener was only a suggestion of a 
>possible 
> way to do it if you were running in a servlet environment.
> 
> You could do this prior to loading the Spring application context.  I'm 
>assuming 
> that if you are using plain old JSE, and not JEE, that Spring 
>applicationContext 
> loading is not being done in some automatic way, but manually.
> 
> And I think I said the per/thread approach is heavyweight because it creates 
>a 
> *lot* of logger repositories and requires configuration to run on each of 
>them as 
> they are created.  That's much more heavyweight than the typical application 
> server JNDI-based logger repositories, which would only be created once per 
> application.
> 
>Finally, you don't have to call LogManager.getLoggerRepository().  Your 
>selector 
> implements this.  Log4j calls it internally when determining which logger 
> repository to log to.  Your selector implements...
> 
> public LoggerRepository getLoggerRepository();
> 
> Again, see the ContextJNDISelector in the sandbox for an example...
> http://svn.apache.org/repos/asf/logging/sandbox/log4j/log4j_sandbox/tags/LOG4J_SANDBOX_ALPHA3/src/java/org/apache/log4j/selector/ContextJNDISelector.java

> 
> Your code just does the following, as usual...
> 
> logger.debug("blah");
> 
> 
> It's all magic/smoke and mirrors.  That's both the beauty and the bane of 
>the 
> repository selector solution.  It's works transparently, like magic, but 
>it's 
> sometimes hard to comprehend; and sometimes simply fails to work in certain 
> situations.
> 
> 
> Jake
> 
> Robert Pepersack wrote:
>> James and Jake, thanks for your replies.
>> 
>> I want to specify a RepositorySelector, because I'm using the Spring IOC 
>>container to manage my application.  The Spring IOC container is a J2SE 
>>container, not J2EE.  So, there is no ServletContext for me to use to 
>>determine which repository to select.  The book points out that 
>>LogManager.getLoggerRepository() does not accept any arguments, and it says 
>>that the RepositorySelector must track the context.  But, in a J2SE 
>>environment, I don't know a way to do this - other than using the MDC, as 
>>Heri suggests in the log4j archives.  Jake, you said that this approach is 
>>heavy weight, but I don't understand why.  Here is the URL for Heri's 
>>suggestion:
>> 
>> http://mail-archives.apache.org/mod_mbox/logging-log4j-user/200602.mbox/%3C3FE38194C8A3334A959B64B7D9A1E27B6E30E1@plejaden.seychelles.ergo%3E

>> 
>> But, here is an added twist.  In the Spring IOC containter, most objects are 
>>created by one thread as the container starts, and the objects' methods are 
>>executed by another thread (i.e. Quartz jobs).  Since my loggers are created 
>>as instance variables, the MDC approach breaks down.
>> 
>> Thanks,
>> 
>> Robert Pepersack
>> Senior Lead Developer
>> Maryland Insurance Administration
>> 410-468-2054
>> 
>>>>> "Jacob Kjome" <hoju@visi.com> 04/09/2008 5:52 PM >>>
>> Your repository selector selects the repository.  You set the repository 
>> selector by calling LogManager.setRepositorySelector(selector, guard).  Note 
>> that the guard is provided so that if someone else comes along a tries to 
>> reset it, they will get an IllegalArgumentException and be prevented from 
>> overriding the initial setting.  This is because the selector is global to 
>>the 
>> Log4j instance.  Repository selector setting is meant to be done at 
>> application startup.  When running inside an application server, it should, 
>> ideally, be set by the server.  However, if you are the only app to use it, 
>> you could have a servlet context listener do this upon application startup.
>> 
>> http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/LogManager.html#setRepositorySelector(org.apache.log4j.spi.RepositorySelector,%20java.lang.Object)
>> 
>> As you can see, this has nothing to do with logger statements.  Your code 
>> doesn't have to change in order to use a repository selector.
>> 
>> Jake
>> 
>> On Wed, 09 Apr 2008 11:58:53 -0400
>>   "Robert Pepersack" <RPepersack@mdinsurance.state.md.us> wrote:
>>> I've checked the archives and didn't find an answer, but please forgive me 
>>> if this a duplicate post.
>>>
>>> I would like to be able to specify a repository for my logger to use.  For 
>>> example:  Logger logger = new Logger("my.class.name", "myRepositoryName");
>>>
>>> I read Chapter 8, "Extending log4j", and it said that subclassing Logger is 
>>> a bad idea.  I don't see a way to accomplish what I want by wrapping Logger.

>>> So, I think, that the only way to do it would be to tweak a few of the log4j

>>> classes (i.e. Logger, LogManager, RepositorySelector, and 
>>> DefaultRepositorySelector).  Would anyone be interested in this, or am I 
>>> barking up the wrong tree?  I realize that this could open a can of worms 
>>> with a lot of repositories getting created, but, if we're carful, this could

>>> be very useful.
>>>
>>> Thanks,
>>>
>>> Robert Pepersack
>>> Senior Lead Developer
>>> Maryland Insurance Administration
>>> 410-468-2054
>>>
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org 
>>> For additional commands, e-mail: log4j-user-help@logging.apache.org 
>>>
>>>
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org 
>> For additional commands, e-mail: log4j-user-help@logging.apache.org 
>> 
>> 
>> 
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org 
>> For additional commands, e-mail: log4j-user-help@logging.apache.org 
>> 
>> 
>> 
>> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org 
>For additional commands, e-mail: log4j-user-help@logging.apache.org 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org 
>For additional commands, e-mail: log4j-user-help@logging.apache.org 
> 
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org 
For additional commands, e-mail: log4j-user-help@logging.apache.org 


---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Mime
View raw message