Most read:
Popular archives:
Java Q&A Forums - Let the great migration begin
We're pleased to announce the first phase of the integration of the Java Q&A Forums with our community platform, JavaWorld's
Daily Brew. Whether you're one of our longtime forum users or a brand newbie, we hope you'll visit the Java Q&A Forums in their new home alongside JW Blogs.
| Enterprise AJAX - Transcend the Hype |
| Oracle Compatibility Developer's Guide |
if( debug )
System.out.println("Debugging diagnostic");
Logging has several advantages over simple
println()
Logging is central to all of my programs. I use it to monitor my program's progress as it works. I use it to log error messages from library methods that might be used in a server-side context (where there's no console on which to print a stack trace). Most importantly, logging is one of my main debugging tools. Though visual debuggers are handy on occasion, I've noticed that I can find more bugs faster by combining a careful reading of the code with a few well-placed logging messages. (I'm not quite sure why reading/logging seems more effective than visual debugging, but my current theory is that a visual debugger narrows your focus to a single thread of control through the program, so you tend to miss bugs that aren't on that thread.)
Logging is essential in server-side debugging, where, typically, no console exists, so System.out proves useless. For example, Tomcat sends System.out to its own log file, so you never see messages that are sent there unless you have access to that log file. More to the point,
you probably want to monitor a server's performance from somewhere other than the server itself. Checking server logs is nice,
but I'd much rather see the logs on my workstation.
One of the better logging systems around is the Apache Software Foundation's log4j project. It's more flexible and easier to use than Java's built-in APIs. It's also a trivial install—you just put a jar file and a simple configuration file on your CLASSPATH. (Resources includes a good introduction article to log4j.) Log4j is a free download. The stripped-down but adequate-for-the-end-user documentation is also free. But you have to pay 0 for the complete documentation, which I recommend.
This article will look at how to extend log4j by adding a new appender—the part of the system responsible for actually sending the log messages somewhere. The appender I discuss is a lightweight version of the socket-based appender that comes with log4j, but you can easily add your own appenders to put log messages into a database or LDAP (lightweight directory access protocol) directory, wrap them in proprietary protocols, route them to specific directories, and so forth.
Listing 1 demonstrates how to use log4j. You create a
LoggergetLogger()
Then, when you want to log a message, you just send it to the logger. Logged messages typically fall into one of five categories:
debug, info, warn, error, or fatal, and methods named
debug()info()shutdown()main()shutdown()
Listing 1. Test.java: Using the log4j classes
1 import org.apache.log4j.Logger;
2 import org.apache.log4j.LogManager;
3
4 public class Test
5 {
6 private static final Logger log = Logger.getLogger( "com.holub.log4j.Test");
7
8 public static void main(String[] args) throws Exception
9 {
10 // For testing, give the client that will display the
11 // logged messages a moment to connect.
12 // (It's in a 50-ms wait loop, so pausing for
13 // 100 ms should do it).
14 Thread.currentThread().sleep( 100 );
15
16 log.debug("Debug Message");
17 log.warn ("Warning Message");
18 log.error("Error Message");
19
20 Thread.currentThread().sleep( 100 );
21 LogManager.shutdown();
22 }
23 }
The only other piece of the puzzle is a simple configuration file, which (thankfully) is not in XML format. It's a simple properties file, like the one in Listing 2.
To understand the file, you need to know a little about the logger architecture. Loggers form a runtime hierarchy of objects, organized by name. The "root" logger is at the root of the hierarchy, and the loggers you create are beneath the root (and each other), depending on their names. For example, a logger named a.b is beneath the logger named a, which is beneath the root.
Loggers write strings using two main helper classes called appenders and layouts. An appender object does the actual writing, and a layout object formats the message. Appenders are bound to a logger at runtime using information in the configuration file—this way, you can change them without recompiling. A particular logger can use several appenders, in which case, each appender sends the message somewhere, thus duplicating messages in several places. Log4j comes with several appenders that do things like console and file output and send logging messages using email or JMS (Java Message Service). Log4j also includes a socket-based appender similar to the one I illustrate in this article.
Layout objects, which control message formatting, are bound to appenders at runtime in a manner similar to loggers and appenders.
Log4J comes with several layout classes, which format in XML, HTML, and by means of a printf-like format string. I've found these to be adequate for most of my needs.
Finally, loggers also have filtering. The idea is to filter out, or discard, all categories of messages below a certain priority. The categories I mentioned earlier (debug, info, warn, error, or fatal) are in priority order. (Debug is the lowest and fatal, the highest.) You can filter all messages at or below a specified level simply by telling the logger to do so—either in your code or in the configuration file.
| Subject | Replies |
Last post
|
|
By Athen
|
0 |
08/28/08 01:51 PM
by Athen |
|
By |
0 |
05/24/07 04:36 PM
by Anonymous |
|
By JavaWorld |
4 |
03/01/06 05:01 PM
by Anonymous |