logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "T Master" <tmas...@iknowledgeinc.com>
Subject Re: Clever Logging?
Date Mon, 14 Jan 2002 20:48:01 GMT
Easy.

What I did was this:
Define a class that has methods to log under differerent Categories:

e.g.

MyLogger
{
    Category good = Category.getInstance("GOOD");
    Category error = Category.getInstance("ERROR");

    public void logGood( String msg){  good.info(msg);  }

    public void logError( String msg){  err.info(msg);  }

    public boolean isGoodEnabled()  {    return good.isInfoEnabled(); }
    public boolean isErrorEnabled()  {    return error.isInfoEnabled(); }

}


This way, no developers knew the underneath api (could be swapped in future
or whatever else).
Also, copy and paste programmers wouldn't have to be shot by me :o)


T Master


----- Original Message -----
From: "Silvert, Stan" <Stan@mediaocean.com>
To: <log4j-user@jakarta.apache.org>
Sent: Monday, January 14, 2002 1:39 PM
Subject: Clever Logging?


> I am responsible for defining standards around how our developers use
Log4J.
> When our company started using Log4J a couple of months ago, I told
> developers to use this technique in their code:
>
> public class MyClass {
>     private static final Category LOG =
> Category.getInstance(MyClass.class.getName());
>     private static boolean DEBUG() { return LOG.isDebugEnabled(); }
> }
>
> So, for all debug statements, write something like this:
>   if (DEBUG()) LOG.debug("The value of my vars are: " + v1 + " and " +
v2);
>
> If not a debug statement, just do something like this:
>     LOG.info("My info message");
>
> That all worked fine, except that developers would make the mistake of
> putting the wrong class name inside the getInstance() method.  This would
> usually happen when they would cut and paste code.
>
> So, one of our developers came up with a clever solution to cut down on
the
> mistakes.  He created a logging utility that could automatically read the
> stack frames, discover which class logged the message, and invoke logging
> from the proper Category.
>
> Here is how he did it:
>
> public class LogUtil {
>     /**
>      * Extends <code>java.lang.SecurityManager</code> to provide the
> <code>getClassName()</code>
>      * method.
>      */
>     private static class ClassGetter extends SecurityManager {
>         // Inner class necessary because getClassContext() is protected
>
>         /**
>          * Returns the name of the calling class.
>          * @return  the name of the calling class
>          */
>         public String getClassName() {
>             // getClassContext() returns the current execution stack trace
>             // as an array of classes -- the element at index 0 is the
class
>             // of the currently executing method, the element at index 1
is
>             // the class of that method's caller, and so on. So, 0 is
going
>             // to be this class (ClassGetter), 1 will be LogUtil, and 2
will
>             // be the magic number we are after.
>             return getClassContext()[2].getName();
>         }
>     }
>     private static ClassGetter classGetter = new ClassGetter();
>
>     /**
>      * Returns the name of the calling class.
>      * Intended to be used from static methods or initializers to
> automagically
>      * determine the calling class's name.
>      * @return  the name of the calling class
>      */
>     public static String getClassName() {
>         return classGetter.getClassName();
>     }
>
>     ///////////////////////////////////////////////////////////////////
>
>     /**
>      * Returns <code>true</code> if debugging is enabled for a given
> category
>      *
>      * @return  <code>true</code> if debugging is enabled,
>      *          <code>false</code> if not
>      */
>     public static boolean DEBUG() {
>         Category cat = Category.getInstance(classGetter.getClassName());
>         return cat.isDebugEnabled();
>     }
>
>     ///////////////////////////////////////////////////////////////////
>
>     /**
>      * Logs the given message with <code>DEBUG</code> priority, to the
> category
>      * automagically derived from the calling class name.
>      *
>      * @param  msg  the message to log
>      */
>     public static void debug(String msg) {
>         Category cat = Category.getInstance(classGetter.getClassName());
>         cat.debug(msg);
>     }
> }
>
> This looks very nice and seems to solve all the problems quite well -
except
> for one thing.  I have been reading about how some JIT's can remove stack
> frames during optimization.  This would cause messages to once again be
> logged under the wrong Category.
>
> My questions to the folks on this list are,
> What is your opinion of both techniques?
> Do you know other developers who have tried the "clever" approach and run
> into the "disappearing stack frame" problem?
> Is there another solution we are overlooking?  (short of disabling cut and
> paste from everyone's IDE)
>
> Thanks in advance for your input.
>
> Stan Silvert
>
>
> --
> To unsubscribe, e-mail:
<mailto:log4j-user-unsubscribe@jakarta.apache.org>
> For additional commands, e-mail:
<mailto:log4j-user-help@jakarta.apache.org>
>


--
To unsubscribe, e-mail:   <mailto:log4j-user-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:log4j-user-help@jakarta.apache.org>


Mime
View raw message