What is the proper way to to use the OSGi LogService in a real world application? At first I figured I would use Declarative Services to create components if a class needs to log something. However, this means you have to declare a service component for just about every single class which seems like overkill and a pain to maintain. This is especially true when you need to make most of the classes into component factories that are just helper classes.
Also, this doesn't work very well for abstract classes and non-final classes as the developer extending the class has to make sure he/she declares a component with the same references as the base class. This is especially true in the system I'm developing that essentially provides a library containing abstract classes that other developers will use.
The current solution is providing static log methods that use a static instance of a LogService reference. However, the LogService provider treats all log messages as coming from the bundle that contains开发者_运维问答 the static log class.
In OSGi (as in any environment) you want to stay away from static helpers as much as you can, so, the static log method solutions is not the best way to go here. As you run in an OSGi environment, you will want to use the LogService
as a central, bundle- and service-aware conduit for all your logging. There are two cases to consider.
Legacy and library code
If the code you use needs logging functionality, but is not OSGi aware, you can build (or find) bridges to the LogService
.
Code under your control
Assuming that all code under your control is supposed to be service-aware, it should use the LogService
directly. For most components this is easy, but some cases need additional consideration.
For abstract classes, it all depends on what you use them for.
- Are they base classes that help you with OSGi details? Then declarative services may not be your best bet, you could look into other dependency management mechanisms that handle inheritance differently.
- Do they provide non-OSGi aware base functionality? This case should be no problem, as your concrete subclass will be registered as a component.
- We all run into situation where library code seems to need logging; however, ask yourself whether it really does. Very generic code can rarely know what it should log. If it knows enough about your situation, it probably should be located in a component, delegating the details to the actual library code. For exceptional situations that warrant logging, you should probably use exceptions.
- Do you really need to log from non-service-aware code? You can pass in a
LogService
to the helper methods (so at least we know on who's behalf this code is executing).
A special case to consider are long-running operations that are not OSGi-aware: if you give a service reference to, for instance, a worker thread which may run a very long time, you're asking for trouble, not only for logging.
精彩评论