[slf4j-dev] MDC Type functionality

Gardiner, Paul PGardiner at syntellect.com
Tue Mar 27 20:03:41 CEST 2007


I got the logback version of the log reader bundle working fine.  I had
to serialize the Marker object when writing it from the log user bundle,
and then deserialize it on the reader side.  Now markers work fine, and
I can log the bundle name by using MDC from the reader.  If anyone's
interested, let me know and I'll email the source.

-----Original Message-----
From: dev-bounces at slf4j.org [mailto:dev-bounces at slf4j.org] On Behalf Of
Gardiner, Paul
Sent: Tuesday, March 27, 2007 10:11 AM
To: slf4j developers list
Subject: Re: [slf4j-dev] MDC Type functionality

John,

What you have in the repo looks like an implementation of an OSGi log
service that uses SLF4j to do the logging.  What I have is a bit
different.  I'll explain in a bit more detail.

The OSGi log service I am using is the Equinox extended log service.
The SLF4J implementation I did (the "log user") is a separate bundle
that uses the OSGi log service; it doesn't provide any services itself.
Instead, it writes out log entries to the OSGi log service.  I use the
slf4j.api bundle, and then export org.slf4j.impl, and my logger package
from my bundle, which the slf4j.api bundle then imports.  

Then I have a completely separate bundle (the "log reader user") that
registers a listener with the OSGi log service.  Every time a log entry
is made by the log user, the log reader user's filter method gets called
(isLoggable), and if it returns true, its logged method gets called,
which is where the logs get written out to their final destination.  The
logged method receives an ExtendedLogEntry object as its argument, which
in addition to the stuff inherited from LogEntry, contains the logger
name, thread id, a sequence number, and a context object, which can be
any object defined by the log user.  Currently, I have the bundle and
FQCN included in this object.  Note that the bundle is the bundle that
made the original log entry, not the log user bundle.  My log reader
bundle is using log4j to log out the messages.  

So all together, there are three components - log user bundle (slf4j),
the OSGi extended log service (in Equinox incubator), and the log reader
user (currently I'm using log4j).  When making a log entry, the path the
log message takes is ->originating bundle->log user->OSGi logger->log
reader user.

The advantage to this approach is that it is reasonably efficient,
allows users to use LoggerFactory.getLogger(getClass())...  and still
get bundle and other context information without having to use a service
reference or bundle as an argument, it allows for different listener
types, and it doesn't break existing OSGi log users/log reader users.

So to answer your question about which implementation, the answer is
it's an OSGi log user implementation.  I implemented it using a
LocationAwareLogger, but nothing is being done with the marker data at
the moment, because I can't use logback as the log reader user.   The
reason for this is that I already have a binding to OSGi, so if I then
bind to logback, I have a classloader issue.  This should be ok if I
completely segregate the bundles, but unfortunately I can't do that,
because the Marker object comes from the log user bundle, which is
different than the Marker object from the log reader user bundle.

Having said that, I'm not really asking for ideas on this, unless you
have ideas off the top of your head.  I really haven't looked into this
very much.  I tried implementing logback, it got lots of class loader
errors, so I put log4j back.  Also, since both the log user and log
reader user use SLF4J (since logback uses it), I end up getting an
endless loop.  Once I have looked a bit deeper, I'll pose some
questions, but for now, I just don't understand what's going on enough.
I'm pretty sure the class loader issues are solvable though.

As far as MDC goes, I think I'll just drop it.  I likely can get the job
done with Markers, but I'll have to learn a bit more about how they
work.  I understand how to use them, but need to learn how to use them
properly and appropriately.

Thanks,
Paul

-----Original Message-----
From: dev-bounces at slf4j.org [mailto:dev-bounces at slf4j.org] On Behalf Of
John E. Conlon
Sent: Monday, March 26, 2007 5:26 PM
To: slf4j developers list
Subject: Re: [slf4j-dev] MDC Type functionality

Gardiner, Paul wrote:
> The extended log service in equinox is similar to the standard one,
but
> it adds a few extra methods for supporting named loggers, isLoggable,
> and logging context objects.  Here's the basic idea:
> https://www.eclipse.org/bugs/show_bug.cgi?id=147824.  It's just an
> incubator project right now, but I have a pressing need at the moment.
>   

Interesting thread... I think our devs and users may find it most 
interesting as slf4j is mentioned several times: :-)

For example:

> Message payload for the LogService consistes primarily of String based
messages
> and when relevant a Throwable. In some situations a generic
String-based
> logging API is insufficient and in these cases it's desirable to pass
additonal
> information with the understanding that it may be ignored. SLF4J uses
it's
> Marker API in this fashion to allow strong coupling between logger and
> recipient without impacting the generic log API.

...

> For this to work there are a couple of problems that need thought:
> 1) we need a binding of the various logging API to the log service
>  - we should consider looking at SLF4J as its defined a few useful
static
> bindings already for JCL and log4j.

...

> I'm step by step migrating to SLF4J, because I really enjoy the
simplicity and
> effectiveness of the API. Problem is: I NEED to know which OSGi Plugin
is
> logging.  This is a serious problem, as all implementations only
provide a
> thread based context.
Note: The osgi-over-slf4j binding in the repo already provides this
information as BundleSymbolicName and Version.





> I'm new to SLF4J, but I have looked around at markers, and found there
> isn't a lot of info on how they are used.  
Logger logger = LoggerFactory.getLogger("testMarker");
Marker blue = MarkerFactory.getMarker("BLUE");
logger.debug(blue, "hello");
logger.info(blue, "hello");
logger.warn(blue, "hello");
logger.error(blue, "hello");

Take a look at the test cases in slf4j.
> It looks like a single piece
> of data, but with a hierarchy.  
Yes.
> How would it work in this case?  Would I
> (or the end user) create a marker named "session_id", and then create
a
> child with the actual session id as the name?  
>
>   
Well from what I gather about the Equinox extension is that there is a 
context associated with logging messages.
In your use case the user or client application is an Equinox Log 
Service client, not a slf4j api user right? That would mean YOU would 
have to create the Marker from the context in the log messages in your 
'equinox-over-slf4j'.

Now the critical question is which Logging API implementation are you 
planning to have your 'equinox-over-slf4j' bind with? If you use Markers

you will have to use an implementation that uses them too and that would

be either one that you implement or the Logback implementation. Check 
the logback project for more details on how it handles marker 
hierarchies. http://logback.qos.ch/

cheers,
John

>
> -----Original Message-----
> From: dev-bounces at slf4j.org [mailto:dev-bounces at slf4j.org] On Behalf
Of
> John E. Conlon
> Sent: Monday, March 26, 2007 12:55 PM
> To: slf4j developers list
> Subject: Re: [slf4j-dev] MDC Type functionality
>
> Hello Paul,
>
> Have you considered using the
>
>
>     org.slf4j.Marker
>
> to move this data to the readers? See the FAQ 
> http://www.slf4j.org/faq.html#marker_interface
>
> BTW - You may have noticed in our slf4j source repository we have 
> implemented a simple osgi log service for slf4j?
> http://svn.slf4j.org/viewvc/slf4j/trunk/osgi-over-slf4j/
>
> I have not worked with the Equinox log service but plan to do so soon.

> Paul would you be so kind to please provide a link to the
documentation 
> that can describe the Equinox extensions? Is this log service the same

> used by Eclipse as well?
>
> thanks,
> John
>
>
> Gardiner, Paul wrote:
>   
>> I have written an SLF4J binding to the Equinox extended log service, 
>> which is an extension of the OSGi logging service, that includes 
>> contextual information, and passes "isLoggable" statements through to

>> log listeners (readers). The problem I have is supporting extra data 
>> that is not part of the log message. SLF4J does not include MDC or
NDC
>>     
>
>   
>> functionality, so I am not sure of the best way to pass through this 
>> kind of data. A typical use case is session id, which is passed as 
>> MDC. When the log entry is made, the session id is included in the 
>> file appender, but omitted from an appender that sends pages. One 
>> solution is to read all MDC data and pass it through to the OSGi log 
>> service, and then recreate it in the log reader. However, I was 
>> wondering if there was a more elegant/less expensive solution.
>>
>> Thanks,
>>
>> Paul
>>
>>
>>     
>
------------------------------------------------------------------------
>   
>> _______________________________________________
>> dev mailing list
>> dev at slf4j.org
>> http://www.slf4j.org/mailman/listinfo/dev
>>     
>
> _______________________________________________
> dev mailing list
> dev at slf4j.org
> http://www.slf4j.org/mailman/listinfo/dev
> _______________________________________________
> dev mailing list
> dev at slf4j.org
> http://www.slf4j.org/mailman/listinfo/dev
>
>
>   

_______________________________________________
dev mailing list
dev at slf4j.org
http://www.slf4j.org/mailman/listinfo/dev
_______________________________________________
dev mailing list
dev at slf4j.org
http://www.slf4j.org/mailman/listinfo/dev



More information about the slf4j-dev mailing list