Part 3 explains how to catch all log events logged by OSGI Bundles using OSGI Log Services.
In part 2 you've seen that catching log entries from "classic" Log - Frameworks was very easy:
- ✓ Choose the right bundles
- ✓ Create a config - file
-thats all :-)
Remark: java.util.logging needs also this one-liner: SLF4JBridgeHandler.install();
Running an OSGI Enterprise Application you'll also find bundles logging their log - entries using OSGI Services:
- org.osgi.service.log.LogService
- org.osgi.service.log.LogReaderService
You have also to watch for Services extending the "normal" OSGI Log Services: Eclipse Riena per ex. uses from Equinox Incubator:
- org.eclipse.equinox.log.ExtendedLogService
- org.eclipse.equinox.log.ExtendedLogReaderService
You can read Log entries using the LogReaderService. You only have to register your LogListener.
The LogListener gets all LogEntry (ExtendedLogEntry), then you can log them using SLF4J-API to your LOGBack Implementation.
You have to use the same config file (logback.xml or logback-test.xml) as described in part 2 (logging the entries from „classic“ Log - frameworks). Details about configuration will follow in another Blog of this series.
Short overview:
We already have following bundles used as bridges between „classic“ Log-Frameworks and SLF4J / LOGBack:
- slf4j.api
- jul.to.slf4j
- log4j.over.slf4j
- jcl.over.slf4j
- logback.core
- logback.classic
You'll find more details in part 2 of this Blog series.
Bundle osgi.over.slf4j (a bridge between OSGI Service and LOG4J)
We need a bundle as bridge between OSGI Log Services and SLF4J / LOGBack. Please create a Plug-In project using PDE:
- my.namespace.osgi.over.slf4j
Your MANIFEST.MF should look like:
This osgi.over.slf4j - bundle has its own org.slf4j.Logger:
We'll use this Logger to log events from this bundle itself and also to log all catched LogEntry from other bundles.
To track LogReader Services we can use a ServiceTracker:
We create our LogServiceTracker with this filter to get only services from type LogReaderService or ExtendedLogReaderService:
(|(objectClass=org.osgi.service.log.LogReaderService) (objectClass=org.eclipse.equinox.log.ExtendedLogReaderService))
A LogListener for „normal“ OSGI LogServices:
LogEntry will be logged using the Logger of our osgi.over.slf4j - bundle.
A LogListener for „extended“ Equinox OSGI LogServices:
ExtendedLogEntry already contains an own Logger.
We'll use an org.slf4j.Logger with same name - but to distinguish we use a prefix („X.“). Details will follow in another Blog.
Then we delegate LogEntry and ExtendedLogEntry to the org.slf4j.Logger:
We have to map the OSGI LogService Levels. We can get the origin message and (optional) exception from LogEntry and delegate to our Logger.
Different from Log4J or Commons-Logging is using a Marker. Markers are part of the SLF4J API, but at the moment only the LOGBack - implementation uses them. We are using Marker to print the bundle-name and perhaps also the service-name. Then we know which bundle / service originally creates the LogEntry or ExtendedLogEntry.
Remark: More about Marker you'll find in one of the next Blogs of this series.
Logging BundleEvent and FrameworkEvent
Its a good idea also to log org.osgi.framework.BundleEvent and org.osgi.framework.FrameworkEvent.
To do this we need these Listener:
Dependent from the Event - Type we create the message and level.
Remark: More about SLF4J - Marker in one of the follow-ups.
--------------------------------------------------------------------------------
Now we are ready to catch and log all events from „classic“ Log-Frameworks, OSGI LogServices, BundleEvents or FrameworkEvents using SLF4J / LOGBack:
This was the third part of my blog series "Logging in OSGI Enterprise Applications":
- Part 1: An overview
- Part 2: How to catch all log events from "classic" logging - frameworks
- Part 3: How to catch all log events from OSGI Log Services
- Part 4: ... follows (Stay tuned...)
Perhaps some of my older blogs about Logging und OSGI are also interesting:
the blog in german.
No comments:
Post a Comment