Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Corona Logging

Revision as of 10:34, 17 January 2007 by Marcin.okraszewski.compuware.com (Talk | contribs) (Required Bundles)

Corona Logging Architecture

Corona logging is an extension uses OSGi Log Service with some additional features like log management. Corona Logging takes an assumption that there is a logger per bundle (granularity is bundle). The architecture of the Corona Logging is shown at the picture below:

Coronalog.png

Log layers (vertical):

  • Corona Log Service provides a class which is used for logging.
    • It implements the same interface as the OSGi Log Service, but it wraps the OSGi Log Service, so that code do not need to take care if the log service available, and use code for checking if log service object isn't null.
    • Any code that expects to operate on OSGi Log service interface, can still work without changes, because the same class has implements the same interface.
    • It provides a method to check if the bundle is in debugging mode or what is the log level, so the application flow may depend on those information.
    • Any code that already uses OSGi Log service can still do it and bypass Corona Log service.
  • OSGi Log Service is a standard OSGi Logging service. It is wrapped by Corona Log Service. The OSGi Log Service do not write log entries anywhere, it is just a mediator between log producer and log consumer.
  • By default Corona provides a Log4j log consumer. Logs from OSGi Log Service are logged with Log4j. With default configuration entries are logged to console, file and Eclipse log.
  • other logging target is any other log consumer. For instance you may want to write log messages to syslog, java.util.logging or any kind of your logging mechanism.

Log management layers (horizontal):

  • Corona Log Manager is an OSGi service implementing org.eclipse.corona.log.ICoronaLogManager. It is used to manage the logging infrastructure.
    • Any part of the code may use the log manager through the OSGi service.
    • At the moment the log manager can control log level for each bundle and its debugging mode.
    • Corona Log Manager uses DebugOptions service to read log level settings.
  • Corona Log Manager modifies the settings in the infrastructure by sending OSGi Events.
    • Any new component may register to the events an change its settings according to message.
    • Log manager do not contact directly with any logging layer, but logging layers can contact with log manager (by OSGi service)
  • By default functionality of the Corona Log Manager is exposed with OSGi console, WSDM and JMX
JMX only if Joel's new management annotations will work with JMX - issue 170650

OSGi Log Service

Corona Logging uses OSGi Log Service. OSGi specifies two log services:

  • Log Service - allows bundles to log information including a message, a level, an exception, a ServiceReference object, and a Bundle object
  • Log Reader Service - allows bundles to access a list of LogEntry objects, and allows the registration of a LogListener object that receives LogEntry objects as they are created.

To extend control over log statements log4j package is used. It is plugged into Corona through the LogListener object registered with the use of the OSGi Log Reader Service.

For details on OSGi services see: OSGi Service Platform, Service Compendium, Release4, August 2005.

Required Bundles

Bundles/classes/libraries required by Corona Logging:

  • bundle: org.eclipse.corona.logger.log4j
    • class: org.eclipse.corona.logger.log4j.listeners.Log4jListener -> log listener converting OSGi log events to log4j logs
    • class: org.eclipse.corona.logger.log4j.Log4jBundleActivator -> bundle activator responsible for log4j listener initialization and registration within OSGi Log Reader Service
    • class: org.eclipse.corona.logger.log4j.appenders.EclipseLogAppender -> log4j appender responsible for sending logs to eclipse platform (when eclipse application is run/debug, eclipse platform registers a listener responsible for sending logs events to Error Log view), class not required by Corona Logging
    • log4j.properties -> configuration of log4j loggers, appenders, layouts etc.used by Corona


  • bundle: org.apache.log4j_1.2.13
    • library: log4j-1.2.13.jar -> log4j package


  • bundle: org.eclipse.corona
    • class: org.eclipse.corona.log.CoronaLogService -> Log Service wrapper responsible for:
      • retrieval of LogService reference
      • retrieval of DebugOptions service reference - service responsible for loading debug tracking options defined with the use of .options file. For detailed information see: Eclipse Debug Options chapter.
      • enabling LogService API
    CoronaLogService wrapper is to be used by any Corona bundle activator. See: Sample Bundle Activator using CoronaLogService.
    • interface: org.eclipse.corona.log.ICoronaLogManager registered as OSGi service. It is responsible for changing log level for bundles.


Corona Logging Configuration

To assure that OSGi Log Service and Log Reader Service is registered and available:

  • modify config.ini (located inside: ${eclipse_home}/configuration) by adding to osgi.bundles the following: org.eclipse.osgi.services@2:start, org.eclipse.equinox.log@3:start, org.eclipse.corona.logger.log4j@4:start
  • start/restart eclipse workbench.

To define loggers and appenders for Corona:

  • modify log4j.properties located inside org.eclipse.corona.logger.log4j bundle
  • restart org.eclipse.corona.logger.log4j bundle.
  • note that logger levels will be overridden with log level settings from Corona log manager.

Change bundle log level and debug flag:

  • start eclipse workbench with the command line argument -debug [.options file path].
    • If no .options file path is specified, expected location is ${eclipse_home}/.options. Command line argument -debug is equivalent to setting osgi.debug inside config.ini.
    • For details on debug tracking options see: Eclipse Debug Options.

Corona Custom Test Level

Corona provides a custom log4j level called TestLevel. New level should be used in Corona's test cases, which should store test information in separate files.
Short tutorial, on how to use custom test level.

  • log4j.properties file has to be enhanced, loggers should be informed that new TestLevel should be used:
  log4j.rootLogger=test#org.eclipse.corona.logger.log4j.levels.TestLevel, console


  • To log something with TestLevel, use following line:
  logger.log(TestLevel.TEST, "This line will be logged");


  • To test whether TestLevel is enabled, use:

  if (logger.isEnabledFor(TestLevel.TEST)) {
           // log test here.
  }


Eclipse Debug Options

Using -debug option (or equivalently setting osgi.debug property inside config.ini) allows for starting any eclipse application in a debug mode. The value of -debug option is treated as the location of .options file. If there is no file path defined after -debug, expected location of .options file is ${eclipse_home}/.options.

.options file content:

<bundle_name>/debug=true|false
e.g.
org.eclipse.corona.common.collaboration/debug=true

When -debug option is specified and .options file is found, DebugOptions service is registered and available. This service is responsible for loading debug tracking options from .options file. Calling eclipse -debug [.options_path] will start eclipse platform and use [.options_path] for locating and loading debug tracking options (one .options file is used). Debug level logs will be filtered, unless debug property for given bundle is set to true.

For development .options can be added to any created plugin/bundle root directory. Such bundles' .options are used by the Tracing tab of the eclipse Run/Debug dialog. The Tracing tab allows for specification of the list of bundles with debug tracking enabled. TracingTab2.JPG </div>


Changing Logging Parameters in Runtime

It is possible to change log settings in runtime. There are special OSGi console commands prefixed with cl (Corona Logger) to do this. The most up-to-date list of commands is available after typing help command. At the moment of writing, following commands were available:

  • clInfo - displays all information about logging
  • clGetDefLevel - displays the default log level
  • clSetDefLevel <LEVEL> - sets a new default log level
  • clGetLevel <logger> - displays a log level of a specified logger
  • clSetLevel <logger> <LEVEL> - sets a new log level for a logger

Where:

  • logger is equal to plugin name; list of loggers is displayed in clInfo command
  • LEVEL values: ALL, DEBUG, TRACE, INFO, WARN, ERROR, FATAL, OFF

Sample Bundle Activator Using CoronaLogService

package org.eclipse.corona.test.log;

import org.eclipse.corona.log.CoronaLogService;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;
import org.osgi.service.log.LogService;


/**
* The activator class controls the plug-in life cycle
*/
public class Activator extends AbstractUIPlugin {

// The plug-in ID
public static final String PLUGIN_ID = "org.eclipse.corona.test.log";

// The shared instance
private static Activator plugin;

// Corona Log Service wrapper
private static CoronaLogService logService = new CoronaLogService();

/**
* The constructor
*/
public Activator() {

plugin = this;

}

/**
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
*/
public void start(BundleContext context) throws Exception {

super.start(context);

// starting Corona Log Service
logService.start(context);

logService.log(LogService.LOG_DEBUG, "starting test log activator...");

}

/**
* (non-Javadoc)
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stop(BundleContext context) throws Exception {

plugin = null;

// stoping Corona Log Service
logService.stop(context);

super.stop(context);

}

/**
*
*
*/
public void testMethod() {

logService.entering("Activator.testMethod()");

// doing nothing ...

logService.exiting("Activator.testMethod()");

}

/**
* Returns the shared instance
*
* @return the shared instance
*/
public static Activator getDefault() {

return plugin;

}

/**
* Returns the logger shared instance
*
* @return the logger shared instance
*/
public static CoronaLogService getCoronaLogService() {

return logService;

}

}


To access Corona Log Service from other bundle classes call: Activator.getCoronaLogService().log(...);


Back to the top