Package de.mnl.osgi.jul2osgi
Installation
This bundle (the main bundle) works together with the bundlede.mnl.osgi.jul2osgi.lib
(the library bundle),
which provides a replacement for the default
LogManager
.
Replacing the LogManager
has the advantage that
all interactions with JUL can be intercepted.
The library bundle must be put on the JVM bootstrap classpath or the
framework classpath by the launcher because the Java runtime accesses the
LogManager
early during
application boot. The replacement LogManager
is made known to JUL
by invoking the JVM with the corresponding system property: "java
-Djava.util.logging.manager=de.mnl.osgi.jul2osgi.lib.LogManager ...
".
Usually, such system properties can be configured in the OSGi launcher.
Until the main bundle is started,
the LogManager
records all JUL LogRecord
in a buffer. The size of the buffer can be configured with the system
property de.mnl.osgi.jul2osgi.bufferSize
, which defaults to 100.
The main bundle is deployed as any other OSGi bundle
bnd launcher before 4.3.0
The library bundle can be put on the framework classpath with the-runpath
instruction
(bnd),
the property is set with the -runvm: ...
instruction.
Example configuration:
-runpath: de.mnl.osgi.jul2osgi.lib;version='latest' -runvm: -Djava.util.logging.manager=de.mnl.osgi.jul2osgi.lib.LogManager
bnd launcher starting with 4.3.0
With 4.3.0 the handling of the-runpath
instruction
has
changed. The library must therefore be added to the bootstrap classpath.
Because this does not add the exported packages to the system capabilities,
this must be done explicitly.
Example configuration:
-runvm: -Xbootclasspath/a:${repo;de.mnl.osgi.jul2osgi.lib;latest}, \ -Djava.util.logging.manager=de.mnl.osgi.jul2osgi.lib.LogManager -runsystempackages: \ de.mnl.osgi.jul2osgi.lib; version=1.4.2
Forwarding functionality
When the main bundle is started, it first requests an OSGI log service from the framework. When this service becomes available, the forwarder in the main bundle registers a callback with theLogManager
.
The LogManager
uses the callback to send all recorded and
future JUL LogRecord
s
to the main bundle. The forwarder converts the information from the
LogRecords
to calls of one of the methods of an OSGi
Logger
.
JUL LogRecord
properties are mapped in the following way:
- logger name: used as logger name when requesting the OSGi Logger.
- message: passed as message parameter (see below).
- level: used to choose the method to call.
FINE
is mapped to a call todebug
, anything below is mapped to a call totrace
. - thrown: passed to the OSGi logger, becomes the exception property
of the OSGi
LogRecord
.
Logger
was created and use it as origin of the event
when forwarding to OSGI logging. Only if determining the bundle
fails will the log event appear to have been created by bundle
de.mnl.osgi.jul2osgi
.
Special handling is applied by the forwarder if recorded log
entries are forwarded to the OSGi Logger
.
The implementation of the logger automatically derives a "thread info"
property for the newly created OSGI LogRecord
from the calling
thread. There is no way to override this automatically created value,
which is obviously wrong when a thread forwards log events that have
been recorded while executing other threads. Therefore the current
thread's name is added to the recorded information. When flushing the
recorded log events later, the name of the flushing thread is
temporarily set to the recorded name with "[recorded]
"
appended.
When using JUL, the message passed to the JUL Logger
isn't
necessarily what you see in your log. It is first used to lookup
a mapping in the ResourceBundle
associated with
the LogRecord
. Then, it is passed to a formatter that may
insert representations of parameters associated with the
LogRecord
. This processing is supposed to take place
during the final processing, i.e. in a JUL
Handler
.
The OSGi log service does not provide such sophisticated post-processing
of log entries. The message text and the parameters from the JUL
LogRecord
are therefore processed before forwarding the message
to the OSGi Logger
. In this respect, the forwarder behaves like a
JUL Handler
.
Before passing the post-processed message to the OSGi Logger
the forwarder applies another formatting operation. It invokes
MessageFormat.format(String, Object...)
with
a format string, the post-processed message and the remaining
information from the JUL LogRecord
. This allows the remaining
information to be added to the message sent to the OSGi log service.
The format
method is invoked as:
format(logPattern,
message, millis, sequenceNumber, sourceClassName, sourceMethodName,
threadID)
In order to e.g. add the source class name and method
to the log message the pattern "{3}.{4}: {0}
" could be used.
Filtering
Calls to the JULLogger
are filtered before further processing
according to the result from (JUL)
Logger.isLoggable(java.util.logging.Level)
and
by any configured JUL filter. Calls that pass this barrier are
forwarded to OSGi logging.
OSGi logging filters the forwarded events according to the level configured for the originating bundle and OSGi logger before accepting the event.
If you want log events to be delivered for levels lower than the
default levels, you must therefore lower the levels in both configurations.
Be aware that the default levels for JUL and OSGi logging differ. JUL
uses the default level INFO
while OSGi logging uses the default
level WARNING
.
In order to avoid unnecessary processing of eventually discarded log
events, filtering should preferably be configured using JUL. Anything
that passes this first barrier can then be accepted by OSGi logging
without further restrictions. Following this approach, the default
level for bundles using JUL should thus best be set to
LogLevel.TRACE
(see bundle property below).
Bundle properties
The following bundle properties are used to configure the described behavior.Property | Description | Default |
---|---|---|
de.mnl.osgi.jul2osgi.logPattern |
The final formating pattern | {0} |
de.mnl.osgi.jul2osgi.adaptOSGiLevel |
If set to true , the OSGi log level for the
originating bundle of a JUL log event will automatically
ne set to LogLevel.TRACE .
This results in the expected behavior that any log
message that has been enabled in JUL is visible in the
OSGi log. |
true |
-
Class Summary Class Description Forwarder