The log reference utility of the ProSyst Util Bundle offers support for creating logs in the two main log systems of mBS - the OSGi Log Service and the Tracer.
Contents:
The log utility, whose class is com.prosyst.util.ref.Log, forwards
message from a bundle to the OSGi Log Service (delivered by the Log
Bundle) or to the system output. In addition, the utility listens for events
concerned with the registration and unregistration of the Log Service, saving
this operation for bundles.
If the Log Service is not registered (i.e. the Log Bundle is not active) and the mbs.util.ref.log.autoPrintOnConsole system property is set to false , depending on its printOnConsole flag the log utility maps provided log messages to the system output (see " Displaying Logs in the Framework Console "). After the Log Service is registered, the utility forwards messages to the service.
To create a Log instance, call one of the following constructors:
Log(org.osgi.framework.BundleContext bc, boolean initDebug)
- For specifying the usage of the log utility's debug options.Log (org.osgi.framework.BundleContext bc) - For convenience
instead of calling Log(bc, true).The parameters of the Log constructors are as follows:
BundleContext bc - The BundleContext of the bundle writing
the logs. boolean initDebug - When true the flag indicates whether
the Log instance should initialize itself using the user defined
values of the mbs.util.ref.log.debug, mbs.util.ref.log.debug,
mbs.util.ref.log.autoPrintOnConsole and mbs.util.ref.log.printOnConsole
system properties. Otherwise, the default values of the log reference
utility system properties are used (no debug log messages will be logged and
printed in the framework console in case of errors and/or missing Log Service).For writing logs strictly compliant with the OSGi Log Service Specification,
the Log class defines separate methods for each log level:
debug(String str, Throwable ex)
For reasons of optimized performance, you should explicitly turn on processing of debug information as described in the "Turning Debug Option On" chapter.
error(String str, Throwable ex)info(String str)warning(String str, Throwable ex)Where str is the text of the log message and ex is
the Java exception being logged.
To check if the logs should be printed in the system output if the Log Service is not registered, use the isAutoPrintOnConsole() method of the log reference utility.
To check if logs with error and warning levels should be printed in the framework console, use the
isLogErrorLevel () method.
The following simple example illustrates the usage of the log reference utility on top of the Log Service. It writes a message with an info log level to the system output.
import org.osgi.framework.*; |
It is also possible to use the log reference utility - com.prosyst.util.ref.Log,
to send log messages written in the Log Service to a remote GUI application
through the Tracer
module or have them printed in a user-friendly format in the text console.
The log reference utility can also be used to trigger framework measurements and provide the received log information in a remote GUI application or print it in the text console. For more information about creating mixed logs, refer to the "Triggering and Logging Measurements" section of this document.
In addition, if the mbs.log.usedispatcher system property is true, the log utility takes advantage of the framework's log dispatcher for non-blocking printing of logged information in the text console.
Writing log message to the Tracer can be done with the following Log
methods corresponding to the log levels, defined in the OSGi Log Specification:
debug(int moduleID, int msgID, String msg, Throwable t, boolean
synch) error(int moduleID, int msgID, String msg, Throwable t, boolean
synch)info(int moduleID, int msgID, String msg, boolean synch) warning(int moduleID, int msgID, String msg, Throwable t, boolean
synch) The Tracer-enabled methods of the Log class take the following
parameters:
int moduleID - The ID of the module originating the debug message.
int msgID - The ID of logged message. Each message ID must
be unique within the whole bundle.String msg - Message text.Throwable t - The exception which has triggered the message
or null.boolean synch - A flag indicating whether to send the message
in a synchronous (synch is true) or asynchronous (synch
is false) manner to the client.Sometimes displaying module and message IDs for a message does not provide
a clear way to debug the behavior of an application. Through the setMaps
method you can provide a "Tracer Map" holding meaningful string equivalents
of used module and message IDs.
The Tracer Map has two parts:
In order to avoid definition of an additional hashtable
to keep module IDs, message IDs should be greater than 0 and module IDs
should have negative values, opposite to the ones used as module IDs in
the corresponding Log methods.
The Starts Map associates IDs of messages indicating operation termination ("end" messages) to IDs of messages from the ID Map, indicating operation start ("start" messages). For example if a message with text "Initialization" is mapped in the Starts Map to another message, the second one will be automatically displayed as "END OF Initialization" when its ID is used in a Tracer-enabled log method.
For convenience, a bundle can have a separate class for Tracer Map definition, as shown in the example that follows.
The following example illustrates the usage of logs on top of Tracer. The example periodically generates debug information by using notifications from the Timer service (Listing 2.1). Generated messages are shown in a user-friendly manner due to a defined Tracer Map (Listing 2.2).
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceReference; import com.prosyst.util.ref.Log; public class TimerToTracer implements BundleActivator, TimerListener {
private ServiceReference refTimer = null;
private Timer timer = null;
private final static String SERVICE_TIMER = Timer.class.getName();private static Log log = null; protected static final int MODULE_ID = 1; protected static final int ODD_SUBMODULE_ID = 11; protected static final int EVEN_SUBMODULE_ID = 12; private int EVENT_TYPE1 = 1; private int EVENT_TYPE2 = 2; int timerCounter = 1; boolean odd = true; public void start(BundleContext bc) throws Exception {
log = new Log(bc);
log.setDebug(true);
log.setPrintOnConsole(true);
// Defining the Tracer Map } public void stop(BundleContext bc) throws Exception {
if (timer != null) {
timer.removeListener(this, EVENT_TYPE1);
timer.removeListener(this, EVENT_TYPE2);
}
if (refTimer != null) {
bc.ungetService(refTimer);
}
if (log != null) {
log.close();
}
} // Method inherited from TimerListener and called by the Timer Service // when the specified time period expires. |
import com.prosyst.util.hash.HashIntObjNS; |
To perform the desired measurement, start the framework with measurements. For more information about launching the framework with measurements, refer to the "Starting the Framework with Measurements" part from the "Starting the Framework" document.
You can use the trigger(String module) method of the Log class to trigger measurements for the framework about memory consumption, threads count, etc., depending on the values of the framework measurements system properties and on the chosen Framework Measurement implementation.
Bundles can use one of the following methods to write logs about measured parameters:
debug(int moduleID, int msgID, String msg, Throwable t,
boolean synch, boolean measurement )debug(int moduleID, int msgID, String msg, Throwable t,
boolean synch, boolean measurement, boolean display)debug(int moduleID, int msgID, String msg, Throwable t,
boolean synch, boolean measurement, boolean display, boolean logInFile)The methods for logging values of measured parameters take the following parameters in addition to those described for the Tracer-enabled methods:
boolean measurement - A flag indicating whether the message
is a measurement or not.boolean display - A flag which indicates whether the message
should be displayed in a native GUI (display is true)
or not (display is false). boolean logInFile - A flag indicating whether the message should
be saved in the Log Service, and, in particular, in the service log file. Bundles can use the fault methods of the log reference utility to indicate failures in their performance:
fault (int level, String str, Throwable exc) - Has signature similar to the signatures of the methods for writing logs to the Log Service. The method indicates a fault, represented by exception exc, of level com.prosyst.mbs.framework.fm.FaultManager.NORMAL or com.prosyst.mbs.framework.fm.FaultManager.CRITICAL. When called, besides contacting the Fault Manager this method logs an error in the OSGi Log Service. fault (int level, int moduleID, int msgID, String msg, Throwable t, boolean synch) - Has signature similar to the signatures of the Tracer-enabled methods. The method indicates a fault, represented by exception t, of level com.prosyst.mbs.framework.fm.FaultManager.NORMAL or com.prosyst.mbs.framework.fm.FaultManager.CRITICAL in moduleID. When called, besides contacting the Fault Manager, this method logs an error in the Tracer module. The log reference utility also provides means to write big logs as binary data in files without storing them in the OSGi Log Service so as to avoid service's overload.
As this option of the log reference utility is not related to the OSGi Log Service, there are no predefined log levels. Instead, logs are associated with a base name, which can be used to represent an application-specific type of log messages.
Each base name, i.e. custom log type, is handled by a separate instance of
the Log class. To obtain such an instance capable of storing log
files, you should use the Log(String baseName, boolean synch, org.osgi.framework.BundleContext
bc) constructor. The constructor takes the following parameters:
String baseName - The base name of the future logs boolean synch - A flag, which indicates if writing logs should be done in a blocking way (when true) or in a non-blocking way by using a separate short-run thread (when false). BundleContext bc - The BundleContext of the bundle writing the logs. Next, to write down log information, use one of the trace methods. If the synch flag has been set to true in the Log constructor, then the trace method won't return until the log is saved.
As a result, the Log instance saves logs in a <base_name>
file within the directory specified with the mbs.logsDir system
property. By default, this directory is called logs and is located in
the working directory of the OSGi framework (bin/vms/<vm_name>).
The com.prosyst.util.ref package contains an extension to the Log class, called ManagedLog, which allows introducing and configuring levels of log information manageable by means of OSGi-compliant configuration dictionaries.
ManagedLog identifies log levels by using integers and associates each level with the ID of a specific boolean configuration property. Based on the current value of the corresponding configuration property, a ManagedLog can indicate if a log level is switched on or off.
ManagedLog implements org.osgi.service.cm.ManagedService, which is registered as a service with a custom PID in the OSGi framework when instantiating the log. In addition, you can attach a parent ManagedService to a ManagedLog - it may be provide some non-log properties. The properties of the parent ManagedService will be updated along with the properties of the log itself.
The log management mechanism implemented in ManagedLog is founded on two log levels - DEBUG_ALL and PRINT_ON_CONSOLE. Other, custom, levels are handled only if both DEBUG_ALL and PRINT_ON_CONSOLE are enabled.
Note: A custom log level should be a number between 2 and 32. Levels 0 and 1 are reserved for the pre-defined ManagedLog levels DEBUG_ALL and PRINT_ON_CONSOLE.
Once created, a ManagedLog can be used for the operation described above - writing messages to the Log Service and to the Tracer, signaling fault situations and writing binary logs in a file.
To describe to the ProSyst implementation of the OSGi Configuration Admin the properties that the configuration dictionary of a ManagedLog contains, you should provide a metadata XML. Besides the properties representing custom log levels, this XML should include the properties for debug and print-on-console - they have IDs respectively DEBUG_ALL and
PRINT_ON_CONSOLE.
Depending on the purpose it will be used for, call the proper constructor to create a ManagedLog object:
ManagedLog (BundleContext bc, HashIntObjNS mapping, String pid, ManagedService parentMS) ManagedLog (String baseName, boolean synch, BundleContext bc, HashIntObjNS mapping, String pid, ManagedService parentMS)ManagedLog-specific constructor parameters are as follows:
HashIntObjNS mapping - Contains the log level/property ID pairs associated with this ManagedLog. To be able to use custom levels, you must include the pairs DEBUG_ALL/DEBUG_ALL_PROP and PRINT_ON_CONOSLE/PRINT_ON_CONSOLE_PROP in the mapping hashtable.String pid - Contains the PID of the configuration dictionary, constructed according to the content of the mapping argument and exported by this ManagedLog. ManagedService parentMS - Contains a parent ManagedService, which may be associated with other non-log properties. Can be null.To check if the general debug (DEBUG_ALL) and print-on-console (PRINT_ON_CONSOLE) levels are enabled, use respectively the getDebug and getPrintOnConsole ManagedLog methods.
To check if a specific custom log level is on in the configuration dictionary, use the getLevel method.
Following is a simple example illustrating the usage of the ManagedLog utility. Basically, the example creates a ManagedLog, configurable under the my.log.pid PID. The ManagedLog has log levels ManagedLog.DEBUG_ALL, ManagedLog.PRINT_ON_CONSOLE and MY_PROP. The last level is a custom, defined for illustration. In addition, the log is assigned a simple parent ManagedService with a String property "property1" and an int[] property "property2".
Then, each 10 seconds the example checks the status of the defined logs levels and if all of them are on, prints an information message to the system output.
The example has a common configuration metadata XML, describing the properties of the parent ManagedService and of the ManagedLog.
Tip: You can turn on and off the example's log levels by using the mConsole or the config console commands.
<metatype-provider>
<objectclass>
<locale>en</locale>
<name>My Log Debug Configuration</name>
<id>my.log.pid</id>
<description>Configuration illustrating logging of messages and
errors.</description>
<attribute modifier="req">
<name>PRINT ON CONSOLE</name>
<id>PRINT_ON_CONSOLE</id>
<description/> |
The above XML file, let's name it log_config.xml, should be included in a bundle JAR and declared in a Config manifest header under the my.log.pid PID:
Config: xml=log_config.xml; pid=my.log.pid; name=My Log Debug Configuration
The following ManagedService simply prints to the system output in the updated method the values of two properties, "property1" and "property2".
import java.util.Dictionary; import org.osgi.service.cm.ConfigurationException; import org.osgi.service.cm.ManagedService; |
The following class, ManagedLogTest, represents a bundle activator which starts a job, CheckPropertiesJob, for periodic check of the current log status. The job implements the Runnable interface and is executed in a thread supplied by the Thread Pool Manager.
import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.ServiceReference; import com.prosyst.util.hash.HashIntObjNS; import com.prosyst.util.ref.ManagedLog; import com.prosyst.util.threadpool.ThreadPoolManager; |
import com.prosyst.util.ref.ManagedLog; public class CheckPropertiesJob implements Runnable {
private Object synch = null;
ManagedLog log = null;
private boolean running = false; public CheckPropertiesJob(ManagedLog log) {
this.log = log;
synch = new Object();
running = true;
} public void run() {
while (running) {
synchronized (synch) {
try {
// Waiting 10 seconds // Checks if MY_PROP is on along with DEBUG_ALL and PRINT_ON_CONSOLE. void stopJob() {
synchronized (synch) {
running = false;
synch.notify();
} |
For debug messages (i.e. written with the debug method), log utility's
debug option should be turned on through:
setDebug method called by an individual application. In
this case, the log utility will process only the debug messages, produced
by the application.ManagedLog, the DEBUG_ALL configuration property. The ManagedLog will internally turn debugging on. mbs.util.ref.log.debug system property. In
this case, the log utility will process the debug messages of those applications
that instantiate the Log class after property has been set to true, use the Log(BundleContext, boolean) constructor and do not specify explicitly that debug is off with the setDebug method.
Otherwise, the log utility will not forward debug logs to the OSGi Log Service or the Tracer.
import com.prosyst.util.ref.Log; |
The log reference utility allows viewing log messages for the OSGi Log Service and Tracer in the framework text console. To turn this option on, the utility should be set to print messages in the system output through:
setPrintOnConsole method which is used in case the Log Service is registered. setAutoPrintOnConsole method which enables message printing in case the Log Service is not registered.ManagedLog, the PRINT_ON_CONSOLE configuration property. The ManagedLog will internally turn on printing generated logs to the system output. mbs.util.ref.log.printOnConsole system property. In this
case, the log utility will print the messages of those applications that instantiate the Log class after property has been set to true, use the Log(BundleContext, boolean) constructor and do not specify explicitly that printing is off with the setPrintOnConsole method. mbs.util.ref.log.autoPrintOnConsole system property. In this case, the log utility will print the messages of those applications that instantiate the Log class after property has been set to true, use the Log(BundleContext, boolean) constructor and do not specify explicitly that automatic printing is off with the setAutoPrintOnConsole method.Tip: Similarly to enabling the debug option of the log utility (see Listing 3), you can introduce a "print" flag for printing generated logs to the system output.
If you no longer need the utility, you should call its close method to dispose engaged resources.
The log reference utility has two system properties for configuration, which apply to all applications using the log utility.
|
| Socket Factory and Event Interfaces | Date, Encode, HTML, INI, Security and XML Utilities |