Introduction
When debugging applications, it is often useful to have a debugging framework that will allow you to control the amount of output generated.
This class does not have the extensibility of the java.util.logging
package that is part of the Java(TM) 1.4 release. If you require a more feature rich logging facility, I suggest you use the one provided by the java.util.logging
package.
Background
When I started actually using Java, it was for the purposes of learning Java. I generally don't use Java in my daily job duties, but wanted to be proficient in it. Since I was trying to learn how things worked inside of Java applications and applets, I needed a way to print debugging information. I came up with the com.rl.debug
package. Soon after writing this package, I found the java.util.logging
package that is part of the Java 1.4.x release.
The Debug
class, which is part of the com.rl.debug
package, follows a simple "hierarchical" logging method. Each debug message is assigned a level. Based upon the level of the message and the current logging level set in the debugging class, the message may or may not be output. All messages which meet the current logging level or higher are logged.
Debug vs. java.util.logging
Since the current 1.4.x release of Java contains a very powerful and extensible logging framework in the java.util.logging
package, why use anything else? Good question. Here are some points that I think will help a developer to make that choice.
- The
java.util.logging
package is available as of the 1.4 release. If your applications are being built with a lower version, it isn't available to you. That is when you would have no choice but to employ your own logging package.
- A limitation that I found a bit annoying in the
java.util.logging
package was that the ConsoleHandler
, by default, will not log anything lower than INFO
. Since the Debug
package is intended as a debugging tool and generally should not output any information, I chose to default to a level of NONE
.
- Certainly the flexibility and extensibility of the
java.util.logging
package is by any comparison way better than the Debug
package. However, it can be a bit much to implement if you want a simple, lightweight package to use for debugging.
I am sure there are many other arguments that can be given for both of these packages. I think those presented here are enough to show the value of each, and to give a good basis for deciding which one is right for your own project.
Using the code
To use the Debug
class, you need a reference to a singleton instance. You can obtain this by using the getLogger()
method.
Obtaining an instance of the Debug
class.
private static Debug log = Debug.getLogger();
private static Debug namedLog = Debug.getLogger("LogFile");
You can set the level of detail output by the Debug
class, by using the setLevel()
method. The following code will log messages that are WARNING
or higher.
log.setLevel(log.WARNING);
By default, all messages are logged to the System.err
print stream. This can be changed using the setPrintStream
method.
import com.rl.debug.*;
import java.io.*;
public class TestDebug {
public static void main(String argv[]) {
FileOutputStream logFile = null;
PrintStream p = System.out;
try {
logFile = new FileOutputStream("TestDebug.log", true);
p = new PrintStream((OutputStream)logFile, true);
} catch (Exception e)
{
}
Debug log = Debug.getLogger();
Debug logger = Debug.getLogger("LogFile");
logger.setPrintStream(p);
log.setLevel(DebugLevel.ALL);
logger.setLevel(DebugLevel.WARNING);
log.DebugOut("We be a log!");
logger.DebugOut("We be a logger!");
log.DebugOut("I be saying I a logger!");
logger.warning("TestDebug", "main", "This is a warning");
log.setLevel(DebugLevel.WARNING);
log.DebugOut("We should not show up.");
logger.DebugOut("We should not be loggered");
log.DebugOut("I said, no output!");
logger.warning("TestDebug", "main",
"This is a warning with a WARNGING level.");
}
}
The above examples should be enough to get you going. I suggest you read the comments in the code. The comments should be enough to explain how to use a particular feature. Of course, I have heard that argument before. :)
I must warn you that I have not tested this class for thread safety, so treat it as not safe.
Happy coding.
Planned Enhancements
Ideally it would be nice to provide your own custom format for outputting the messages. I have considered implementing this and may in the future. However, if you really need that flexibility, you should probably just use the java.util.logging
package. Perhaps, if I get some feedback and a sense that formatting is really wanted, I will implement it. For now, I think the code is about as functional as it needs to be.
History
- 2003.03.13 - v1.3
After sleeping it over, I realized that I had an awful log of static items that just don't need to be. I modified it so that the private members are no longer static and the only static methods are the getLogger
methods.
After doing this, I realized it would be nice to have some information in my application logged to the console, while other information went to a file. Once I made the private members not static, this was possible, but only if I had more than one instance of the Debug
. This would allow me to set PrintStream
on one and not affect the other. To facilitate this, I removed the class member m_logger
and added the class member m_loggers
. m_loggers
is a hashtable of the loggers. This keeps the loggers accessible at a class level and keeps existing applications from breaking. It also now allows you to maintain multiple loggers. I updated the sample code to reflect the new version.