[logback-user] Separating the logging-output of libraries in tomcat/shared
Ceki Gülcü
ceki at qos.ch
Fri Mar 5 00:04:07 CET 2010
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