We've have a class that implements logging also (just for when the next best thing comes about).
For the init method, you just pass an ojbect. public Log(Object object) { category = Category.getInstance(object.getClass()); ... This way, copy and paste people don't muck things up. - Robert Lasch "T Master" <tmaster@iknowled To: "Log4J Users List" <[EMAIL PROTECTED]> geinc.com> cc: Subject: Re: Clever Logging? 01/14/2002 02:48 PM Please respond to "Log4J Users List" 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" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> 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:[EMAIL PROTECTED]> > For additional commands, e-mail: <mailto:[EMAIL PROTECTED]> > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED] > For additional commands, e-mail: <mailto:[EMAIL PROTECTED] > -- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>