Hi Jim, 

Nice to see there *are* people using custom
Priorities .. I thought I was alone for a while!

Just a few comments:

(a)
with this approach, the custom category needs
to be used like this:

TraceableCategory cat = (TraceableCategory) 
   TraceableCategory.getInstance("catname"); 
cat.trace("msg");

ie a cast is needed. This is not a big deal, 
but is a minor nuisance

(b)
in your xml config file, you didn't specify a 
custom CategoryFactory. Doesn't this mean 
that the above cast to TraceableCategory
will throw an exception, because the 
Category object was actually created as a 
normal org.apache.log4j.Category?

Your example shows how to explicitly set
the category class for root, but it isn't feasable 
to set an explicit category class for every
category...

I think it *might* be ok if you don't try to
set any filtering level on categories in the
config file, as then the only category created
is the root category, but as soon as category-
specific config features are specified, the 
Configurator needs to create the Category
object, and will use the default factory unless
an alternative "global" factory has been defined.

(c)
If Ceki accepts the patch I submitted a week ago 
(and he has indicated he will), then the
PropertyConfigurator will very soon be
able to use custom priority classes, like this:
log4j.category.fred = com.acme.Priority#TRACE, appender1

I worked on this because I want to use custom priorities from
an applet, and don't want to download an XML parser as part
of the applet just to read a log4j xml config file!

Cheers,

Simon

> -----Original Message-----
> From: Jim Moore [SMTP:[EMAIL PROTECTED]]
> Sent: Thursday, February 15, 2001 5:01 PM
> To:   'LOG4J Users Mailing List'
> Subject:      RE: adding custom priorities
> 
> There is no way to use a custom Priority when using the
> PropertyConfigurator.  Major bummer, I know, because that's certainly more
> straightforward than DOMConfigurator to use.  The format of the XML for
> DOMConfigurator is easy (if you know XML), but it's a bit of a pain to
> have
> to include the extra libraries.
> 
> Other than that, the code below should give you a good example of how to
> address your other concerns:
> 
> /**
>  * Provides support for the {@link TraceablePriority.TRACE} priority.
>  */
> public class TraceableCategory extends Category {
>   private static final Factory factory = new Factory();
>   private static final String instanceFQCN =
> TraceableCategory.class.getName();
> 
>   public TraceableCategory(String name) {
>     super(name);
>   }
> 
>   /**
>    * This method overrides {@link Category#getInstance(String)} by
> supplying
>    *   its own factory type as a parameter.
>    */
>   public static Category getInstance(String name) {
>     return Category.getInstance(name, factory); 
>   }
> 
>   /**
>    * This method overrides {@link Category#getInstance(String)} by
> supplying
>    *   its own factory type as a parameter.
>    */
>   public static Category getInstance(Class cls) {
>     return Category.getInstance(cls.getName(), factory);
>   }
> 
>   /**
>    * Log a message object with the {@link TraceablePriority#TRACE TRACE}
>    *   priority.<p>
>    * 
>    * This method first checks if this category is <code>TRACE</code>
>    *   enabled by comparing the priority of this category with the {@link
>    *   TraceablePriority#TRACE TRACE} priority. If this category is
>    *   <code>TRACE</code> enabled, then it converts the message object
>    *   (passed as parameter) to a string by invoking the appropriate
>    *   {@link ObjectRenderer}. It then proceeds to call all the
>    *   registered appenders in this category and also higher in the
>    *   hierarchy depending on the value of the additivity flag.
>    * 
>    * @param message  the message object to log.
>    */
>   public void trace(String message) {
>     if (isTraceEnabled())
>       callAppenders(new LoggingEvent(instanceFQCN, this,
> TraceablePriority.TRACE,
>                                      message, null));
>   }
> 
>   /**
>    * Check whether this category is enabled for the <code>TRACE</code>
>    * priority.<p>
>    * 
>    * This function is intended to lessen the computational cost of
>    * disabled log trace statements.<p>
>    * 
>    * For some <code>cat</code> Category object, when you write,
>    * <pre>
>    *   cat.trace("This is entry number: " + i );
>    * </pre>
>    * 
>    * You incur the cost constructing the message, concatenatiion in
>    * this case, regardless of whether the message is logged or not.<p>
>    * 
>    * If you are worried about speed, then you should write
>    * <pre>
>    *   if(cat.isTraceEnabled()) {
>    *     cat.trace("This is entry number: " + i );
>    *   }
>    * </pre>
>    * 
>    * This way you will not incur the cost of parameter construction
>    * if tracing is disabled for <code>cat</code>. On the other hand,
>    * if the <code>cat</code> is trace enabled, you will incur the cost
>    * of evaluating whether the category is trace enabled twice. Once
>    * in <code>isTraceEnabled</code> and once in the <code>trace</code>.
>    * This is an insignificant overhead since evaluating a category
>    * takes about 1% of the time it takes to actually log.
>    * 
>    * @return boolean - <code>true</code> if this category is trace
>    *         enabled, <code>false</code> otherwise.
>    */
>   public boolean isTraceEnabled() {
>     return(disable >=  TraceablePriority.TRACE_INT) ?
>       false :
>       TraceablePriority.TRACE.isGreaterOrEqual(this.getChainedPriority());
>   }
> 
>   // Any sub-class of Category must also have its own implementation of 
>   // CategoryFactory.
>   public static class Factory implements CategoryFactory {
>     public Factory() {
>     }
> 
>     public Category makeNewCategoryInstance(String name) {
>       return new TraceableCategory(name);
>     }
>   }
> }
> 
> /**
>  * This class introduces a new priority level called TRACE. TRACE has
>  *   lower priority than DEBUG.
>  */
> public class TraceablePriority extends Priority {
>   public static final int  TRACE_INT  = 800;
> 
>   // We assimilate TRACE to DEBUG on Syslog
>   private static final int SYSLOG_TRACE_INT  = 7;
> 
>   public static final TraceablePriority TRACE =
>     new TraceablePriority(TRACE_INT, "TRACE", SYSLOG_TRACE_INT);
> 
>   protected TraceablePriority(int level, String strLevel, int syslogEquiv)
> {
>     super(level, strLevel, syslogEquiv);
>   }
> 
>   public static Priority toPriority(String sArg) {
>     if (sArg == null)
>       return TraceablePriority.TRACE;
> 
>     return (sArg.equalsIgnoreCase("TRACE")) ?
>       TraceablePriority.TRACE :
>       Priority.toPriority(sArg);
>   }
> 
>   public static Priority toPriority(int i) throws IllegalArgumentException
> {
>     return (i == TRACE_INT) ?
>       TraceablePriority.TRACE :
>       Priority.toPriority(i);
>   }
> }
> 
> Then you would have an entry like this in your log4j.xml file:
>     <!-- Note the class attributes! -->
>     <root class="TraceableCategory">
>         <priority value ="trace"
>           class="TraceablePriority"/>
>         <appender-ref ref="MAIN" />
>     </root>
> 
> There's no need for mucking around with Hierarchies.  The package scope
> used
> in Priority is a nuisance (I consider the use of package scope to be a
> design flaw in general), but inheratance let me treat it as private data
> and
> continue on.
> 
> -Jim Moore
> 
> 
> -----Original Message-----
> From: Geert Mergan [mailto:[EMAIL PROTECTED]]
> Sent: Thursday, February 15, 2001 10:42 AM
> To: [EMAIL PROTECTED]
> Subject: adding custom priorities
> 
> 
> Hello,
> 
> I suppose I'm not the only one's trying to define custom priorities
> (TRACE,
> ALWAYS, DEBUG2). It seems this is not as easy as I hoped it would be.
> 
> I've started with writing MyPriority (extending Priority as the javadoc
> says
> you shoulds when enlarging the priority set). That already gave some
> problems because the _INT fields have package scope. This seems like a
> design flaw to me, since I'd like to access these fields in MyPriority (in
> com.mycompany.util.logging package), but I managed to bypass via
> copy/paste
> (or so I hope).
> 
> Now the next thing I do is writing MyCategory (extends Category) since I
> need to add the methods trace(), always() and debug2(). I suppose I must
> also implement getInstance() because otherwise I won't be able to create
> MyCategory events. And then I have to write a MyHierarchy class since
> getInstance() requires a hierarchy and who knows what other classes I'll
> have to subclass and I won't even be sure that it will work so...
> 
> I start to suspect I'm not on the right track to add custom priorities.
> Anyone every tried to add custom priorities?
> 
> G.
> ---------------
> Geert Mergan
> Java Developer
> Email: [EMAIL PROTECTED]
> Phone: +32-2-3571765
> 
> EuropeanInvestor.com
> Lasne Business Park
> Chaussée de Louvain 431, Building F
> B-1380 Lasne
> Phone: +32-2-3571711
> Fax: +32-2-3571700
> URL: http://www.europeaninvestor.com
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]

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

Reply via email to