LOG Package

Document

xxxx

Authors

J. L. Abad Peiro (ZRL)
N. Asokan (ZRL)
C. Gulcu (ZRL)

Editor

C. Gulcu (ZRL)

Status

Alpha Version 0.6, SEMPER internal

Abstact

The semper.util.log package exports only a single class namely Log, although it defines two other unexported classes for internal use.

The goal of the LOG package is to provide a general but simple, yet robust and flexible logging facility. A major objective is to minimize source code fiddling in order to activate/deactivate arbitrary log messages. Ideally, one should be able to write a log statement in the source code and control its activation/deactivation dynamically through some sort of preference manager.

Short Remarks

There is one log file for all messages.

We write bytes instaed of unicode chars... (Mehdi's suggestion)

Requires

The LOG package requires the ExecInfo class defined in the "semper.util.execInfo" package. The ExecInfo class is used to print stack tracing information.

To do

  1. Catch errors early by trying to "touch" the log file while still in the setFullFileName() method.

Exported Constants

Gravity of Messages

The following five constants allow us to assign different levels of severity to messages. They are listed in the order of their severity.

CRITICAL

Corresponds to highly irrecuperable malfunctions. CRITICAL level errors should be used for extremely serious error conditions.

ERROR

Corresponds to serious malfunction. ERROR level errors should be used for highly serious error conditions.

WARNING

Corresponds to situations of minor malfunction or misconfiguration. WARNING level messages should be used for situations reflecting misconfigurations or probable programming errors.

INFO

Corresponds to progress report messages. INFO level is intended for high level messages, e.g. for reporting to the user/programmer on the progress of a particular run.

TRACE

Corresponds to debugging messages. TRACE level is intended for use in isolating programming erros.


Exported Methods


void init()

Read configuration options such as [LogFile], [DefaultCategoryLevel], [TimeEnable], [DateEnable], [LogPrefix], [CategoryPrefixing] and other category related options. (see Preferences .)

Unimplemented at this time. Please use the relevant setX() methods instead.


void init(String fullFileName)

This form is provided for compatibility with existing code. On Asokans request, it adds ".log" to the file name parameter. Thus, behavioral backward compatiblity is acheived.


void log(Sting category, int level, String message)

The Log.log() method may send a message to [LogFile] depending on the space separated categoryList and level parameters.

The categoryList parameter specifies a list of categories. Each element of this list corresponds to a specific category to which the log message belongs.

A message can belong to multiple categories.

For example the code

     Log.log("X.CONTRUCTOR PAYMENT", Log.TRACE, "Some message");
  
specifies that "Some Message" belongs to the "X.CONSTRUCTOR" and "PAYMENT" categories and is of level Log.TRACE.

The category values are set in the preference manager. The allowed values are (in increasing priority) CRITICAL, ERROR, WARNING, INFO and TRACE.

When a message belongs to more than one category the category with the lowest priority dominates. We say that lower severity messages subsume higher severity messages. The rationale behind this is that, if you are interested in lower severity messages then you are certainly interested in more severe messages. If a message does not belong to a known category, it is assigned a default category level as specified by the [DefaultCategoryLevel] option.

For example, if we set

    DefaultCategoryLevel = TRACE
    X = INFO
    Y = WARNING
  
then, in the code
   Log.log("X Y",   Log.TRACE, "Message 2"); // X dominates
   Log.log("Z",   Log.TRACE, "Message 2");   // Z is not set
  
"X Y" evaluates to INFO and Z evaluates to TRACE.

Once the categoryList parameter is evaluated it is compared with the actual level of the message. If the valuation of categoryList subsumes the level parameter, then the message is logged.

For example, if we set

   
    DefaultCategoryLevel = TRACE
    X = INFO
    Y = WARNING
  
then,
    Log.Trace("X"  , "Message 1");
  
will not log, since X doesn't subsume TRACE. Similarly,
 
    Log.Error("X Y", "Message 2");
  
will log, since "X Y" evaluates to INFO and INFO subsumes ERROR.

Remark: The order in which the categories are listed is insignificant.

By convention, a if a message pertains to a certain category it also pertains to all dot separated prefixes of that category. For example,

     Log.trace("X.Y.Z", "Some message");
means that "Some message" pertains to categories "X.Y.Z", "X.Y" and "X".

When evaluating categories the most specific category has precedence. For example, if in the preferences manager we set

X     = TRACE 
X.Y   = INFO 
X.Y.Z = WARNING
then, in the code
     Log.trace("X.Y.Z", "Some message");
"X.Y.Z" will evaluate to WARNING. Furthermore, since WARNING does not subsume TRACE the message will not log.

Similarly,

     Log.trace("X.Y.WHATEVER", "Some message");
will evaluate to the value of X.Y ("INFO") assuming X.Y.WHATEVER is unset. Consequently, the message will not log.

void log(Object object, int level, String message)

Similar to the preceding log() form except that the category is derived from the class name of the specified object,

This form is provided for compatibility with existing code. It should be phased out.


critical(String categoryList, String message)
error(String categoryList, String message)
warning(String categoryList, String message)
info(String categoryList, String message)
trace(String categoryList, String message)

Similar to log() except that the message level is deduced from the method name itself.

These new forms are provided as a syntaxic facility.


String setFullFileName(String fullFileName)

Set the log file where logging messages will go. Equivalent to setting up the [LogFile] option in the preference manager. If unset, there is no default value. INFO.

int fullFileName
The full file name for the log file.
returns
Previously used log file.

int setDefaultCategoryLevel(int level)

Sets up the default level assigned to unknown categories. Equivalent to setting up the [DefaultCategoryLevel] option in the preference manager. If unset, the default category level is INFO.

int level
New default category level.
returns
The old default category level

void setCategory (String category, int value)

Configure logging categories.

String category
The category to configure.
int value
The level of the category. Possible values (in decreasing severity) are CRITICAL, ERROR, WARNING, INFO and TRACE.

int setStackInfoThreshold(int level)

Set the stack information threshold. Equivalent to setting up the [StackInfoThreshold] option in the preference manager. If unset, defaults to WARNING.

Stack tracing information is added for all messages of same or higher severity than the stack information threshold.

int level
The new stack info threshold. Possible values (in decreasing priority) are CRITICAL, ERROR, WARNING, INFO and TRACE.
returns
The old stack info threshold.

boolean setDatePrinting(boolean newValue)

Sets whether date printing is enabled or not. Equivalent to setting up the [DatePrinting] option in the preference manager. If unset, defaults to TRUE.

If date printing is enabled, then date information is added to all logged messages.
int level
New date printing setting.
returns
The old date printing setting.

boolean setTimePrinting(boolean newValue)

Sets whether date printing is enabled or not. Equivalent to setting up the [TimePrinting] option in the preference manager. If unset, defaults to TRUE.

If time printing is enabled, then time information is added to all logged messages.
int level
New time printing setting.
returns
The old time printing setting.

boolean setCategoryPrefixing(boolean newValue)

Set whether category printing is enabled or not.

If time category printing is enabled, then the first category in the categoryList (see log() ) is added to all messages.

int newValue
New category printing setting.
returns
The old category printing setting.

String setStdPrefix(String newValue)

Set the standard prefix added to all messages. Returns the old standard prefix.


Preferences

[LogFile]

The name of the file where messages are appended. There is no default.

[DefaultCategoryLevel]

Possible values (in decreasing severity) are CRITICAL, ERROR, WARNING, INFO and TRACE.

Default value is INFO.

The default level for unknown categories.

[StackInfoThreshold]

Possible values (in decreasing priority) are CRITICAL, ERROR, WARNING, INFO and TRACE.

Default value is WARNING.

Additional stacked information is recorded with the logged message if its level has the same or higher priority than [StackInfoThreshold].

[TimePrinting]

Possible values are TRUE and FALSE. Default value is TRUE. If the [TimePrinting] is set to TRUE then all messages are prefixed with the current time (see logging format below).

[DatePrinting]

Possible values are TRUE and FALSE. Default value is TRUE. Similar to the [TimePrinting] option (see logging format below).

[LogPrefix]

All strings are valid. Log messages are prefixed with the log prefix (see logging format below). By default the [LogPrefix] is set to null value.

[CategoryPrefixing]

Possible values are TRUE and FALSE. Default is TRUE. If CategoryPrefixing is enabled then the first listed category in the log() method's first argument, i.e. categoryList, is prepended to the message.

Logging format

The logging format is:

  {date} {time} LEVEL {StdPrefix} {CategoryPrefix} - logMessage 

{} means that the field is optional.

The date is in the European format where the day precedes the month. Months are represented by their 3 letter abbreviations, i.e. Jan, Feb, ..., Dec.

For example, if in the preference manager we set

  DefaultCategoryLevel = INFO
  StackInfoThreshold   = WARNING
  DatePrinting         = TRUE           
  TimePrinting         = TRUE           
  StdPrefix            = Semper
  CategoryPrefixing    = TRUE        
  SEMPER               = INFO
then,
  Log.critical("X", "Some critical message"); 
  Log.info("SEMPER.PAYMENT TINGUIN", "Some info message");
will log
  [14:02:08] 07Aug1996 CRITICAL Semper  X - Some critical message
          at semper.util.log.Test.Test.x(Test.java:55)
          at semper.util.log.Test.Test.main(Test.java:52)
  [14:02:31] 07Aug1996 INFO     Semper  SEMPER.PAYMENT - Some info message