General Interface provides an advanced logging system which is defined in the jsx3.util.Logger class. The logging system is designed to be an integral part of the development process. It can be used in General Interface Builder and in a running General Interface application to trace activity and diagnose errors. Logging messages can be sent to a variety of destinations using custom logging handlers — on-screen, memory, web service, local file, and so on. Which messages are displayed, where, and how they're displayed can be configured declaratively in an XML logging system configuration file without modifying source code.
Loggers and Handlers
Two important classes of objects in the logging system are:
A logger is used to log messages about a particular component of an application. After receiving the log message, the logger forwards the message to registered handlers. A logger may have one or more handlers associated with it.
A handler, which receives log messages from the loggers it's registered with, defines what to do with a logging message. A handler can output messages in a specified format to various destinations, such as to memory, system log, console, files, and so on. In some cases, a handler might ignore messages.
A logger is identified by its unique name. All logger instances exist in an inheritance tree and are descendants of the global logger. Inheritance is organized by name with the dot (".") character defining levels of the tree. For example, a logger named com.tibco inherits from com, which inherits from the root logger, global. Loggers are typically given names based on the package or class name of the component. Handlers must also have unique names. Because handlers don't inherit from other handlers, names can be much simpler and do not need to be based on inheritance.
Log Levels
Each logger has a log level associated with it. Log levels control which messages pass through the logger. A logging message also has a level associated with it. Only a message with a level equal to or more severe than the level specified for the logger passes through the logger. The levels defined in the system are, in order of decreasing severity, — FATAL, ERROR, WARN, INFO, DEBUG, and TRACE.
In the following example, mylogger is assigned a level of DEBUG. This logger only forwards messages of level FATAL, ERROR, WARN, INFO, and DEBUG to the appropriate handlers. All TRACE messages are ignored.
<logger name="mylogger" level="DEBUG"/>
If a log level isn't specified, the logger inherits the log level of its parent logger, such as the global logger. In this example, mylogger2 inherits log level INFO from its parent logger, global. Only FATAL, ERROR, WARN, and INFO messages are forwarded by mylogger2 to the registered handlers.
<logger name="global" level="INFO"/>
<logger name="mylogger2"/>
Handlers, like loggers, can also define a minimum level of message that they handle. In the following example from the logging system configuration file (logger.xml), appMonitor1 has been assigned a level of ERROR. This handler only outputs messages of a level equal to and more severe than ERROR, even though the logger it is registered with, global, forwards all messages of level INFO and more severe.
<handler name="appMonitor1" class="jsx3.app.Monitor"
require="true" level="ERROR">
. . .
</handler>
<logger name="global" level="INFO">
<handler-ref name="appMonitor1"/>
</logger>