Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

burst.logging.Log Class Reference

List of all members.

Detailed Description

Class to manage debug, warning, and other logging calls.

It decides whether to output the messages, and if so, where to. Right now, in practice this is a singleton class.

The system is distantly inspired by log4j, at http://jakarta.apache.org/log4j/

While our implementation is based on Logger instances, in practice we consider it unreasonable to expect programmers to explicitly instantiate them. So instead, we expect that in general the only interaction with this module will be via these global functions:

bu_debug(arg0, ...) bu_info(arg0, ...) bu_warn(arg0, ...) bu_error(arg0, ...)

bu_alert(message)

Loggers

There are a set of burst.logging.Log instances, each with a name. Any instance can have a parent. By convention, a "dotted name" is used for names, which reflects this containment hierarchy, so that a child would have the name "parentname.childname".

There is always at least the "root logger" instance (held in global bu_Log). There are no others unless client code creates them. Note that to strictly match the dotted name convention, the root logger should have the name "" (empty string). Instead it is given the name 'root'.

Each burst.logging.Log instance contains this state:

Log Levels

When log messages are produced by the application, it is with a particular verbosity level (from lowest, FATAL, to highest, DEBUG). Any log instance can have configured what the highest level is that it will respond to. This might come from an external configuration, associated with the logger name. If its maximum level is not configured, it will inherit from its parent, bubbling up until it reaches the root logger, which always has a maximum level configured (out of the box, at the WARN level). If the logger instance determines that the message verbosity level is less than or equal to its (possibly inherited) maximum level, then the message is said to be "enabled"; otherwise it is "disabled".

Appenders

There can be zero, one, or more "appenders" associated with any burst.logging.Log instance. If a message is "disabled", then it is not sent to any appenders. If a message is "enabled", then the burst.logging.Log instance sends it to all of its appenders, and to all the appenders up its inheritance hierarchy. For this reason, typically appenders are associated only with the root logger. (Log4j supports an "additivity flag" at any logger which stops bubbling up to parent appenders. We have not implemented that feature.)

Note that appenders are associated with logger instances in the logger hierarchy, not with a particular verbosity level. Of course any appender implementation may choose on its own to not respond to some message levels.

Formatting

The format of logged lines can be controlled by supplying a custom formatter, which would then be used when sending to all appenders. The default format is:

time level [logger] message

The format method is called as: format(logger, level, message, stack_start) The stack_start parameter is the number of stack frames to skip to get to the actual caller. It is available if the formatter wants to carry out (potentially expensive) investigation of the stack to determine caller class, caller method, file name, and/or line number.

(Fyi, log4j has special format strings, see http://jakarta.apache.org/log4j/docs/api/org/apache/log4j/PatternLayout.html )

Configuration

This class has several class properties, including: 'maxLevel', 'appender', 'formatter'.

As with any module in this library, application-specific configuration of class properties is done after the entire library is loaded. That leaves the question of what to do with calls into this module while the library itself is being loaded. This is something of a catch-22 challenge, because the functionality to do class property configuration may not even be defined at the time of a call.

So we have to have a temporary fixed behavior that governs what happens during the library load phase. In a shell, we use an appender which uses the shell's println functionality (this is governed by BU_LOG_USE_PRINTLN_APPENDER). In a browser, we use an appender which holds all messages in a circular Array buffer (circular, so it doesn't grow without bound). If an appender is added in the configuration phase, any accumulated messages in the circular Array is flushed to the new appender.

At configuration time, the application may set any appender it likes via the appender class property. If specified, it will replace any appenders that already exist (and, in the case of the circular buffer appender, flush its pending messages to the new appender).

We provide one potentially useful burst.logging.Appender subclass, called burst.logging.AppenderIframe, which sends its output to an iframe within the current web page. (This is not useful in a shell, obviously.) This appender is lazy, in that it does not add the iframe child to the current page until there is actually some output to display (which there may not be, depending on maxLevel). This would be configured for example by:

var bu_AppConfig = {'burst.logging.Log.appender' : 'new burst.logging.AppenderIframe()'};
Any of the optional constructor parameters could of course be specified; the whole string value is eval'd at configuration time to determine the burst.logging.Appender instance.

The global variable burst.logging.Log.ROOT_MAX_LEVEL governs the debug level that is used in the period between when this Log.js file is loaded, and when the external configuration (if any) is applied. You may set that variable prior to loading the file by something like this:

burst.logging.Log.ROOT_MAX_LEVEL = 'DEBUG';
If it is not set at configuration time, it keeps whatever level is set at load time via that variable (WARN by default).

If no configuration at all is done:

For any output to be seen it is necessary configure both an appender and set the debug level appropriately.

(Note that there is also the catch-22 problem of how library maintainers debug the module itself, but we don't get into that here. See the function bu_dbgdbg_ in the source.)

TODO

Todo:
automatically choose burst.logging.Log instance by caller file name, in environments where it is available.

incorporate any ideas/code from http://code.audiofarm.de/Logger/ (written in ActionScript 2.0)

maybe let bu_debug and so on be used in burst_first after all


Public Member Functions

 Log (String name, burst.logging.Log parent)
 Constructor for a burst.logging.Log.

void debug (...)
 Issue a debug message.

void setMaxLevel (Object level)
 Sets the highest level to pass on to any appender.

Boolean isOn (Object level)
 Whether the specified level is passed by this instance.

void addAppender (Object appender)
 Add an appender to this instance.

void setAppender (Object appender, Boolean copy_buffered)
 Will clear any existing appenders, and then add the given one.


Static Public Member Functions

Log getLogger (String name)
 Get a logger instance by name, or null if none.

void enableDebug (Boolean isEnabled)
 Will enable or disable debug at a global level (this is a class method).

Object toLevelObject (Object level)
 Convert a String name or Number level to a BU_LogLevel object.

String format (BU_Log logger, BU_LogLevel levelobj, String message, Number stack_start)
 The class method called to format a line of text.

void setFormatter (Function func)
 Set the formatter.


Static Public Attributes

final BU_LogLevel DEBUG = new BU_LogLevel(DEBUG, 7)
 The debug level.

final BU_LogLevel INFO = new BU_LogLevel('INFO', 6)
 The info level.

final BU_LogLevel WARN = new BU_LogLevel('WARN', 4)
 The warn level.

final BU_LogLevel ERROR = new BU_LogLevel(ERROR, 3)
 The error level.

final BU_LogLevel FATAL = new BU_LogLevel(FATAL, 0)
 The fatal level.

String maxLevel
 Class property: The max level of the "root" logger.

Expr appender
 Class property: If specified, the string is eval'd and the result is passed to setAppender.

Expr formatter
 Class property: If specified, the string is eval'd and the result is passed to burst.logging.Log.setFormatter.


Constructor & Destructor Documentation

burst.logging.Log.Log String  name,
burst.logging.Log  parent
 

Constructor for a burst.logging.Log.

No args for the root instance.

Parameters:
name Optional argument, the name of the instance.
parent Optional argument, the parent of the instance.


Member Function Documentation

void burst.logging.Log.addAppender Object  appender  ) 
 

Add an appender to this instance.

Currently there is no protection against duplicate adds.

Parameters:
appender An object with a method named format, or a function which is used in a burst.logging.Appender constructor.

void burst.logging.Log.debug ...   ) 
 

Issue a debug message.

Same as BU_Log.message(BU_Log.DEBUG, ...).

void burst.logging.Log.enableDebug Boolean  isEnabled  )  [static]
 

Will enable or disable debug at a global level (this is a class method).

This is efficiently redefining the bu_debug so it is a noop function, when isEnabled is false. If isEnabled is true, it is restored.

Note that if it is disabled, no debug will at all will ever come out, regardless of the debug level set in any BU_Log instance. If it is enabled, any filtering at the instance level still applies.

If setMaxLevel('DEBUG') is called on any BU_Log instance, it will automatically call enableDebug(true).

Parameters:
isEnabled whether debug should be enabled.

Log burst.logging.Log.getLogger String  name  )  [static]
 

Get a logger instance by name, or null if none.

Parameters:
name the name of the BU_Log instance

Boolean burst.logging.Log.isOn Object  level  ) 
 

Whether the specified level is passed by this instance.

If max_level_ is set, it does a comparison, otherwise bubbles to parent.

Parameters:
level (object, Number, or String name).

void burst.logging.Log.setAppender Object  appender,
Boolean  copy_buffered
 

Will clear any existing appenders, and then add the given one.

Optionally, will also copy over any buffered log statements from a previous burst.logging.AppenderBuffer.

Parameters:
appender The appender to set.
copy_buffered Optional. If specified and true, does the copying.

void burst.logging.Log.setFormatter Function  func  )  [static]
 

Set the formatter.

Must implement signature of BU_Log.format. This oly has an affect on appenders which do not do their own formatting.

void burst.logging.Log.setMaxLevel Object  level  ) 
 

Sets the highest level to pass on to any appender.

If null or undefined is passed in, it will cause this instance to inherit from its parent.

Parameters:
level A level as String name, Number level, or Object.

Object burst.logging.Log.toLevelObject Object  level  )  [static]
 

Convert a String name or Number level to a BU_LogLevel object.

If it is already a BU_LogLevel instance, it is just returned unchanged.


Member Data Documentation

Expr burst.logging.Log.appender [static]
 

Class property: If specified, the string is eval'd and the result is passed to setAppender.

No default.

final BU_LogLevel burst.logging.Log.FATAL = new BU_LogLevel(FATAL, 0) [static]
 

The fatal level.

This differs from ERROR in that messages to this level automatically cause an exception.

Expr burst.logging.Log.formatter [static]
 

Class property: If specified, the string is eval'd and the result is passed to burst.logging.Log.setFormatter.

No default.

String burst.logging.Log.maxLevel [static]
 

Class property: The max level of the "root" logger.

A string name of a level such as "DEBUG". If specified, it overrides BU_LOG_ROOT_MAX_LEVEL. No default.


The documentation for this class was generated from the following file:
Generated on Tue Nov 30 04:03:09 2004 for BurstProject by doxygen 1.3.4