Provides classes (especially {@link JavaGroups.Common.Trace}) for logging timestamped messages to files, streams, writers, and sockets at differing levels of verbosity.

Log outputs are associated with a module name and a trace level. A module name specifies a class name and optionally a method name (see Module Names below).

A trace level is an integer specifying a level of output verbosity. The Trace class defines trace level constants such as DEBUG, WARN, and FATAL. Messages sent to an output are only printed if the trace level of the message is greater than or equal to the trace level set for the output.

Outputs are flushed when an output is closed. Outputs may be set to auto-flush after every call to print. By default, auto-flushing is turned off. Note: there is currently no way to assure that output is flushed when the program exits. It is the programmer's responsibility to call Trace.closeAllOutputs() or otherwise flush and close all outputs. As of Java 1.3, the Runtime.addShutdownHook method allows us to register a thread that could be used to flush and close all outputs.sed to flush and close all outputs. See code commented out in Trace.java.

If a module is not associated with any output, then a default output is used. The initial value of the default output is null. Messages sent to a null output are ignored.

Module Names

A module name is a string used to associate a message with a particular logging output. Module names should be of the form classname[.methodname([args...])]]: a class name optionally followed by a method name with parenthesis that optionally contain arguments. Here are some examples of legal module names:

Currently, method arguments are always ignored. In the future, we may want to be able to distinguish between methods with the same name and different arguments (for example, "MyClass.method(int)" and "MyClass.method(String)".

Module Inheritance

When calling Trace.print, the first argument is a moduprint, the first argument is a module name. When looking for which output to use, Trace uses the following set of rules. If no output is found (the returned output is null), then nothing is printed.

  1. If the module name contains no method name (there are no parenthesis), look for the output associated with this module name. If found, return it. Else, return the default output (initially null).
  2. Look for the output associated with this module and method name, excluding arguments if any.
  3. Strip off the method name and look for the output associated with the class name.
  4. Use the default output (initially null).

For example,

Trace.print("JChannel.Foo1()", Trace.FATAL, "ouch!");
would first look for "JChannel.Foo1()", then "JChannel", then use the default output (which may be null, which means no output will be produced).

Example Code

The following code shows how the rules above are used.

// Create outpu>

// Create output logging for all JChannel modules
Trace.setOutput("JChannel", Trace.FATAL, "logfile");

// Output to logfile
Trace.println("JChannel", Trace.FATAL, "ouch!");

// Not output (level is not FATAL)
Trace.println("JChannel", Trace.DEBUG, "buggy?");

// Both output to logfile because "JChannel" found.
Trace.println("JChannel.Foo1()", Trace.FATAL, "waah");
Trace.println("JChannel.Foo2()", Trace.FATAL, "waah");

// Send JChannel.Foo1() messages to a different logfile and set
// the trace level for Foo1() to INFO.
Trace.setOutput("JChannel.Foo1()", Trace.INFO, "foo1_logfile");

// These are output to logfile because "JChannel" log is still in
// effect for all "JChannel*" modules that are not "JChannel.Foo1()"
Trace.println("JChannel", Trace.FATAL, "ouch!");
Trace.println("JChannel.Foo2()", Trace.FATAL, "ouch!");

// Output to foo1_logfile because trace level FATAL > INFO
Trace.println("JChannel.Foo1()", Trace.FATAL, "ouch!");

// Not output because trace level DEBUG < INFO
Trace.println("JChannel.Foo1()", Trace.DEBUG, "buggy?");

// Reset trace level of all JChannel messages to DEBUG. Does not
// reset output file; oblue">// reset output file; output still goes to logfile. Does not affect
// "JChannel.Foo1()" output.
Trace.setOutput("JChannel", Trace.DEBUG);

// Now this gets output because we have reset the debug level.
Trace.println("JChannel", Trace.DEBUG, "buggy?");

// Flush and close output for "foo1_logfile". All messages printed
// for "JChannel.Foo1()" are now sent to the "JChannel" output
// logfile. The level is Trace.DEBUG because that's what it was
// already for "JChannel".
Trace.closeOutput("JChannel.Foo1()");
body>