Ok, back to the subject of extracting the method name from the 
stack trace.

The problem is actually a bit more complicated and I think we're
doing the wrong thing at the moment, and all proposed solutions
are quite bad.

What we are trying to solve: display the method and classname that
makes the log call. 

Log4j and jdk1.4 logging provide a config format to enable displaying this 
- logkit doesn't seem to, so it's not a problem there ( since it couldn't
be displayed in the first place - if it does, same issue as in jdk1.4 
apply )

Log4j has the best support for this - if you enable the display for
method and classname it'll generate a Throwable and walk the stack to
find the caller. It also have support for passing a Object which is 
indicates the 'wrapper' - so if log4j is wrapped, we display the real
caller, not the wrapper.

JDK1.4 does almost the same thing - if called directly and if the
method display is configured, it'll walk the stack. It is also possible
to pass the class/method as String params ( as oposed to log4j 
where you pass the Object wrapper ).

The problem in JDK1.4 is that there is no good way to deal with the 
case when their logger is wrapped ( by commons-logging or by a tomcat
logger or any other method ). So we have to 'emulate' this and extract
the information from stack in the wrapper. We could ask the user
to pass this explicitely - but that's stupid, since the info is redundant
( we already _have_ it, in the stack ) and make the logger hard to use.

We solve the problem for commons-logging, but what if commons-logging
itself is wrapped ? Well, same solution as in log4j can be used here, 
i.e. pass ( somehow ) information about the wrapper and skip it from
the stack walk.

However there are 2 huge problems:

1. Performance. Generating an exception and parsing the stack trace
is _extremely_ expensive. If you need the information - you'll have 
to pay for it, but the problem is that you pay for it even if you
_don't_ use it. 

2. Configuration. We either add explicit API to pass this info in each
Log method or we allow to configure it per LogFactory or once per Log
( i.e. a single method - generic or not - to configure it ). 

What that means is that in order to avoid the performance when it is
not needed, we also need to request the logger to enable stack checking
in 1.4 ( again, log4j works without problems anyway ). 

The solution of casting or constructing Jdk14Logger explicitely is 
wrong - we loose the pluggability and discovery. 

IMHO the only way to deal with that is to allow some form of 
configuration ( hints ) that is generic to all loggers. 

I'll ask for a vote - after I hear your comments. The hints 
will be passed by whoever creates the Logger, and so far the 
best solution seems to be setAttribute in Logger.

There is one alternative - that doesn't require API changes, and it
may be much better: 

Require ( or recomend ? ) that each Log and LogFactory to support a form 
of JMX. 

That would mean that we'll be able to find if a Log or LogFactory support
configuration, pass configuration using a standard API, use the 
existing JMX support in log4j, get the loggers to integrate nicely
in tomcat and apps that use JMX. 

A static MBean would be the best choice for this case - as it 
doesn't introduce _any_ dependency on JMX, it's just a programming
style where each LogFactory/Log impl would also implement an interface
with getters/setters. For log4j we could expose the 'real' MBean 
of the Category, since it already exist and get access to all
the config capabilities. 

Yet another alternative is to just use getter/setters and the 
introspection-based dynamic MBean in tomcat-util ( which can be used
to transparently enable any bean as a JMX component - like 3.3 
interceptors or jk handlers ).

I hope at least someone has read all this long message and will respond 
:-)

Costin 








--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to