Log Bundle

The Log Bundle provides the Log Service, which implements the OSGi Log Service Specification and extends it with new functionality. Log Bundle can be assumed as core for mBS as many bundles use its abilities for writing and reading logs.

Contents:


Bundle Information

Bundle JAR

The Log Bundle has two JAR files, both in the bundles directory, designed specifically for the two versions of the framework - log.jar should be used with the Standard Version and logmio.jar should be used with the Connector Version.

Import

All packages the Log Bundle imports are exported by bundles in the Framework package.

Package Exporter Description
com.prosyst.mbs.framework.event System Bundle/
ProSyst Util Full Bundle
Enables event dispatching within the framework.
com.prosyst.util.hash ProSyst Util Bundle/
ProSyst Util Full Bundle
Provides hash table utilities.
com.prosyst.util.io System Bundle/
ProSyst Util Full Bundle
Contains utilities for object serialization.
com.prosyst.util.pcommands ProSyst Util Bundle/
ProSyst Util Full Bundle
Contains the API for implementing pluggable text commands.
com.prosyst.util.text Provides support of standard date formats.
com.prosyst.util.threadpool Contains the Thread Pool Manager, which provides active reusable threads from a pool.
com.prosyst.util.time Provides a native equivalent of the System.currentTimeMillis method.
com.prosyst.util.timer Contains the Timer service for time-based notification.
org.osgi.service.cm OSGi Library Bundle Contains the API of the OSGi Configuration Admin Service Specification.
org.osgi.service.event Contains the API of the OSGi Event Admin service.
org.osgi.service.log Contains the API of the OSGi Log Service Specification.
org.osgi.util.tracker Contains the OSGi Service Tracker utility.

Export

The Log Bundle exports the com.prosyst.mbs.services.log package providing a utility filtering log entries by bundle ID and time, and a service for remote access to stored logs over PMP.


Principles of Work

Logs are objects holding useful information about the runtime behavior of a service or bundle, such as operation results, thrown exceptions, service references, etc. However, it is recommended to use logs mainly for events and errors.

Log Levels

The OSGi Log Service Specification introduces four log levels indicating the severity of logged information:

Log Maintenance

Log entries are placed in a queue with user-defined capacity and reader applications can get no more entries than this capacity is. To optimize log system performance, the queue can also be set to keep only messages with severity level equal or less than a specified threshold level.

Log Files

Keeping too many messages in the queue for a long time is not reasonable. That's why to preserve log information from an accidental crash, queued log entries are persistently saved in a log file (log.txt) when:

Stack traces of logged exceptions are stored in another file, strace.txt, under unique throwable IDs. In such case, log.txt contains only throwable IDs thus associating log entries with appropriate stack traces.

Log Files Location

The initial text file with log entries (log.txt) is located in <storage_dir>/<log_bundle_ID_dir>/<log_bundle_update_No_dir>/data/logs, where:

Example: bin/vms/jdk/storage/6/3/data/logs - the Log Bundle is with ID 6 and its version is 3.

The Log Bundle can be configured to keep its log files outside the framework storage by using the toExternalStorage and externalPath configuration properties (see the "Configuration" chapter).

Backup Mechanism

When the size of the log.txt and strace.txt files reaches a specified limit, they are backed up and the initial files are recreated. Backup files are numbered separately with the most recently created file having the highest number.

Note: When log messages are written too fast to the Log Bundle, the log files may exceed dramatically the stipulated size. This is because some time is necessary to create the new files, after the moment when the maximum file size is reached.

When the number of backup files exceeds a specific count, the oldest one (the one with suffix "_0") is deleted and the rest are renamed as their sequence number is decremented by 1 (e.g. log_23.txt will become log_22.txt).

Issue on Log Storage in the Connection Version of the Framework

When running the Log Bundle in the Connector Version of the framework with enabled resource management, due to the restrictions on bundle storage space (default or declared in its resource requirement file), the Log Bundle may receive notification that there is no more place in the storage to record entries. Then the bundle tries to free space by first deleting backup files. If there still isn't enough place for recording new logs, it deletes the log.txt and strace.txt files.

Services

The Log Bundle registers the following services listed by interface:

Service Description
com.prosyst.mbs.services.log.LogFilter Represents the Log Filter Service.
com.prosyst.mbs.services.log.RemoteLogReader Used for getting information for the log entries, kept by the Log Service, via PMP.
com.prosyst.util.pcommands.PluggableCommands Represents the commands that the Log Bundle provides to the framework or Telnet console.
org.osgi.service.cm.ManagedService Provides the configuration of the Log Bundle for management by the OSGi Configuration Admin Service. See Config Bundle documentation for details.
org.osgi.service.log.LogReaderService Represents the OSGi Log Reader Service.
org.osgi.service.log.LogService Represents the OSGi Log Service.

Log Service

The Log Service is developed according to the OSGi Log Service Specification and keeps information such as time, message, bundle caller, etc., in log entry objects. When writing a message to the Log Service, specify the attributes:

Note: If a log is received with a log level different from the predefined ones, the Log Service still keeps the log in the queue. This allows bundles to define their own log levels if needed.

Tip: The ProSyst Util Bundle offers a convenient utility for writing logs in the OSGi Log Service saving some common operations to bundles using it. For further details, refer to the "Log Reference Utility" document.


                             . . .
import org.osgi.service.log.LogService;
import java.net.ServerSocket;
import java.io.IOException;
  
public class LogServiceSample {
  private LogService logService;
  private ServerSocket serverSocket;
  private final static int PRIMARY_PORT = 80;
  private final static int SECONDARY_PORT = 8080;
  
                             . . .

  public LogServiceSample(LogService logService) {
    this.logService = logService;
  }
                             . . .

  public void test() {
    logService.log(LogService.LOG_DEBUG, "Testing LogService...");

    try {
      serverSocket = new ServerSocket(port);
      logService.log(LogService.LOG_INFO, "Test server started and listening at " 
                   + PRIMARY_PORT + " port!");
    } catch (IOException ex) {
      logService.log(LogService.LOG_WARNING,
                   "The primary port is in use. Trying to bind to secondary port " 
                   + SECONDARY_PORT, ex);

      try {
        serverSocket = new ServerSocket(sec_port);
        logService.log(LogService.LOG_INFO, "Test Server started and now listening at "
                   + SECONDARY_PORT + " port!");
      } catch (IOException ioex) {
        logService.log(LogService.LOG_ERROR, "Can't open server socket. Port "
                   + SECONDARY_PORT + " is in use!", ioex);
      }
    }
  }
}
Listing 1: Using the Log Service

The example above tries to open a socket. If this operation fails at the primary port, which here is the default HTTP port 80, a Warning log entry is created. Then we try to open socket on the secondary port (8080) and in case it is successful an Info log entry is created, otherwise Error is logged. In both Warning and Error entries, the exception that occurred is included in the log entry.

Log Reader Service

The Log Reader Service is defined by the OSGi Log Service Specification and provides access to the log entries, written in the Log Service. Bundle developers are allowed to get past log entries and to receive notifications about new ones.

There are two mechanisms for retrieval of log entries:

The example below illustrates the usage of the getLog method. On each LogEntry the getMessage method is called to obtain its human readable message and the getLevel method - to have its severity level.

                             . . .

import org.osgi.service.log;
                             . . .

  private LogReaderService logReaderService;
                             . . .
  public void get(){
    LogEntry logEntry;

    // Puts logs in an enumeration
    Enumeration enum = logReaderService.getLog(); 

    while (enum.hasMoreElements()) {
      logEntry = (LogEntry)enum.nextElement(); 

      // Prints messages with severity level
      System.out.println("Level:" + logEntry.getLevel() + 
                         " - logEntry Message: " + logEntry.getMessage()); 
    }
  }
                             . . .
    
Listing 2: Using the Log Reader Service's getLog method and LogEntry's methods for retrieving information.

Log Filter Service

The Log Filter Service, available under the com.prosyst.mbs.services.log.LogFilter interface name, provides methods for getting log entries by using a filter.

There are two methods for filtered retrieval of log entries:

import com.prosyst.mbs.services.log.*;  

                             . . .
  private LogFilter logFilter;

                             . . .
  public void filter(){

    // Gets the current time in milliseconds
    long time = System.currentTimeMillis(); 
    Enumeration enum;
    LogEntry logEntry;

    // Puts filtered logs in an enumeration
    enum = logFilter.getLogsByTime(0,time);  
    
    while(enum.hasMoreElements()) {
      logEntry = (LogEntry)enum.nextElement();

      // Prints log entries
      System.out.println("Log Filter Entry: " + logEntry.getMessage()); 
    }
  }

Listing 4: Using the Log Filter Service.

Remote Log Reader

The Remote Log Reader (com.prosyst.mbs.services.log.RemoteLogReader) is intended for use over PMP from a remote OSGi framework. The Remote Log Reader combines basic functionality of LogReader and LogFilter (getLogs, getLogsById), as well as provides some additional methods like getLogFileNames and getLogFile.

import java.util.Properties;
import com.prosyst.mbs.services.pmp.PMPConnection;
import com.prosyst.mbs.services.pmp.PMPException;
import com.prosyst.mbs.services.pmp.PMPService; import com.prosyst.mbs.services.pmp.RemoteMethod; import com.prosyst.mbs.services.pmp.RemoteObject;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class RemoteLogTester implements BundleActivator {
public void start(BundleContext bc) { PMPService pmpService = null;
// Getting the PMP Service from the service registry of the OSGi framework
. . . Properties login = new Properties(); login.put(PMPService.USERNAME, "admin"); login.put(PMPService.PASSWORD, "admin"); try { // Connecting to the remote PMP Service
PMPConnection connection = pmpService.connect("socket://127.0.0.1:1449", login); // Getting the Remote Log Reader as a reference and invoking
// its methods
RemoteObject service = connection.getReference( "com.prosyst.mbs.services.log.RemoteLogReader", null); RemoteMethod method = service.getMethod("getLogFileNames", null); String[] logFiles = (String[]) method.invoke(null, true); for (int i = 0; i < logFiles.length; i++) { System.out.println("[RemoteLogTester] logFile: " + logFiles[i]); } } catch (PMPException e) { // e.printStackTrace(); } }
public void stop(BundleContext bc) {
// Releasing all engaged resources and ungetting the PMP Service
. . .
} }
Listing 5: Using the Remote Log Reader Service in a PMP application.

Pluggable Commands

The Log Bundle registers a Pluggable Commands service, which adds to the Parser Service the log command group accessible from the framework text console. Log commands are described in the "Console Commands" chapter below.

Managed Service

The Log Bundle registers a Managed Service with service PID - mbs.log.pid, enabling configuration of some of the bundle's runtime parameters through the OSGi Configuration Admin Service (implemented by the Config Bundle).

You can configure the Log Bundle to "hide" (not register) its ManagedService by setting mbs.log.registerManagedService system property to false.


Console Commands

The Log Bundle provides the log group of commands in the framework text console for reading stored log messages.

Command Shortcut Description
next n Prints next 10 log messages.
prev p Prints previous 10 log messages.
info [<ID>{ <ID>}] i Prints informational messages. You can specify one or more bundles IDs of interest.
error [<ID>{ <ID>}] er Prints error messages. You can specify one or more bundle IDs of interest.
warning [<ID>{ <ID>}] w Prints warning messages. You can specify one or more bundles IDs of interest.
debug [<ID>{ <ID>}] d Prints debugging messages. You can specify one or more bundles IDs of interest.
all [<ID>{ <ID>}] a Prints all messages. You can specify one or more bundles IDs of interest.
view <number>{ <number>} v Prints the exceptions with the specified throwable IDs.
clear - Saves buffered logs and clears the logs left in memory.


Configuration

Configuration Resources

The Log Bundle registers a Managed Service with name Log Configuration and PID mbs.log.pid. Through the properties exported by this Managed Service, specific parameters of the Log Bundle's performance can be modified through the OSGi Configuration Admin Service.

Tip: You can "hide" the mbs.log.pid configuration by setting the mbs.log.registerManagedService system property to false. In such a case, the Log Bundle will be configurable only by means of its system properties.



Configuration Property Name Type Description
backupFileCount
BackupFileCount
integer The maximum number of log backup files to be created.
externalPath
External Path for Log Files
String Optional. A path to an external directory where the log files will be stored. The property is taken into account when toExternalStorage is true.
By default this is logs in the framework startup directory.
fileLength
Log/Stack Trace File Length
integer The maximum length of the log/stack trace file in KB, over which it will be backed up and another initial file will be created.
logCount
Log Count
integer Maximum number of logs stored in the queue.
osgievents Store OSGi events boolean If true, framework, bundle and service events will be logged. Defalut is false.
storeTimeout
Timeout to Store
integer The time in seconds, after which logs in the queue are stored persistently. If this property is set to 0, saves will be done when the queue gets full.
thresholdLevel
Threshold Level
integer The severity level, beyond which logs are not kept in the queue. Its design goal is to prevent the queue from getting filled with unnecessary logs.
toExternalStorage
Store Outside Server Storage
boolean Optional. A flag for writing log files to the external location, specified by the externalPath property.
toStore
Store Logs
boolean A flag telling whether logs should be saved in log files.

Visual Administration

Log Configuration

The operational parameters of the Log Bundle, exported by its Managed Service, can be conveniently configured through the mConsole and its general property editor. The bundle configuration is accessible under the Log Bundle/Log Configuration node.


Figure 1: Configuring the Log Bundle through mConsole.

You can use the Edit button to include/exclude the configuration properties for external storage.

Use the Set button to apply modifications on the configuration and Defaults to load default property values in the configuration dictionary. In case another administrator has changed some properties in the meanwhile, use Refresh to get the changes.

Log Reader

Through the Log Reader custom property editor you can view all queued logs or filter them by bundle ID and level, as well as access the content of log.txt and strace.txt and their backups. The Log Reader editor is available in the mConsole's bundles tree as a child of the Log Bundle node.

Viewing Log Entries. The Log Messages tab of Log Reader shows the log entries currently kept in the log queue. Initially, the tab shows no information until the Get Messages button is used.


Figure 2: Using mConsole for logs from the queue.

Use check boxes to specify what type of logs you want to retrieve and then the Get Messages button to retrieve them from the queue.

If you are interested in a concrete bundle, fill in its ID and click the Search by ID button.

The Log Reader also allows you to search for an expression in the selected message by using the Find button.

Viewing the Content of Log Files. The Log Files tab of Log Reader allows you to view the content of stored log files. As the tab initially shows no information, load the files through the Get Files button.


Figure 3: Getting the content of log files in the mConsole.

You can save a selected log file under a different name for later use, print it and check it for a specific expression.

System Properties

The Log Bundle uses the following system properties:

System Property Default Value Description
mbs.log.callback.timeout 10 Defines the time in seconds a LogListener will be waited to return from its logged method. If this time is exceeded, a new thread is created to process the other LogListeners. The current thread is stopped after the logged method finishes and the hanging LogListener is removed.
mbs.log.registerManagedService true Turns on or off the availability of OSGi-compliant configuration for the OSGi-based log system.
mbs.log.debug false Turns on or off generation of debug information about the runtime operation of the Log Bundle.
mbs.log.console false Prints the debug output in the framework's text console.
mbs.measurements.full false Enables generation of information about the startup time of different functional parts of the Log Bundle.
mbs.measurements.bundles

To change in the values of the above system properties, you should specify them:


Demo

mBS contains the Log Demo, which illustrates the usage of the Log Bundle.


References


OSGi Bundles