On 14.06.2005 17:29:01 Victor Mote wrote:
> Jeremias Maerki wrote:
> 
> > The logging problem is a minor one. There's a wrapper for JCL 
> > that easily wraps an Avalon Logger [1]. But that's obviously 
> > the exact opposite of what you need. On the other side, 
> > creating an implementation of Avalon's Logger interface that 
> > wraps a JCL logger should be just as easy. Unfortunately, 
> > such a class doesn't exist, yet, but that's written within 10 minutes.
> > 
> > Let me explain why we switched from Avalon Logging to JCL. 
> > Avalon Loggers are always passed from container to child 
> > object (Inversion of Control). A class using a JCL logger 
> > always fetches a logger from a factory. So the difference is 
> > in acquiring a logger but there's also another aspect: With 
> > Avalon Logger you can use different loggers on different 
> > instances of the same class which you can't if you use the 
> > normal JCL pattern of using a static variable for holding the logger.
> > The static variable has certain advantages, too: You don't 
> > need a variable on every object instance and you don't have 
> > to pass Loggers all around in the system, which is 
> > particularly problematic or at least cumbersome in FOP. JCL 
> > makes many thing easier.
> > 
> > But as I hinted above there's no problem connecting the two 
> > approaches.
> > Both are light-weight and therefore easy to handle.
> > 
> > [1] 
> > http://jakarta.apache.org/commons/logging/api/org/apache/commo
> > ns/logging/impl/AvalonLogger.html
> 
> Thanks for the explanation. I went to a lot of trouble in FOray, mostly
> based on past conversations with you, to remove all such static-ish things,
> and I probably won't do anything that would require a client application to
> use anything like that. But maybe there are some other things that can be
> done.

I've seen that work and I'm sure it was worth it. Relying on static
variables in the case of logging is not necessarily bad. I know I
advocated the use of Avalon Logger at that time. I still think it is
good. The big advantage is really to be able to provide a new logger
instance for each processing run so you can log each document separately
which you can't if you use JCL's static logging pattern. But I've
learned from several people as well as from my own experience that
especially in the case of FOP the Avalon Logging approach can be
annoying and that per-processing-run loggin should be done through a
different mechanism, such as specialized, application-specific
interfaces. I haven't been able to get to the latter, yet. It's one of
my long term goals to provide better feedback to the caller about layout
problems or progress, as well as cleaner exception throwing.

> Foray addresses the logging problem through its tree organization
> (everything is a tree), and storing the Logger instance at the top of the
> tree, each child node being able to get the Logger instance from its parent.

The question here, of course, is if it is performant. It's probably ver
little but still, in a deep tree a logging call causes a number of
method calls to determine the logger instance.

> The only times it needs to get passed as a parameter is when moving from one
> module to another. So, for example if PDFDocument is at the top of the tree
> in the FOrayPDF module, it probably requires a Logger in its constructor,

The pure Avalon spirit would be to have that class implement LogEnabled.

> but then makes it available to all of its children. In some cases (like
> FOrayFont) it must be provided through an interface to keep the module as
> independent as it needs.
> 
> During our previous Inversion of Control discussion, I briefly toyed with
> the idea of having the FontConsumer provide a method *to do its own
> logging*. So, rather than FontConsumer providing a Logger to FontServer
> (which you did not like), it would instead provide something like:

The whole discussion there was problematic because I didn't really have
time to explain everything to you. But again, I think it was worth it
from what I can see.

>       public void logMessage(String message, int messageLevel) ;
>
> where messageLevel would indicate whether the message was debug, error,
> warning, etc. The things I dislike about this are 1) it is YALP (yet another
> logging protocol), which is what I understood Avalon to be trying to unify,
> and 2) it requires the client side to write code that seems pretty
> redundant. However, it is a pretty generic solution.
> 
> One alternative would be for FontServer and FontConsumer to both allow
> Commons loggers as well as Avalon loggers, and for it to deal with the
> wrapping, etc. If it will help and if there are no better ideas, I am
> willing to do this.

I'd leave it as-is for the moment. As I said earlier, I believe it's
very easy to wrap a JCL logger into an Avalon Logger and pass that into
FontServer and FontConsumer. I'd even say you're on the safer side than
FOP because with the static logging you can't separate the logging
output for each processing run anymore. This is still something I found
important back when I was still coding heavy-duty FO processing servers.
And I know that many people have asked on the mailing list about
providing their own loggers to access the output made by FOP. That is
something that won't be possible ATM in CVS HEAD in a multi-threaded
environment. To get the log output per processing run you need to
serialize them.


Jeremias Maerki

Reply via email to