Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Write custom appenders for log4j

Extend log4j to support lightweight over-the-network logging

  • Print
  • Feedback

Page 3 of 6

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.

Turning to Listing 2, the first line specifies the filter level ( DEBUG) and the appenders ( FILE, CONSOLE, and REMOTE) attached to the root logger. All loggers beneath the root in the runtime hierarchy inherit this filter level and these appenders, so this line effectively controls logging for the whole program (unless you use a more complex configuration file to specify something different).

The remainder of the configuration file specifies properties for the appenders. For example, Listing 2's second line says that the file appender named FILE is an instance of the com.apache.log4j.FileAppender class. Subsequent lines initialize this appender object when it's created—in this case, passing it the name of the file in which it will put the log messages, the layout object to use, and a format string for that layout object.

The rest of the configuration file does the same for the other appenders. The CONSOLE appender sends messages to the console, and the REMOTE appender sends messages down a socket. (We'll look at the source code for the REMOTE appender shortly.)

At runtime, log4j creates all the required classes for you, hooks them up as necessary, and passes the arguments you specify in the configuration file to the newly created objects using JavaBean-style "setter" methods.

Listing 2. log4j.properties: A log4j configuration file

 log4j.rootLogger=DEBUG, FILE, CONSOLE, REMOTE
log4j.appender.FILE=org.apache.log4j.FileAppender
log4j.appender.FILE.file=/tmp/logs/log.txt
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=[%d{MMM dd HH:mm:ss}] %-5p (%F:%L) - %m%n
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%d{MMM dd HH:mm:ss}] %-5p (%F:%L) - %m%n
log4j.appender.REMOTE=com.holub.log4j.RemoteAppender
log4j.appender.REMOTE.Port=1234
log4j.appender.REMOTE.layout=org.apache.log4j.PatternLayout
log4j.appender.REMOTE.layout.ConversionPattern=[%d{MMM dd HH:mm:ss}] %-5p (%F:%L) - %m%n



Using a remote appender

One of log4j's major strengths is that the tool is easy to extend. My RemoteAppender extension provides a way to log messages across the network to a simple socket-based client application. Log4J actually comes with a means of doing remote logging (an appender called SocketAppender), but this default mechanism is too heavyweight for my needs. It requires you to have the log4j packages on the remote client, for example.

Log4j also comes with an elaborate standalone GUI called Chainsaw that you can use to view messages from a SocketAppender. But Chainsaw is also way more than I need and really badly documented to boot. (I've never have had the time or patience to figure out how to use Chainsaw.) In any event, I just wanted to watch debugging diagnostics scroll by on a console window as I tested. Chainsaw was way too much for this simple need.

  • Print
  • Feedback

Resources