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:
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.
All packages the Log Bundle imports are exported by bundles in the Framework package.
|
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.
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.
The OSGi Log Service Specification introduces four log levels indicating the severity of logged information:
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.
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.
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).
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).
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.
The Log Bundle registers the following services listed by interface:
|
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);
}
}
}
}
|
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.
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:
getLog, which returns
an enumeration of log entries (LogEntry instances) currently
residing in the log queue.LogListeners.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());
}
}
. . .
|
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:
getLogsById filters logs by bundle ID. Using this method is
helpful when you need to watch the behavior of a concrete bundle. The method
returns the log entries logged by the specified bundle, sorted by time (the
first entry returned is the one logged most recently).
getLogsByTime filters logs by user-specified period of time
given in milliseconds. Thus you can watch the behavior of all bundles within
a period of time.
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());
}
}
|
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; |
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.
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.
The Log Bundle provides the log group of commands in the framework text console for reading stored log messages.
|
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.
|
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.
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.
The Log Bundle uses the following system properties:
|
To change in the values of the above system properties, you should specify them:
mBS contains the Log Demo, which illustrates the usage of the Log Bundle.