|< Free Open Study >|| |
In this chapter we've used the Tomcat server log file as a central holding area for debug messages from the filter and the event listener. That was simple to do but it was not without its problems:
The messages that we're interested in may be interspersed with other log file entries that we need to strip out prior to visualization
Our JPDA Debugger had no comprehension of the server log file so we had to direct its output to a standalone file
For the full picture of what's happening in our servlets and container it would be best for all debugging messages to be channeled through to a common file or a real time analyzer.
We haven't used any of the new features available in J2SE version 1.4 so far, but if you are using that version, or will be soon, then there's some good news. Its Logging API allow you to send debug messages to a Logger object, which publishes those messages (LogRecord objects) with the help of a Handler object. The various styles of publication, such as writing to a file or sending to a remote monitoring process, are handled by the various types of Handler:
StreamHandler - A simple handler for writing formatted records to an OutputStream
ConsoleHandler - A simple handler for writing formatted records to System.err
FileHandler - A handler that writes formatted log records either to a single file, or to a set of rotating log files
SocketHandler - A handler that writes formatted log records to remote TCP ports
MemoryHandler - A handler that buffers log records in memory
The logging feature does nothing to help us capture the debugging information in the first place. It won't tell us which servlets have been called, in what order, or by which remote clients. It won't tell us when sessions are created and destroyed, and how the session attributes are modified. It won't tell us what interactions have occurred between low level container objects. So it won't replace the debugging mechanisms we developed earlier.
What it will do is provide a standard coupling mechanism for debugging components. The following diagram shows how the components we've developed could be connected via the Logging API:
When debugging web applications I think it's better to review the object interactions in the form of a trace, after the event, than it is to step through the events one-by-one as your would with a standalone single-user program. However, if you want to step through the events then the following configuration would be more appropriate:
We wrote our debugging output with embedded tags in order to make the results suitable for further processing. As a consequence, the logged output was not very readable until we looked at it using the TraceViewer class.
The Logging API can help us out there because it supports the idea of Formatters that render the debugging output in various ways. You can write your own Formatters or take advantage of the two that are supplied by default:
SimpleFormatter - Writes brief, readable summaries of log records
XMLFormatter - Writes detailed XML-structured information
The following listing shows some typical output using XMLFormatter (which is similar to what we produced):
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <!DOCTYPE log SYSTEM "logger.dtd"> <log> <record> <date>2000-08-23 19:21:05</date> <millis>967083665789</millis> <sequence>1256</sequence> <logger>kgh.test.fred</logger> <level>INFO</level> <class>kgh.test.XMLTest</class> <method>writeLog</method> <thread>10</thread> <message>Hello world!</message> </record> </log>
We'll round off the chapter with an idea for enhancing the software that we've developed so far.
|< Free Open Study >|| |