This shouldn't be a factory.  I don't want to have to manage the instance, but 
I do want to reference the instance from anywhere (this is assuming support for 
levels outside of TRACE, regardless of if we still support the trace helper 
methods in loger).

CustomLevelRegistry may make more sense, with statics for accessing and 
registering levels (requiring syslog level support seems like a pain - maybe we 
can have two 'register' methods, one that supports syslog levels, one that 
doesn't but sets all custom levels to the same syslog level.

CustomLevelRegistry.register(3000, "TRACE");

logger.log(CustomLevelRegistry.getLevel("TRACE"), "my message");

No need to have CustomLevelRegistry extend Level - it can live in 
org.apache.log4j along with Level.

If we still feel like supporting trace helpers in logger, fine.  We do need to 
look at Level's toLevel method because it defaults to DEBUG if it doesn't 
recognmize the level (this will need to change).


Scott

-----Original Message-----
From:   Curt Arnold [mailto:[EMAIL PROTECTED]
Sent:   Wed 5/25/2005 2:06 PM
To:     Log4J Developers List
Cc:     
Subject:        Re: Remove TRACE?  Was: [VOTE] Modified Release Proposal

I was surprised that it was hard to find a lot of previous discussion  
or previous bugs on the issue.  If anybody else has links to relevant  
discussions, please add them.  Here are some that I found:


Recent log4j-user discussion (assume existence of problem): http:// 
marc.theaimsgroup.com/?l=log4j-user&m=111253143214177&w=2
Commons-dev patch submission to http://marc.theaimsgroup.com/? 
l=jakarta-commons-dev&m=107472058005673&w=2
Commons-dev thread (followups appear as distinct topics) http:// 
marc.theaimsgroup.com/?l=jakarta-commons-dev&m=106865687610260&w=2

As far as I can reconstruct, Apache Geronimo wanted a distinct level  
lower than debug and had trace() added to Jakarta Commons Logging.    
Without that change, I believe that most code that used JCL could be  
converted to use log4j simply by changing the package names and  
switching Log and Logger.  The JCL bridge to log4j just treated trace  
as a synonym for debug where the JDK 1.4 logging maps debug() to  
Level.FINER and trace to Level.FINEST.

So trace is a special case due to its "endorsement" by JCL.  There  
are a couple of distinct issues:

JCL/log4j client code compatibility:
Switching JCL code that uses org.apache.commons.logging.Log.trace()  
to log4j would require adding an explicit org.apache.log4j.Logger.

JCL mapping of trace calls to level lower than Level.DEBUG
The major roadblock is the lack of a public constructor for  
o.a.l.Level.  I think the approach used in tests/java/org/apache/ 
log4j/xml/XLevel.java is problematic  since adding a custom  
implementation class would cause problems for SocketAppender et al to  
fail if the class is not available.  A derived class definition could  
be used to bypass the access control on the constructor and would  
might be an appropriate way to address the issue:

class final CustomLevelFactory extends org.apache.log4j.Level {

    /**
     *   Private, non-functional constructor.
     */
     private CustomLevelFactory() {
         super(-1, "", -1);
         throw new NotImplementedException();
    }

    //
    //   since we are in extension of Level we can access the  
protected constructor
    public static final org.apache.log4j.Level createLevel(
         final int severity,
         final String name,
         final int syslogLevel) {
             return new Level(severity, name, syslogLevel);
     }
}

class Log4JLogger {
     private static final Level TRACE = CustomLevelFactory.createLevel 
(5000, "TRACE", 7);
     public void trace(Object message) {
           getLogger().log(FQCN, TRACE, message, null );
     }

}

In a perfect world (aka 2.0), Category would disappear and Level  
would be final with a public constructor.  That would make life  
easier in general but CustomLevelFactory would need to be changed to  
not extend Level and call the public constructor.

The final area would be in parsing configuration files that contain  
"TRACE" (or any other place were you need to convert a Level name  
back to an object), but the only place that I can think of right now  
are in the configuration parsers.  The code might be made more  
general so that if it encounters a name like "5000" it will parse it  
as an integer and fabricate a level with that value which would be  
sufficient for configuration purposes.

To recap my non-exhaustive analysis:

trace() is special since it is in JCL.

JCL should be able to map trace() to a distinct level than debug() by  
using hacky CustomLevelFactory to create an instance of Level with a  
custom name and value.

Other custom levels should be available using the CustomLevelFactory  
approach without any code changes (excluding configuration).

Setting a threshold to a custom level would require modifying the  
configuration code or Level.toLevel to fabricate a new level if the  
argument is a string representation of an integer which would allow  
stuff like:

<root>
     <level value="5000"/>
</root>

Or providing a mechanism to inform the configurators of new levels to  
recognize:

JoranConfigurator config = new JoranConfigurator();
const.addLevel(MyCustomLevels.TRACE);
config.configure(...);


which would allow you to do:

<root>
     <level value="TRACE"/>
</root>



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




<<winmail.dat>>

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

Reply via email to