[logback-user] Can the SiftingAppender discard 'unknown' log events?
Ceki Gulcu
ceki at qos.ch
Wed Nov 24 13:56:08 CET 2010
Hello Colm,
Thanks for your feedback. Adding an OnConsoleStatusListener can help in
identifying such errors. Just add
<statusListener
class="ch.qos.logback.core.status.OnConsoleStatusListener" />
at the top of your config file. See also
http://logback.qos.ch/manual/configuration.html#statusListener
Cheers,
http://logback.qos.ch/manual/configuration.html#statusListener
On 24.11.2010 10:41, Colm.McDonnell at rbs.com wrote:
> Thanks Ceki, I have implemented that and tested it successfully.
>
> There's a typo in the Janino evaluator's expression, noting it here in case someone reuses this solution: s/mdg/mdc
>
> Thanks for the prompt response, much appreciated.
>
>
> -----Original Message-----
> From: logback-user-bounces at qos.ch [mailto:logback-user-bounces at qos.ch] On Behalf Of Ceki Gülcü
> Sent: 23 November 2010 22:51
> To: logback users list
> Subject: Re: [logback-user] Can the SiftingAppender discard 'unknown' log events?
>
> Hello Colm,
>
> You could add a filter into the nested appender so that when the value for the MDC key isolatedLogName is null, the event is denied. For example,
>
> <appender name="SIFTER"
> class="ch.qos.logback.classic.sift.SiftingAppender">
> <discriminator>
> <key>isolatedLogName</key>
> <defaultValue>unknown</defaultValue>
> </discriminator>
> <sift>
> <appender name="${isolatedLogName}"
> class="ch.qos.logback.core.FileAppender">
> <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
> <!-- GEventEvaluator requires Groovy -->
> <evaluator
> class="ch.qos.logback.classic.boolex.GEventEvaluator">
> <expression>
> (e.mdc == null) ||
> (e.mdc.get("isolatedLogName") == null)
> </expression>
> </evaluator>
> <OnMismatch>NEUTRAL</OnMismatch>
> <OnMatch>DENY</OnMatch>
> </filter>
> <file>${log.path:-target/log}/${isolatedLogName}.log</file>
> <encoder>
> <pattern>%d | %-5p | %logger{5} | %m%n</pattern>
> </encoder>
> </appender>
> </sift>
> </appender>
>
>
> or alternatively using Janino
>
>
> <appender name="SIFTER"
> class="ch.qos.logback.classic.sift.SiftingAppender">
> <discriminator>
> <key>isolatedLogName</key>
> <defaultValue>unknown</defaultValue>
> </discriminator>
> <sift>
> <appender name="${isolatedLogName}"
> class="ch.qos.logback.core.FileAppender">
> <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
> <!-- JaninoEventEvaluator requires Janino -->
> <evaluator
> class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
> <expression>
> mdc == null || mdg.get("isolatedLogName") == null
> </expression>
> </evaluator>
> <OnMismatch>NEUTRAL</OnMismatch>
> <OnMatch>DENY</OnMatch>
> </filter>
> <file>${log.path:-target/log}/${isolatedLogName}.log</file>
> <encoder>
> <pattern>%d | %-5p | %logger{5} | %m%n</pattern>
> </encoder>
> </appender>
> </sift>
> </appender>
>
> In both cases, the contents of ${log.path:-target/log}/unknown.log will be empty.
>
> In case of very intensive usage, you could also write your own custom evaluator in Java inserting the above logic into your evaluator in order to improve performance.
>
> HTH,
>
> On 23/11/2010 11:49 AM, Colm.McDonnell at rbs.com wrote:
>> I am using the SiftingAppender to isolate log events with a specific
>> MDC key. This works really well, giving me high signal:noise ratio log
>> files for specific invocations on particular process etc etc.
>> However the SiftingAppender (or rather the MDCBasedDiscriminator)
>> insists on the provision of a 'default value'. If I supply this
>> default value (e.g. "unknown") then all unmatched events will be
>> directed to unknown.log. But the 'other' log events are already logged
>> separately so the entries in 'unknown.log' are unwanted duplicates
>> (for me). Ideally I would use the sifting appender for a particular
>> use case and let everything else be logged the way it is currently
>> logged i.e. I would lke to provide no default value and have the
>> appender understand this to mean 'ignore any events which do not match
>> the given key' but that seems not to be supported so I'm trying to
>> figure out how to either discard the unwanted events or to incorporate
>> my existing logging into the sifting appender.
>> I'd be grateful if someone could suggest how I might do either of the
>> following:
>> * somehow discard the 'unknown' events discriminated by the
>> SiftingAppender i.e. to ignore them completely as they are already
>> logged elsewhere or
>> * figure out how to control the 'unknown' log events so that Ii can
>> direct them to an 'everything else' appender which is distinct from
>> the 'isolated events' appender I've included an example of the config
>> below. The STDOUT appender is the main appender, there's a wrapper
>> process running the java app and this wrapper process redirects STDOUT
>> to its own log file (with its own rolling rules etc) therefore the
>> 'everything else' events are all logged to STDOUT. I'd like the SIFTER
>> to only log events for which it gets a match otherwise we end up with
>> the same events in STDOUT and in "unknown.log". Alternatively, if
>> there is a way to configure SIFTER such that it wraps the STDOUT
>> appender and the unmatched events are only directed to that appender
>> then that would work too. I have tried several configurations but I
>> cannot associate the unmatched events with a specific appender.
>> <configuration>
>> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
>> <encoder>
>> <pattern>[%-5p] [%t] %logger{5}: %m%n</pattern> </encoder> </appender>
>> <appender name="SIFTER"
>> class="ch.qos.logback.classic.sift.SiftingAppender">
>> <discriminator>
>> <Key>isolatedLogName</Key>
>> <defaultValue>unknown</defaultValue>
>> </discriminator>
>> <sift>
>> <appender name="${isolatedLogName}"
>> class="ch.qos.logback.core.FileAppender">
>> <File>${log.path:-target/log}/${isolatedLogName}.log</File>
>> <encoder>
>> <Pattern>%d | %-5p | %logger{5} | %m%n</Pattern> </encoder>
>> </appender> </sift> </appender>
>> <!-- ... loggers excluded for brevity ... --> <root level="INFO">
>> <appender-ref ref="STDOUT" /> <appender-ref ref="SIFTER"/> </root>
>> </configuration> For example: I tried this:
>> <appender name="SIFTER"
>> class="ch.qos.logback.classic.sift.SiftingAppender">
>> <discriminator>
>> <Key>isolatedLogName</Key>
>> <defaultValue>everythingElse</defaultValue>
>> </discriminator>
>> <sift>
>> <appender name="isolatedLogName"
>> class="ch.qos.logback.core.FileAppender">
>> <File>${log.path:-target/log}/${isolatedLogName}.log</File>
>> <encoder>
>> <Pattern>%d | %-5p | %logger{5} | %m%n</Pattern> </encoder>
>> </appender> <appender name="everythingElse"
>> class="ch.qos.logback.core.ConsoleAppender">
>> <encoder>
>> <pattern>[%-5p] [%t] %logger{5}: %m%n</pattern> </encoder> </appender>
>> </sift> </appender> And logback created two files - everythingElse.log
>> and<the real value associated with the isolatedLogName key>.log -
>> then wrote all output to the "everythingElse" appender. I was trying
>> to tell it to do this: "if the key's value is the default value then
>> ignore it or if that is not possible then direct the output to the
>> appender named after that value otherwise direct to the other
>> appender".
>> Any help appreciated, thanks.
>
> _______________________________________________
> Logback-user mailing list
> Logback-user at qos.ch
> http://qos.ch/mailman/listinfo/logback-user
>
More information about the Logback-user
mailing list