Discussion:
[logback-user] Setting log LEVEL on a per <appender-ref/> basis
Shane Kelly
2012-05-05 20:48:02 UTC
Permalink
Folks,

I've been tinkering with both log4j and more recently logback and I was
wondering whether or not it is possible to configure it in such a way that
it would be possible for a single logger to write to multiple appenders
using different LEVEL restrictions on a per-appender-ref basis. I
appreciate that it is possible to specify a LEVEL attribute for each
individual logger - but then any message which meets the logger LEVEL
criteria will be sent to all referenced appenders. I'm also aware that you
can define level thresholds and filters on a per-appender basis - but what
I was hoping for was rather than define lots of very similar appender
configurations (each with slightly different thresholds) that I could
define a smaller number of core appenders and have messages of certain
levels filtered out even before the appender is called.

To help illustrate the concept I'm aiming for, I've included a
pseudo-configuration file below. You'll notice that I've omitted the LEVEL
attribute from the <logger/> nodes and added LEVEL attributes to each of
the <appender-ref> nodes - this doesn't work obviously, but I was wondering
if there was some other way of emulating the behaviour that I'm after
without cluttering up the logback configuration too much...? You can see
from the configuration that for com.myorg.myapp.subpackage.one I would like
to apply different log level restrictions depending on the destination
appender. You'll also notice that for com.myorg.myapp.subpackage.two I want
to reuse the same appenders, but also use different level restrictions....
hope that makes it clear enough...

---------

<appender name="A">
...
...
</appender>

<appender name="B">
...
...
</appender>

<logger name="com.myorg.myapp.subpackage.one">
<appender-ref ref="A" LEVEL="INFO"/>
<appender-ref ref="B" LEVEL="DEBUG"/>
</logger>

<logger name="com.myorg.myapp.subpackage.two">
<appender-ref ref="A" LEVEL="WARN"/>
<appender-ref ref="B" LEVEL="TRACE"/>
</logger>

----------

Regards,

Shane
ceki
2012-05-05 21:09:22 UTC
Permalink
Hello Shane,

There are probably multiple approaches to this problem. It should be not
too difficult to write a RoutingAppender which can perform the type of
routing operation you describe. Here is how the config file would look like:

<appender name="A"></appender>
<appender name="B"></appender>

<appender name="ROUTING-ONE" class="...RoutingAppender">
<reference name="A" level="INFO"/>
<reference name="B" level="DEBUG"/>
</appender>

<appender name="ROUTING-TWO" class="...RoutingAppender">
<reference name="A" level="WARN"/>
<reference name="B" level="TRACE"/>
</appender>

<logger name="com.myorg.myapp.subpackage.one">
<appender-ref ref="ROUTING-ONE"/>
</logger>

<logger name="com.myorg.myapp.subpackage.two">
<appender-ref ref="ROUTING-TWO"/>
</logger>


By the way, could you provide more detail for your use case?

Cheers,
--
Ceki
http://twitter.com/#!/ceki
Post by Shane Kelly
Folks,
I've been tinkering with both log4j and more recently logback and I was
wondering whether or not it is possible to configure it in such a way
that it would be possible for a single logger to write to multiple
appenders using different LEVEL restrictions on a per-appender-ref
basis. I appreciate that it is possible to specify a LEVEL attribute for
each individual logger - but then any message which meets the logger
LEVEL criteria will be sent to all referenced appenders. I'm also aware
that you can define level thresholds and filters on a per-appender basis
- but what I was hoping for was rather than define lots of very similar
appender configurations (each with slightly different thresholds) that I
could define a smaller number of core appenders and have messages of
certain levels filtered out even before the appender is called.
To help illustrate the concept I'm aiming for, I've included a
pseudo-configuration file below. You'll notice that I've omitted the
LEVEL attribute from the <logger/> nodes and added LEVEL attributes to
each of the <appender-ref> nodes - this doesn't work obviously, but I
was wondering if there was some other way of emulating the behaviour
that I'm after without cluttering up the logback configuration too
much...? You can see from the configuration that for
com.myorg.myapp.subpackage.one I would like to apply different log level
restrictions depending on the destination appender. You'll also notice
that for com.myorg.myapp.subpackage.two I want to reuse the same
appenders, but also use different level restrictions.... hope that makes
it clear enough...
---------
<appender name="A">
...
...
</appender>
<appender name="B">
...
...
</appender>
<logger name="com.myorg.myapp.subpackage.one">
<appender-ref ref="A" LEVEL="INFO"/>
<appender-ref ref="B" LEVEL="DEBUG"/>
</logger>
<logger name="com.myorg.myapp.subpackage.two">
<appender-ref ref="A" LEVEL="WARN"/>
<appender-ref ref="B" LEVEL="TRACE"/>
</logger>
----------
Regards,
Shane
Shane Kelly
2012-05-05 21:35:58 UTC
Permalink
Hi Ceki,

Thanks for your prompt response. I wasn't aware of routing appenders - so
this is something that I shall certainly look into. My main motivation for
wanting to do this was primarily so that I could control the verboseness of
logging for the same logger depending on the destination appender without
having to create several (almost duplicate) appender configurations (whilst
setting slightly different threshold levels for each) - as far as possible
I only wanted to create a single appender configuration entry for each
distinct destination - i.e. Console, RollingFile etc. So, for example, I
might have a logger in a Java class which generates log messages of varying
levels, but I only want INFO and above to go to a Console appender, whilst
I want DEBUG and above to be written to a RollingFileAppender - for the
same class - simply because I don't want to clog up STDOUT with too much
information (unless I need to) but have a separate file to fall back to
which does contain a complete set of log messages for reference/debug at a
later date.

Is there any documentation describing how to create routing appenders (I
had a quick look and couldn't see anything) or is there an example of such
an appender lurking somewhere within the source that you could point me
towards?

Regards,

Shane
Post by ceki
Hello Shane,
There are probably multiple approaches to this problem. It should be not
too difficult to write a RoutingAppender which can perform the type of
<appender name="A"></appender>
<appender name="B"></appender>
<appender name="ROUTING-ONE" class="...RoutingAppender">
<reference name="A" level="INFO"/>
<reference name="B" level="DEBUG"/>
</appender>
<appender name="ROUTING-TWO" class="...RoutingAppender">
<reference name="A" level="WARN"/>
<reference name="B" level="TRACE"/>
</appender>
<logger name="com.myorg.myapp.**subpackage.one">
<appender-ref ref="ROUTING-ONE"/>
</logger>
<logger name="com.myorg.myapp.**subpackage.two">
<appender-ref ref="ROUTING-TWO"/>
</logger>
By the way, could you provide more detail for your use case?
Cheers,
--
Ceki
http://twitter.com/#!/ceki
Post by Shane Kelly
Folks,
I've been tinkering with both log4j and more recently logback and I was
wondering whether or not it is possible to configure it in such a way
that it would be possible for a single logger to write to multiple
appenders using different LEVEL restrictions on a per-appender-ref
basis. I appreciate that it is possible to specify a LEVEL attribute for
each individual logger - but then any message which meets the logger
LEVEL criteria will be sent to all referenced appenders. I'm also aware
that you can define level thresholds and filters on a per-appender basis
- but what I was hoping for was rather than define lots of very similar
appender configurations (each with slightly different thresholds) that I
could define a smaller number of core appenders and have messages of
certain levels filtered out even before the appender is called.
To help illustrate the concept I'm aiming for, I've included a
pseudo-configuration file below. You'll notice that I've omitted the
LEVEL attribute from the <logger/> nodes and added LEVEL attributes to
each of the <appender-ref> nodes - this doesn't work obviously, but I
was wondering if there was some other way of emulating the behaviour
that I'm after without cluttering up the logback configuration too
much...? You can see from the configuration that for
com.myorg.myapp.subpackage.one I would like to apply different log level
restrictions depending on the destination appender. You'll also notice
that for com.myorg.myapp.subpackage.two I want to reuse the same
appenders, but also use different level restrictions.... hope that makes
it clear enough...
---------
<appender name="A">
...
...
</appender>
<appender name="B">
...
...
</appender>
<logger name="com.myorg.myapp.**subpackage.one">
<appender-ref ref="A" LEVEL="INFO"/>
<appender-ref ref="B" LEVEL="DEBUG"/>
</logger>
<logger name="com.myorg.myapp.**subpackage.two">
<appender-ref ref="A" LEVEL="WARN"/>
<appender-ref ref="B" LEVEL="TRACE"/>
</logger>
----------
Regards,
Shane
______________________________**_________________
Logback-user mailing list
http://mailman.qos.ch/mailman/**listinfo/logback-user<http://mailman.qos.ch/mailman/listinfo/logback-user>
ceki
2012-05-06 10:53:19 UTC
Permalink
Hi Shane,
You could not have possibly be aware of RoutingAppender because it does
not exist yet. For the moment, it's just an idea for solving the problem
you described in your message. Browsing through logback documentation
and source code should give you ideas about writing a RoutingAppender.
Of course, once you get started you can ask for feedback here.

Cheers,
--
Ceki
http://twitter.com/#!/ceki
Post by Shane Kelly
Hi Ceki,
Thanks for your prompt response. I wasn't aware of routing appenders -
so this is something that I shall certainly look into. My main
motivation for wanting to do this was primarily so that I could control
the verboseness of logging for the same logger depending on the
destination appender without having to create several (almost duplicate)
appender configurations (whilst setting slightly different threshold
levels for each) - as far as possible I only wanted to create a single
appender configuration entry for each distinct destination - i.e.
Console, RollingFile etc. So, for example, I might have a logger in a
Java class which generates log messages of varying levels, but I only
want INFO and above to go to a Console appender, whilst I want DEBUG and
above to be written to a RollingFileAppender - for the same class -
simply because I don't want to clog up STDOUT with too much information
(unless I need to) but have a separate file to fall back to which does
contain a complete set of log messages for reference/debug at a later date.
Is there any documentation describing how to create routing appenders (I
had a quick look and couldn't see anything) or is there an example of
such an appender lurking somewhere within the source that you could
point me towards?
Regards,
Shane
Shane Kelly
2012-05-06 12:59:15 UTC
Permalink
Ceki,

That would certainly explain why I couldn't find any detailed info :) The
RoutingAppender concept that you describe is quite interesting though - it
would certainly address our particular needs. In the short term I think
we'll have to go with existing logback configuration and capabilities
(which meet the vast majority of our logging requirements) and investigate
some sort of RoutingAppender solution in the medium to long term.

In the meantime, thanks for your help. Much appreciated.

Regards,

Shane
Post by ceki
Hi Shane,
You could not have possibly be aware of RoutingAppender because it does
not exist yet. For the moment, it's just an idea for solving the problem
you described in your message. Browsing through logback documentation and
source code should give you ideas about writing a RoutingAppender. Of
course, once you get started you can ask for feedback here.
Cheers,
--
Ceki
http://twitter.com/#!/ceki
Post by Shane Kelly
Hi Ceki,
Thanks for your prompt response. I wasn't aware of routing appenders -
so this is something that I shall certainly look into. My main
motivation for wanting to do this was primarily so that I could control
the verboseness of logging for the same logger depending on the
destination appender without having to create several (almost duplicate)
appender configurations (whilst setting slightly different threshold
levels for each) - as far as possible I only wanted to create a single
appender configuration entry for each distinct destination - i.e.
Console, RollingFile etc. So, for example, I might have a logger in a
Java class which generates log messages of varying levels, but I only
want INFO and above to go to a Console appender, whilst I want DEBUG and
above to be written to a RollingFileAppender - for the same class -
simply because I don't want to clog up STDOUT with too much information
(unless I need to) but have a separate file to fall back to which does
contain a complete set of log messages for reference/debug at a later date.
Is there any documentation describing how to create routing appenders (I
had a quick look and couldn't see anything) or is there an example of
such an appender lurking somewhere within the source that you could
point me towards?
Regards,
Shane
______________________________**_________________
Logback-user mailing list
http://mailman.qos.ch/mailman/**listinfo/logback-user<http://mailman.qos.ch/mailman/listinfo/logback-user>
Loading...