Gardiner, Paul wrote: > -----Original Message----- > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] On Behalf Of > John E. Conlon > Sent: Tuesday, March 27, 2007 2:39 PM > To: slf4j developers list > Subject: Re: [slf4j-dev] MDC Type functionality > > Paul, > > Gardiner, Paul wrote: > >> 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. >> >> > > > So your 'log user' might also be called in our slf4j naming conventions > a: slf4j-osgi. > Bundle wiring (with the symbol --> meaning uses some package or service > from another bundle) so far looks like: > [PAG] By "-->", I was just intending to show the flow of the logged > message, not a dependency. > > originatingBundle(s) --> slf4j-api --> your 'log user'(aka slf4j-osgi) > > Right? > [PAG] Yes, assuming that the "slf4j-osgi" is not the one in the repo, > because that one is an OSGi log service, not a user of the log service. > My slf4j implementation is a user of the service. > That is correct. > >> 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. >> > Paul, I have a rough idea of what your doing but I maybe hossed up > somewhere - if from the following you see that I am still confused > please send me a list of the package imports and exports from each of > your bundles and also note which services are used by each of the > bundles. > [PAG] Would it be easier to send the whole workspace? It's not too big. > > Yes you can just send directly to my email address [EMAIL PROTECTED] and not copy the list.
- thanks, John >> 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. >> >> > 1. originatingBundle(s) --> 2. slf4j-api bundle--> 3. your 'log > user'(aka slf4j-osgi) bundle --> 4. OSGi logger(LogService) bundle--> 5. > > 'log reader user' bundle--> 6. log4j > [PAG] Yes, that looks right on. > > I think I got it so far. So how are you using the log4j(6)? Or in > other words how does your 'log reader user' bundle (5) use the log4j (6) > > packages, does it import them from a log4j bundle or are they privately > packaged by you into your 'log reader user' (5) bundle? > [PAG] In the case of log4j, it has a Require-Bundle entry in the > manifest. Because the "slf4j-osgi" bundle and the logback bundle both > use slf4j, I had to place the logback and slf4j jars inside the logback > reader bundle, otherwise I would go into an endless loop. > > >> 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. >> >> > Native LogService client bundles would then be wired like: > 3*. LogService client bundles -->4. OSGi logger(LogService) bundle--> 5. > > 'log reader user' bundle--> 6. log4j > > Top end sounds good - both Equinox LogService clients (3*) and slf4j > clients (1) are supported. > >> So to answer your question about which implementation, the answer is >> it's an OSGi log user implementation. >> > OSGi logging (like many other OSGi services) can be split up (or > combined) in many different ways. So from slf4j perspective it's impl > is your OSGi 'log user'(3) . From the perspective of the actual > outputing of log messages to the world the 'logging impl' would be > log4j(6). Sorry for mixing up terms in previous email. > >> 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. >> > So your 'log user' (3) is implemented with a LocationAwareLogger which > means you have the information you want at (3) and you want to > (obliviously) get it to (6). > > the path again... > 3. 'log user'(aka slf4j-osgi) bundle --> 4. OSGi logger(LogService) > bundle--> 5. 'log reader user' bundle--> 6. log4j > > So if you want your logging messages from originatingBundles that use > slf4j apis to use this path > 1. originatingBundle(s) --> 2. slf4j-api bundle--> 3. your 'log > user'(aka slf4j-osgi) bundle --> 4. OSGi logger(LogService) bundle > > and you want to retain context information then you would have to map > the Marker information you have at 'log user' (3) to something that the > LogService (4) can use passing that through to (5). You would then have > > to pull out this information again at (5) and pass it to a logger(6) for > > output. Sounds messy. > [PAG] Yes. I had to serialize the marker to a byte array and > deserialize it on the other side. Yes, kind of messy. > > Why not implement the slf4j at the 'log reader user' bundle (5)? > [PAG] A couple of reasons. First, the way it's implemented now, all a > programmer has to do is import the slf4j-api bundle, and then use it. > They don't have to worry about context, because its all taken care of. > Second, the OSGi api without the extensions has no way of getting > context through to the reader where no service reference is used. The > objective here is to provide a better logging api while still using the > OSGi log service, and provide implementation options on the reader side. > >> 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. >> >> > The Marker interface and the BasicMarker are exported from the slf4j-api > > 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. >> > Your use case is rather generic so I expect this will come up again in > the future so trying to get a handle on it now is a good thing. > (Actually had it on my todo list to address this.) ;-) > > Did you make a logback bundle? > [PAG] Yes. It seems to be working very well, and the markers work fine > also. > > Alternative suggestion - > An OSGi bundle implementation of a logback based slf4j binding that I > will call here 'slf4j&osgireader-logback' that also listens to the > OSGi logService (5*). That replaces the 'log reader user' bundle (5) > the log user (3) as well. > > slf4j clients now do: > 1. originatingBundle(s) --> 2. slf4j-api bundle--> 5*. > slf4j&osgireader-logback bundle > > and LogService clients now do: > > 3*. LogService client bundles -->4. OSGi logger(LogService) bundle--> > 5*.slf4j&osgireader-logback bundle > > WDYT? > John > > >> 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 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: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] 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 >>>> [email protected] >>>> http://www.slf4j.org/mailman/listinfo/dev >>>> >>>> >>>> >>> _______________________________________________ >>> dev mailing list >>> [email protected] >>> http://www.slf4j.org/mailman/listinfo/dev >>> _______________________________________________ >>> dev mailing list >>> [email protected] >>> http://www.slf4j.org/mailman/listinfo/dev >>> >>> >>> >>> >>> >> _______________________________________________ >> dev mailing list >> [email protected] >> http://www.slf4j.org/mailman/listinfo/dev >> _______________________________________________ >> dev mailing list >> [email protected] >> http://www.slf4j.org/mailman/listinfo/dev >> >> >> >> > > _______________________________________________ > dev mailing list > [email protected] > http://www.slf4j.org/mailman/listinfo/dev > _______________________________________________ > dev mailing list > [email protected] > http://www.slf4j.org/mailman/listinfo/dev > > > _______________________________________________ dev mailing list [email protected] http://www.slf4j.org/mailman/listinfo/dev
