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

Ceki Gülcü ceki at qos.ch
Fri Mar 5 00:06:03 CET 2010


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
>
>>
>
> _______________________________________________
> Logback-user mailing list
> Logback-user at qos.ch
> http://qos.ch/mailman/listinfo/logback-user



More information about the Logback-user mailing list