MoMELog 1.0 Guide

Sergio Morozov


Contents

  1. Overview
  2. Description
  3. Usage
  4. Configuration
    1. Declarative Configuration
      1. General Framework Configuration
      2. Listener Configuration
      3. Formatter Configuration
    2. Programmatical Configuration
      1. General Framework Configuration
      2. Listener Configuration
      3. Formatter Configuration

Overview

MoMELog is a logging framework for J2ME architecture as log4J is for J2SE. It resembles log4J very much. But, it has a different purpose, is build on other principals, and is much more smaller and simple.

I will not discuss here in details all the principals and ideas that led to the development of this project. Please, read the Introduction To MoMELog. I will just remember the main of them. In my humble option, the aim of J2ME logging framework (at least now) should be it's use at development time as debugging tool. It should be as simple and extensible as possible. All logging events should be formatted using one method and presented to the developer via one mean (except, that some of them can be filtered out ;-)).

MoMELog logging framework is intended to be used at development time. Of course, author doesn't prohibit it's use in final application (;-)), It is just not the aim of the project. MoMELog doesn't support the notion of priority of logging events and doesn't maintain the hierarchy of loggers. All logging events are formatted using one method and presented to the developer via one mean. It is possible to suppress logging of group of loggers and/or vice versa allow logging only of group of loggers. It is also possible to specify group of loggers that will issue logging only if user request contains not-null error. Besides, MoMELog framework doesn't maintain a hierarchy of loggers, it is recommended to specify structural categories. They are helpful in formatting (e.g to use only last part of category) and/or suppressing/allowing logging or allowing only logging events with not-null error for the group of loggers.

MoMELog logging framework consists of a small core and extensions that realize particular formatting method or display logging information to the developer via particular mean.

MoMELog framework can be configured declaratively and/or programmatically. Declarative configuration of the core of the framework and extensions is done by putting initialization file in application's jar archive. It is a simple text properties file. Programmatical configuration of the core of the framework can be done by invoking static methods of Logger class. Programmatical configuration of extensions is realized by invoking instance methods of particular extension. Developers can set group of loggers, that are allowed and/or disallowed to log, group of loggers that are allowed to log only events with error, type of Formatter intended to convert logging events to strings and type of LogListener intended to make formatted logging information accessible to the developers.

Now MoMELog logging framework consists of three extensions:

Some of the extensions (i.e LogCanvas) require some programming work to be done to make use of them. As MoMELog is intended to be used at development time and by developer it is not considered as big problem.

Description

MoMELog logging framework is very simple. It consists of three parts: Logger, Formatter, LogListener.

Fig-1. MoMELog Framework.

Logger is the main part of MoMELog framework. It generates logging events on user request and directs them to the configured LogListener. LogListener converts these events to formatted strings using configured Formatter and makes obtained strings available to the user (e.g. shows on screen, puts in RMS, sends via http/https, appends to a file or any other way).

Loggers are distinguished by categories, that are the case-sensitive identification strings. MoMELog doesn't maintain the hierarchy of loggers. All loggers are even. It is possible to suppress logging of group of loggers and/or allow logging of only group of loggers, by specifying disallowed categories and allowed categories lists respectively. They are a comma separated lists of patterns. Logger can only log it's events, if it's category matches one of the patterns in allowed categories list and not in disallowed categories list. If any of the lists is empty, it is not considered. It is recommended to use structural categories. This can be very helpful in formatting logging events and gives better possibilities to suppress or allow logging of a group of loggers. It is also possible to specify group of loggers that will generate logging event only if user request contains not-null error. This feature is realized by onlywitherror categories list, that is also the list of patterns.

Pattern can contain any text and only one type of special character - asterisk (*). Asterisk, like in file regular expression, designates any number of any characters. Of course, pattern can contain zero or more asterisks. For example pattern "somepackage.*Screen", specifies categories that start with "somepackage." and ends with "Screen".

MoMELog framework doesn't support the notion of priority. All logging events are even. The feature of filtering out logging events based on their properties (except not-null error) can be built in a particular LogListener implementation and is not realized by the core of the framework.

In MoMELog framework logging events have the following properties:

MoMELog framework can be configured declaratively and/or programmatically. Declarative configuration of the core of the framework and extensions is done by putting initialization file .momelog.txt (don't omit preceding dot ;-)) in application's jar archive. This is a simple text properties file, where lines are separated by new-line characters and empty lines and lines that start with hash (#) (preceding spaces are allowed) are ignored. The core of the framework can be also configured programmatically by using static methods of Logger class. Programmatical configuration of LogListener and/or Formatter can be done by using instance methods of respective implementation. Declarative configuration occurs at Logger class loading time and programmatical one, of course, overrides it. See Configuration chapter for details.

The core framework provides means to set the type of LogListener used for presenting logging to the developer, type of Formatter used for converting logging events to strings and allowed categories, disallowed categories and onlywitherror categories lists. MoMELog is preconfigured with PatternFormatter, no LogListener and empty allowed categories, disallowed categories and onlywitherror categories lists. Developer need to supply the type of LogListener to use declaratively (recommended) or programmatically. In other case no logging events will be generated.

The core of the MoMELog framework consists of 5 classes.

MoMELog also consists of three extensions:


Usage

Usage of MoMELog framework is pretty simple. It is very similar to that of log4J framework.

As mentioned in Description chapter, MoMELog doesn't support the notion of priority of logging. That's why, there are only two methods (defined in Logger class) intended to log messages and/or errors log(String message) and log( String message, Throwable error). First of them logs just the specified message and last - message and error. Any of the parameters can be null, of course.

Like in log4J framework, the above methods should be called on Logger instance. There are three static factory methods defined in Logger class Logger.getLogger(String category), Logger.getLogger(Class clazz) and Logger.getLogger() intended to return Logger instance. The first method returns Logger instance of specified category. In the second case category is the name of the given class (like from Class.getName() method). The last convenient Logger.getLogger() method returns Logger instance of default category, that is a slash (/). Besides, the same Logger instance is returned for the same category (case is significant), it is recommended to save reference to Logger instance in static variable.

For example, class Apollo is using MoMELog for logging.

public class Apollo
{
    // obtaining logger of Apollo category.
    private static final Logger log = Logger.getLogger( Apollo.class);

      ...

    public method launch()
    {
      // logging a message.
      log.log( "launch started.");

        ...

      try
      {

          ...

        // logging a message.
        log.log( "launch completed.");
      } catch( Throwable err)
      {
        // logging a message and error.
        log.log( "Huston we have a problem", err);

        ...
      }
    }

      ...
}

Configuration

  1. Programmatical Configuration
  2. Declarative Configuration

MoMELog is a simple logging framework. It does not require complex configuration. In general, it can be completely configured declaratively. But, some LogListener implementations can require additional programming work (e.g. LogCanvas).

MoMELog framework can be configured declaratively and/or programmatically. Declarative configuration is done by putting initialization file .momelog.txt (don't omit preceding dot ;-)) in the application's jar archive. This is a text properties file. MoMELog framework declarative configuration occurs at Logger class loading time. This gives developers possibility to override it programmatically.

MoMELog distinguishes general framework, formatter and listener configurations.

General framework configuration includes setting the type of Formatter to use for converting logging events to strings or any other objects, the type of LogListener to use for processing logging events (e.g. displaying them on a screen, saving in RMS, sending via http/https or appending to a file) and allowed categories, disallowed categories and onlywitherror categories lists to control logging of groups of loggers.

MoMELog is not preset with some type of LogListener. Developer needs to specify it declaratively (recommended) or programmatically. MoMELog framework is preconfigured to use PatternFormatter for converting logging events to strings. It is also preset with empty allowed categories, and onlywitherror categories lists (i.e. all loggers are allowed to log).

Formatter and listener configurations consist of setting Formatter and LogListener instances respectively. These configurations depend on particular Formatter or LogListener implementation used. See respective Formatter or LogListener documentation for details.

Declarative Configuration

As mentioned above, declarative configuration is done by putting initialization file .momelog.txt (don't omit preceding dot) in application's jar archive. This file is the text properties file. It's format is very simple. Lines must be terminated by new-line character ('\n'). All empty lines and lines, that consist only of spaces are ignored. All lines that start with pound sign (#) (preceding spaces are allowed) are considered as comments and ignored too. All other lines are considered as configuration lines and parsed. The format of configuration line is

  [S*]name[S*]=[S*]value[S*]

Spaces around names are always ignored. Significance of spaces around values depends on particular property.

If line is of invalid format, property name is unknown or property has invalid value, the warning message is printed to standard error output and offending line is ignored.

General Framework Configuration

MoMELog supports following general configuration properties. Spaces around all general configuration properties values are ignored. If any property is specified more than one time, the last prevails.

Property Name

Description

Default Value

"listener"

Name of Loglistener implementation class, to be instantiated and used for processing logging events. Specified class must be not abstract, must implement Loglistener interface and must have a null-arg constructor.

Note: If specified class can't be found, instantiated or doesn't implement LogListener interface, error message is printed to the standard error output and property is ignored.

MoMELog is preconfigured with no LogListener. If this property is not specified, developer must set it programmatically or no logging events will be generated.

Since version 1.0

None

"formatter"

Name of Formatter implementation class to be instantiated and used for converting logging events to strings. Specified class must be not abstract, must extend Formatter abstract class and must have a null-arg constructor.

Note: If specified class can't be found, instantiated or doesn't extend Formatter class, error message is printed to the standard error output and property is ignored.

By default, MoMELog is preconfigured with momelog.formatter.PatternFormatter formatter.

Since version 1.0

momelog.formatter.PatternFormatter

"allowedcategories"

Comma separated list of patterns. Logger instance can only log, if it's category matches at least one of the patterns in this list. Spaces around patterns and empty patterns are allowed and ignored. If this property is set to an empty string (the default), it is not considered (in other words all loggers are allowed.).

Pattern can contain any text and only one type of special character - asterisk (*). Asterisk, like in file regular expression, designates any number of any characters. Of course, pattern can contain zero or more asterisks. For example pattern "somepackage.*Screen", specifies categories that start with "somepackage." and end with "Screen".

Since version 1.0

empty string ("")

"disallowedcategories"

Comma separated list of patterns. Logger instance can only log, if it's category doesn't match any pattern in this list. Spaces around patterns and empty patterns are allowed and ignored. If this property is set to an empty string (the default), it is not considered (in other words all loggers are allowed.).

Pattern can contain any text and only one type of special character - asterisk (*). Asterisk, like in file regular expression, designates any number of any characters. Of course, pattern can contain zero or more asterisks. For example pattern "somepackage.*Screen", specifies categories that start with "somepackage." and end with "Screen".

Since version 1.0

empty string ("")

"onlywitherrorcategories"

Comma separated list of patterns. Logger instance, if it's category matches at least one of the patterns in this list, can only log, if logging event contains not-null error. Spaces around patterns and empty patterns are allowed and ignored. If this property is set to an empty string (the default), it is not considered (in other words all loggers are allowed.).

Pattern can contain any text and only one type of special character - asterisk (*). Asterisk, like in file regular expression, designates any number of any characters. Of course, pattern can contain zero or more asterisks. For example pattern "somepackage.*Screen", specifies categories that start with "somepackage." and end with "Screen".

Since version 1.0

empty string ("")

For example following initialization file snippet configures MoMELog to use PatternFormatter for converting logging events to strings, LogFile for making logging events accessible, disallows logging of logger of the "NotInterestingClass" category and allows only error logging of loggers with the categories that start with "somelibrary.".

  # configuring MoMELog to use PatternFormatter
  # this is redundant as MoMELog is preconfigured with it
  formatter = momelog.formatter.PatternFormatter

  # configuring MoMELog to use LogFile
  listener = momelog.listener.LogFile

  # disallows logging of NotInterestingClass logger
  disallowedcategories = NotInterestingClass

  # allows only error logging of somelibrary
  onlywitherrorcategories = somelibrary.*

Listener Configuration

LogListener can be configured declaratively from initialization file by specifying it's specific properties. All names of listener configuration properties must start with "listener." prefix. After this prefix removal, they are directed to the specific Loglistener implementation instance. See particular listener documentation for the list of supported properties.

MoMELog framework now contains LogCanvas and LogFile LogListener implementations. See LogCanvas Guide or LogFile Guide for the list of supported properties.

Formatter Configuration

Formatter can be configured declaratively from initialization file by specifying it's specific properties. All names of formatter configuration properties must start with "formatter." prefix. After this prefix removal, they are directed to the specific Formatter implementation instance. See particular formatter documentation for the list of supported properties.

MoMELog framework now contains only PatternFormatter formatter implementation. See PatternFormatter Guide for the list of supported properties.


Programmatical Configuration

As mentioned above, MoMELog framework can be configured declaratively and/or programmatically. Besides, declarative configuration is the preferred one, developers can configure framework programmatically. Also some Formatter or LogListener implementations can require some programming work to be performed. As MoMELog logging framework is intended to be used at development time and by developers, it is not considered as big problem. Programmatical configuration, of course, overrides declarative.

General Framework Configuration

All programmatical general framework configuration can be performed by using static methods of Logger class.

Instance of LogListener implementation to be used for making logging information accessible to the developer can be set by using Logger.setLogListener(LogListener listener) static method. Invoking this method with null unsets LogListener (or sets it to null). MoMELog is preset with no LogListener implementation. Developers need to set it or no logging events will be generated. Of course, it is more convenient to do this declaratively. Configured LogListener can be obtained by calling Logger.getLogListener() static method.

Instance of Formatter implementation to be used for converting logging events to strings or any other objects can be set by using Logger.setFormatter(Formatter formatter) static method. This method throws NullPointerException on null parameter. MoMELog is preset with PatternFormatter initialized with default pattern. Configured Formatter can be obtained by calling Logger.getFormatter() static method.

To control logging of different loggers MoMELog defines notions of allowed categories, disallowed categories and onlywitherror categories. They are a comma separated lists of patterns. Logger instance can only log, if it's category matches any pattern in allowed list and none in disallowed. If category of the Logger instance matches any of the patterns in onlywitherror list, it is allowed only to log events with errors. If any list is set to an empty string, it is not considered. Allowed categories, disallowed categories and onlywitherror categories lists can be set by invoking Logger.setAllowedCategories(String), Logger.setDisallowedCategories(String) and Logger.setOnlyWithErrorCategories(String) static methods respectively. Allowed categories, disallowed categories and onlywitherror categories lists can be obtained by calling Logger.getAllowedCategories(), Logger.getDisallowedCategories() and Logger.getOnlyWithErrorCategories() static methods respectively.

As mentioned in the Description chapter logging event has a property of timestamp, that is the long integer indicating time of issuing of this logging event. Actually, it is the number of milliseconds from some base time point till logging event generation. By default, this base time point is set to Logger class loading time. By calling Logger.resetBaseTime() static method base time point can be set to now.

All of the above static methods can be called at any time. In typical usage, of course, all these methods except Logger.resetBaseTime() are called at the start of the application (e.g. in MIDlet.startApp() method).

For example in MIDlet SomeMIDlet.

    ...

    protected void startApp()
    {
      if( !started)
      {
        // if MoMELog is configured to use LogCanvas declaratively it can be obtained by
        //logScr = (LogCanvas) Logger.getLogListener();

        // if MoMELog is not configured to use LogCanvas declaratively it should be instantiated.
        logScr =  new LogCanvas();

        // ordinary Canvas configuration.
        logScr.addCommand( BACK);
        logScr.setCommandListener( this);

        // LogCanvas specific configuration.
        logScr.setFont( Font.getFont( Font.MONOSPACE,FONT.PLAIN,Font.SMALL);

        // setting our pattern of PatternFormatter.
        // as MoMELog is preset with PatternFormatter
        // we don't need to instantiate it.
        ((PatternFormatter) Logger.getFormatter()).setPattern( "%.5C>%m %e at %t [%h]");

        // disallowing logging of  NotInterestingClass class.
        Logger.setDisallowedCategories( "NotInterestingClass");

        // configuring to receive only error logging from somelibrary
        Logger.setOnlyWithErrorCategories( "somelibrary.*");

        // if MoMELog is configured to use LogCanvas it is redundant
        Logger.setLogListener( logScr);

        ...

        started = true;
      }

      ...
    }

Listener Configuration

LogListener implementation used for processing logging events can also be configured programmatically. See particular LogListener documentation for details. All LogListener implementations should provide meaningful default values for their properties to minimize necessary configuration. Taking into consideration restrictions and specificity of J2ME architecture and functionality of some LogListeners, this is not always possible. Some LogListeners require programming work to be performed to make use of them. As MoMELog framework is intended to be used at development time, it is not considered as big problem.

MoMELog framework consists now of two LogListener implementations:

Formatter Configuration

Formatter implementation used for converting logging events to strings can also be configured programmatically. See particular Formatter documentation for details. All Formatter implementations should provide meaningful default values for their properties to minimize necessary configuration.

MoMELog framework consists now of only one formatter - PatternFormatter - formatter that converts logging events to strings based on configuration pattern. It's functionality and pattern's format resemble very much that of log4J framework. It provides meaningful default values for all properties and doesn't require configuration. See PatternFormatter Guide for details.



Sergio Morozov. 2007