You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-user@logging.apache.org by Charles Hache <ch...@tsco.ca> on 2012/07/18 19:26:11 UTC
Filter log based on package when using getLogger(String)
Hello folks,
Most of my loggers are constructed with the Logger.getLogger(String)
function, so that I can have loggers like "Device(#3, Some Description)"
instead of "ca.something.package.Device" with the goal of being able to
more easily identify which instances are writing what log lines.
I've found that when I do this I can't use properties to filter the log
level, such as
log4j.logger.ca.something.package=INFO
I figure this is because if I use getLogger(Device.class) it gets the
package of the logger from the class I give it and it all works from there.
So this all makes sense, but brings up two questions:
Can I still declare my loggers with a String name (getLogger(String))
and somehow still use package-style log level selection in the
properties file?
If not, do you guys have any tips on how to differentiate between
instances when they're logging? The obvious solution would be to
prepend any log message I want to write with a description of the
instance, but that seems like a lot of extra work.
I think really what I'm looking for is something like getLogger(Class
theClass, String theName), but maybe there is an already-implemented way
to do this.
Any tips?
Regards,
Charles
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
Re: Filter log based on package when using getLogger(String)
Posted by Charles Hache <ch...@tsco.ca>.
Thanks a lot for the tips guys!
tl;dr - skip to the end for my final, simple solution.
I'm a bit hesitant to adding expression filters to do this filtering.
The root of the issue is that I want to set the package log level using
the regular, standard way (so that anyone can do it/understand it from
the properties file), but I want my loggers to output a bit of extra
info whenever they print a line, so I know what instance is doing what.
The MDC/NDC stuff looks very interesting, but I'm looking for per logger
granularity, not per thread. When a thread traverses an object graph
and does work in each object, I want the object to tell me which
instance it is when it prints it's log lines, regardless if the worker
is Thread-4 or Thread-34 etc.
I had found that this is sort of a tall order as the architecture
doesn't really do this sort of thing (according to my primitive
knowledge of it), but I made it pretty close (with some blocking
caveats) with a custom logger.
I ended up finding out about custom loggers and log factories from the
<Install Zip>/examples/subclass folder. I threw together a new logger
('DescriptiveLogger') and a factory for it. The DescriptiveLogger has a
description field and overrides all the default logging to prepend the
message with this description.
The system works out fine until I want to create two loggers with the
same name/package with a different description. When I try
DescriptiveLogger.getLogger(existingClassAkaPackage, newDescription), it
will change the original/old logger and update it with the new
description, but I want a whole new instance.
This is due to the Hierarchy implementation - it stores all the loggers
in a hashtable that is keyed by the logger name (which is the same for
all my loggers, but I'd like a separate instance for each one so they
can each have their own description).
So after pouring over the source, I've finally found the trivial ideal
solution. Beforehand I was using getLogger("ImportantDevice: This
instance has ID 23"), which would give me the information I wanted in
the log, but wouldn't allow me to easily user per-package log levels
through the properties file. The alternative log creation, namely
getLogger(ImportantDevice.class) would give me the log level control I
wanted, but wouldn't give me the instance information I crave.
The solution is to use getLogger(ImportantDevice.class.getName()+": This
instance has ID 23"). Now the logger name is prefixed with the package,
which allows log4j to apply package log level rules to it, and the
logger name is also suffixed with the extra information I was looking
for. It took more time then I was hoping to figure this out (and I
didn't get to employ anything cool), but I expect that at least one
other person on here may be able to find it useful.
Regards,
Charles
On 7/18/2012 10:55 AM, Scott Deboy wrote:
> Correction: expression would use the LOGGER instead of MSG, since you're
> filtering on that.
>
> On Wed, Jul 18, 2012 at 10:54 AM, Scott Deboy<sc...@gmail.com> wrote:
>
>> You can use filters, including the ExpressionFilter, to build pretty much
>> arbitrary expressions and filter appenders using that, but it requires you
>> to use a log4j.xml configuration file.
>>
>> Something like this (requires you to have the 'extras' companion in your
>> classpath):
>>
>> <filter class="org.apache.log4j.filter.ExpressionFilter">
>> <param name="Expression" value="MSG ~=
>> #3"/>
>> <param name="AcceptOnMatch"
>> value="false"/>
>> </filter>
>> Scott
>>
>>
>> On Wed, Jul 18, 2012 at 10:26 AM, Charles Hache<ch...@tsco.ca> wrote:
>>
>>> Hello folks,
>>>
>>> Most of my loggers are constructed with the Logger.getLogger(String)
>>> function, so that I can have loggers like "Device(#3, Some Description)"
>>> instead of "ca.something.package.Device" with the goal of being able to
>>> more easily identify which instances are writing what log lines.
>>>
>>> I've found that when I do this I can't use properties to filter the log
>>> level, such as
>>> log4j.logger.ca.something.**package=INFO
>>> I figure this is because if I use getLogger(Device.class) it gets the
>>> package of the logger from the class I give it and it all works from there.
>>>
>>> So this all makes sense, but brings up two questions:
>>>
>>> Can I still declare my loggers with a String name (getLogger(String)) and
>>> somehow still use package-style log level selection in the properties file?
>>>
>>> If not, do you guys have any tips on how to differentiate between
>>> instances when they're logging? The obvious solution would be to prepend
>>> any log message I want to write with a description of the instance, but
>>> that seems like a lot of extra work.
>>>
>>> I think really what I'm looking for is something like getLogger(Class
>>> theClass, String theName), but maybe there is an already-implemented way to
>>> do this.
>>>
>>> Any tips?
>>>
>>> Regards,
>>> Charles
>>>
>>> ------------------------------**------------------------------**---------
>>> To unsubscribe, e-mail:log4j-user-unsubscribe@**logging.apache.org<lo...@logging.apache.org>
>>> For additional commands, e-mail:log4j-user-help@logging.**apache.org<lo...@logging.apache.org>
>>>
>>>
--
Charles Hache
Manager, Software Systems
Technical Solutions Company Ltd.
101 Titanium Way, Unit 105
Whitehorse, Yukon Y1A 0E7
Tel 867-668-6588, Ext. 204
Cell 867-336-1484
Fax 866-528-6410
EmailCHache@tsco.ca
Webwww.tsco.ca
Technical Solutions Company Ltd.
Automation - Telemetry - Electronics - Communications
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org
Re: Filter log based on package when using getLogger(String)
Posted by Scott Deboy <sc...@gmail.com>.
Correction: expression would use the LOGGER instead of MSG, since you're
filtering on that.
On Wed, Jul 18, 2012 at 10:54 AM, Scott Deboy <sc...@gmail.com> wrote:
> You can use filters, including the ExpressionFilter, to build pretty much
> arbitrary expressions and filter appenders using that, but it requires you
> to use a log4j.xml configuration file.
>
> Something like this (requires you to have the 'extras' companion in your
> classpath):
>
> <filter class="org.apache.log4j.filter.ExpressionFilter">
> <param name="Expression" value="MSG ~=
> #3"/>
> <param name="AcceptOnMatch"
> value="false"/>
> </filter>
> Scott
>
>
> On Wed, Jul 18, 2012 at 10:26 AM, Charles Hache <ch...@tsco.ca> wrote:
>
>> Hello folks,
>>
>> Most of my loggers are constructed with the Logger.getLogger(String)
>> function, so that I can have loggers like "Device(#3, Some Description)"
>> instead of "ca.something.package.Device" with the goal of being able to
>> more easily identify which instances are writing what log lines.
>>
>> I've found that when I do this I can't use properties to filter the log
>> level, such as
>> log4j.logger.ca.something.**package=INFO
>> I figure this is because if I use getLogger(Device.class) it gets the
>> package of the logger from the class I give it and it all works from there.
>>
>> So this all makes sense, but brings up two questions:
>>
>> Can I still declare my loggers with a String name (getLogger(String)) and
>> somehow still use package-style log level selection in the properties file?
>>
>> If not, do you guys have any tips on how to differentiate between
>> instances when they're logging? The obvious solution would be to prepend
>> any log message I want to write with a description of the instance, but
>> that seems like a lot of extra work.
>>
>> I think really what I'm looking for is something like getLogger(Class
>> theClass, String theName), but maybe there is an already-implemented way to
>> do this.
>>
>> Any tips?
>>
>> Regards,
>> Charles
>>
>> ------------------------------**------------------------------**---------
>> To unsubscribe, e-mail: log4j-user-unsubscribe@**logging.apache.org<lo...@logging.apache.org>
>> For additional commands, e-mail: log4j-user-help@logging.**apache.org<lo...@logging.apache.org>
>>
>>
>
Re: Filter log based on package when using getLogger(String)
Posted by Scott Deboy <sc...@gmail.com>.
You can use filters, including the ExpressionFilter, to build pretty much
arbitrary expressions and filter appenders using that, but it requires you
to use a log4j.xml configuration file.
Something like this (requires you to have the 'extras' companion in your
classpath):
<filter class="org.apache.log4j.filter.ExpressionFilter">
<param name="Expression" value="MSG ~=
#3"/>
<param name="AcceptOnMatch" value="false"/>
</filter>
Scott
On Wed, Jul 18, 2012 at 10:26 AM, Charles Hache <ch...@tsco.ca> wrote:
> Hello folks,
>
> Most of my loggers are constructed with the Logger.getLogger(String)
> function, so that I can have loggers like "Device(#3, Some Description)"
> instead of "ca.something.package.Device" with the goal of being able to
> more easily identify which instances are writing what log lines.
>
> I've found that when I do this I can't use properties to filter the log
> level, such as
> log4j.logger.ca.something.**package=INFO
> I figure this is because if I use getLogger(Device.class) it gets the
> package of the logger from the class I give it and it all works from there.
>
> So this all makes sense, but brings up two questions:
>
> Can I still declare my loggers with a String name (getLogger(String)) and
> somehow still use package-style log level selection in the properties file?
>
> If not, do you guys have any tips on how to differentiate between
> instances when they're logging? The obvious solution would be to prepend
> any log message I want to write with a description of the instance, but
> that seems like a lot of extra work.
>
> I think really what I'm looking for is something like getLogger(Class
> theClass, String theName), but maybe there is an already-implemented way to
> do this.
>
> Any tips?
>
> Regards,
> Charles
>
> ------------------------------**------------------------------**---------
> To unsubscribe, e-mail: log4j-user-unsubscribe@**logging.apache.org<lo...@logging.apache.org>
> For additional commands, e-mail: log4j-user-help@logging.**apache.org<lo...@logging.apache.org>
>
>
Re: Filter log based on package when using getLogger(String)
Posted by Douglas E Wegscheid <Do...@whirlpool.com>.
Use MDC for the string?
■ DOUGLAS E. WEGSCHEID // LEAD ENGINEER
(269) 923-5278 // Douglas_E_Wegscheid@whirlpool.com
"A wrong note played hesitatingly is a wrong note. A wrong note played
with conviction is interpretation."
Charles Hache <ch...@tsco.ca>
07/18/2012 01:26 PM
Please respond to
"Log4J Users List" <lo...@logging.apache.org>
To
log4j-user@logging.apache.org
cc
Subject
Filter log based on package when using getLogger(String)
Hello folks,
Most of my loggers are constructed with the Logger.getLogger(String)
function, so that I can have loggers like "Device(#3, Some Description)"
instead of "ca.something.package.Device" with the goal of being able to
more easily identify which instances are writing what log lines.
I've found that when I do this I can't use properties to filter the log
level, such as
log4j.logger.ca.something.package=INFO
I figure this is because if I use getLogger(Device.class) it gets the
package of the logger from the class I give it and it all works from
there.
So this all makes sense, but brings up two questions:
Can I still declare my loggers with a String name (getLogger(String))
and somehow still use package-style log level selection in the
properties file?
If not, do you guys have any tips on how to differentiate between
instances when they're logging? The obvious solution would be to
prepend any log message I want to write with a description of the
instance, but that seems like a lot of extra work.
I think really what I'm looking for is something like getLogger(Class
theClass, String theName), but maybe there is an already-implemented way
to do this.
Any tips?
Regards,
Charles
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org