[logback-user] Separating the logging-output of libraries in tomcat/shared

Ceki Gülcü ceki at qos.ch
Fri Mar 5 09:18:34 CET 2010


What do you mean by "no another 
web-app/app1/web-inf/classes/logback-context-name.xml" ? The rest looks good.

On 05/03/2010 12:44 AM, toxel wrote:
>
> Finally we have
>
> 1. logback.xml in shared libs with sift appender and
> JNDIBasedContextDiscriminator
> 2. configured ContextJNDISelector
> 3. configured web.xml for each application
> <env-entry-name>logback/context-name</env-entry-name>
>
>   and no another  web-app/app1/web-inf/classes/logback-context-name.xml ?
>
>
>
> Ceki Gulcu wrote:
>>
>> Change references from ${context} to ${contextName} as
>> JNDIBasedContextDiscriminator is hardwired to use the key "contextName".
>>
>> On 05/03/2010 12:04 AM, Ceki Gülcü wrote:
>>> Just remove  "<Key>context</Key>"
>>>
>>>
>>> On 05/03/2010 12:00 AM, toxel wrote:
>>>>
>>>> Hello
>>>>
>>>> I have a little question when I use configuration bellow I take
>>>> Exception
>>>>
>>>> Caused by: java.lang.UnsupportedOperationException: Key cannot be set.
>>>> Using
>>>> fixed key contextName
>>>> at at
>>>> *.logging.JNDIBasedContextDiscriminator.setKey(JNDIBasedContextDiscriminator.java:57)
>>>>
>>>>
>>>> Maybe I need other configuration ?
>>>>
>>>>
>>>> Ceki Gulcu wrote:
>>>>>
>>>>>
>>>>> I think the short answer is yes. The nested appenders will have the
>>>>> same configuration differentiated by the value returned by the
>>>>> discriminator. You could add properties to the logger context and
>>>>> since logger context properties are seen as variables, you could in
>>>>> principle use the value of the property to filter events. Here is an
>>>>> example using a ThresholdFilter and the variable myLevel with a
>>>>> default substitution value (see [1]).
>>>>>
>>>>> <appender name="SIFT"
>>>>> class="ch.qos.logback.classic.sift.SiftingAppender">
>>>>> <discriminator
>>>>> class="ch.qos.logback.classic.sift.JNDIBasedContextDiscriminator">
>>>>> <Key>context</Key>
>>>>> <DefaultValue>unknown</DefaultValue>
>>>>> </discriminator>
>>>>> <sift>
>>>>> <appender name="FILE-${context}"
>>>>> class="ch.qos.logback.core.FileAppender">
>>>>> <File>${context}.log</File>
>>>>> <Append>true</Append>
>>>>> <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
>>>>> <level>${myLevel:-DEBUG}</level>
>>>>> </filter>
>>>>> <layout>
>>>>> <pattern>%d [%thread] %level %mdc %logger{35} -
>>>>> %msg%n</pattern>
>>>>> </layout>
>>>>> </appender>
>>>>> </sift>
>>>>> </appender>
>>>>>
>>>>> You could set the myLevel property at the start of each
>>>>> application. Here is the sample code for web-app A:
>>>>>
>>>>>
>>>>> LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
>>>>> lc.putProperty("myLevel", some level value as appropriate for web-app
>>>>> A);
>>>>>
>>>>> For web-app B, the code is similar:
>>>>>
>>>>> LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
>>>>> lc.putProperty("myLevel", some level value as appropriate for web-app
>>>>> B);
>>>>>
>>>>> You need to make sure that the "myLevel" property is set before the
>>>>> logger context is configured which means that you need to override
>>>>> default logback configuration by invoking joran directly. Search for
>>>>> "Invoking JoranConfigurator directly" in [2]. The code then becomes:
>>>>>
>>>>> LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
>>>>>
>>>>> JoranConfigurator configurator = new JoranConfigurator();
>>>>> configurator.setContext(lc);
>>>>> // the context was probably already configured by default
>>>>> configuration
>>>>> // rules
>>>>> lc.reset();
>>>>> lc.putProperty("myLevel", some level value as appropriate for the
>>>>> web-app);
>>>>> configurator.doConfigure(args[0]);
>>>>>
>>>>> HTH,
>>>>>
>>>>> [1]
>>>>> http://logback.qos.ch/manual/configuration.html#defaultValuesForVariables
>>>>>
>>>>> [2] http://logback.qos.ch/manual/configuration.html
>>>>>
>>>>>
>>>>> On 02/03/2010 1:52 PM, Achim Wiedemann wrote:
>>>>>> Hi Ceki,
>>>>>>
>>>>>> I just implemented your suggestion and it works like a charm. :)
>>>>>> So it seems like there's a workaround for LBLCLASSIC-166 with your new
>>>>>> discriminator-class now. Great work and thanks a lot!
>>>>>>
>>>>>> By the way: Is there any possibility to have different logging-levels
>>>>>> for the nested appenders of a SiftingAppender?
>>>>>>
>>>>>>
>>>>>> greetz,
>>>>>> achim
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Ceki Gülcü schrieb:
>>>>>>> You are right. ContextBasedDiscriminator will not help you because
>>>>>>> the
>>>>>>> context name is retreived from the LoggingEvent which ultimately gets
>>>>>>> its value from the calling logger. If the calling logger is attached
>>>>>>> to the wrong context, ContextBasedDiscriminator will give you the
>>>>>>> wrong context name. Sorry for misleading you.
>>>>>>>
>>>>>>> However, I've written a new discriminator which should work assuming
>>>>>>> you have installed ContextJNDISelector as explained in
>>>>>>>
>>>>>>> http://logback.qos.ch/manual/loggingSeparation.html
>>>>>>>
>>>>>>> JNDIBasedContextDiscriminator can be found at
>>>>>>>
>>>>>>>
>>>>>>> http://github.com/ceki/logback/blob/90e50c/logback-classic/src/main/java/ch/qos/logback/classic/sift/JNDIBasedContextDiscriminator.java
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> or the same in tiny-speak
>>>>>>>
>>>>>>> http://tinyurl.com/yb6pdj2
>>>>>>>
>>>>>>> Getting values from JNDIBasedContextDiscriminator, SiftingAppender
>>>>>>> will get the correct context name and things should work much better.
>>>>>>> Give it a try.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 01/03/2010 9:38 AM, Achim Wiedemann wrote:
>>>>>>>> Hey Ceki,
>>>>>>>>
>>>>>>>> thanks for your fast reply. I tested your tip with the
>>>>>>>> SiftingAppender,
>>>>>>>> but couldn't see how this gets me further compared to the
>>>>>>>> logging-separation described in Ch8 of the manual (separation via
>>>>>>>> JNDIContextSelector). The problem is still the same: The context
>>>>>>>> of the
>>>>>>>> logger, once initialized, remains the same in shared libraries.
>>>>>>>> Since
>>>>>>>> SiftingAppender has to sieve based on some criteria (in my case the
>>>>>>>> context), it also can't solve this issue.
>>>>>>>>
>>>>>>>> So I see, as you already stated, it's not possible to get this
>>>>>>>> scenario
>>>>>>>> to work. However, thanks for your time and all your work.
>>>>>>>>
>>>>>>>>
>>>>>>>> greetz,
>>>>>>>> achim
>>>>>>>>
>>>>>>>>
>>>>>>>> Ceki Gulcu schrieb:
>>>>>>>>>
>>>>>>>>> Hello Achim,
>>>>>>>>>
>>>>>>>>> Thank you for your message.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> The only way to solve this issue transparently and perfectly
>>>>>>>>> would be
>>>>>>>>> to introduce another level of indirection inside loggers so that
>>>>>>>>> each
>>>>>>>>> logger-shell somehow delegate work to an inner logger attached to
>>>>>>>>> the
>>>>>>>>> appropriate context. This is quite a difficult problem
>>>>>>>>> technically and
>>>>>>>>> would generate significant computational overhead. I don't see the
>>>>>>>>> problem fixed via such indirection any time soon. Read, as a
>>>>>>>>> logback
>>>>>>>>> user, don't expect this problem to be solved without a little
>>>>>>>>> work on
>>>>>>>>> your side.
>>>>>>>>>
>>>>>>>>> As far as I can see, you have two options:
>>>>>>>>>
>>>>>>>>> 1) move shared classes whose loggers you care about to the web-app
>>>>>>>>> (unshare them)
>>>>>>>>>
>>>>>>>>> If 1) is not an option, there is:
>>>>>>>>>
>>>>>>>>> 2) Use a single shared logback.xml file with separation done by
>>>>>>>>> SiftingAppender [1] using the context as separation criteria [2].
>>>>>>>>> In
>>>>>>>>> conjunction with prudent mode of FileAppender, you will be able to
>>>>>>>>> separate logging by context.
>>>>>>>>>
>>>>>>>>> Let me know if the above does not make sense.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> [1] http://logback.qos.ch/manual/appenders.html#SiftingAppender
>>>>>>>>> [2]
>>>>>>>>> http://logback.qos.ch/xref/ch/qos/logback/classic/sift/ContextBasedDiscriminator.html
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 26.02.2010 08:21, Achim Wiedemann wrote:
>>>>>>>>>> Hey everybody,
>>>>>>>>>>
>>>>>>>>>> just wanted to port our application from commons-logging / log4j
>>>>>>>>>> to
>>>>>>>>>> slf4j / logback. Unfortunately I stumbled upon some problems when
>>>>>>>>>> separating the logging-output from different webapps (using the
>>>>>>>>>> JNDIContextSelector). As long as you only use logging from classes
>>>>>>>>>> inside the webapp, everything works fine. But as soon as you've
>>>>>>>>>> got
>>>>>>>>>> classes in tomcat/shared which use logging, you run into
>>>>>>>>>> trouble: All
>>>>>>>>>> logging output of the shared classes (e.g. Spring) are directed to
>>>>>>>>>> the
>>>>>>>>>> logger-context of the webapp which first loads the (shared) class.
>>>>>>>>>>
>>>>>>>>>> Example: Let's say you've got webbapp [A], webbapp [B], and
>>>>>>>>>> Spring in
>>>>>>>>>> tomcat/shared. Now both webapps use Spring. If webapp [B] first
>>>>>>>>>> accesses
>>>>>>>>>> any classes of Spring, all output of Spring will be directed to
>>>>>>>>>> the
>>>>>>>>>> log-file of [B], no matter from which webapp Spring is used.
>>>>>>>>>> This is
>>>>>>>>>> because static Logger references are used in Spring (which is
>>>>>>>>>> commonplace) and are initialized with the context of webapp [B].
>>>>>>>>>>
>>>>>>>>>> The issue is already described very well in the logback JIRA:
>>>>>>>>>> http://jira.qos.ch/browse/LBCLASSIC-166
>>>>>>>>>>
>>>>>>>>>> I wondered if anyone can make a suggestion how to deal with
>>>>>>>>>> this. Any
>>>>>>>>>> advice, tricks or magic is welcome. ;)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Thanks a lot,
>>>>>>>>>> Achim
>>>


More information about the Logback-user mailing list