avalon-phoenix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Paul Hammant <Paul_Hamm...@yahoo.com>
Subject Re: [Mx4j-devel] Logger
Date Fri, 16 Aug 2002 21:27:01 GMT

>>A suggestion with respect to Logging.  The current impl has a class 
>>called Logger that can be extended by other impls.  My 
>>sugestion is that 
>>a full interface/impl separated design would be better.
>>For instance...
>>       mx4j.log.Log.redirectTo(new MX4JLoggerAdapter());
>>... is weird as the instance passed in is ignored and an empty 
>>contructor is requied as MX4J tries to do a newInstance().
>Exactly. The pattern followed here is "Prototype".
I prefer 'Interface' and 'Factory' Patterns :-)

>>If Logger were an interface, and users of MX4J could implement it as 
>>they see fit and MX4J would just use that logger rather than try to 
>>instantiate another the whole thing would be a lot cleaner.  
>Uhm, not sure I've understood.
>In general, you can have many Logger instances at a given time, because for example you
have 2 clients calling contemporarly the MBeanServer. Since the Loggers may have different
categories, I must have many different logger *objects*.
>Since I have to create different objects for different categories, I must have an empty
prototype to copy every time I need a new category, I cannot use only the object I'm passing
in in Log.redirectTo().
>Now, if Logger is an interface I force the implementor every time to implement dumb methods
such as error(), info() and so on. With Logger as a class, I just say "override log(...) if
you want".
>I don't think I will gain much from having Logger as interface, while I save some typing
to people that want to subclass it if I keep it as a class.
>Am I missing something here ?
Kinda.  I think the Models honored by the two interface/impl Logger APIs 
at Apache are way superior :

1) Commons :


  ( Log and LogFactory )

2) Avalon-Framework's Logger :


  ( Logger - passed in according to Inversion of Control pattern and 
LogEnagled interface )

>>Also the 
>>static nature of redirectTo makes me very nervous (all static in 
>>reusable tools makes me nervous).  
>Well, sometimes I get nervous too about static stuff, but this was a simple and working
solution, XP style.
I have to pick you up there dude.  I appreciate we're about to fall out 
over this, but XP's "Do The Simplest Thing" does not apply to API 
writers whose users are *outside* their own CVS control. 
 Do-the-Simplest-Thing works very well (I work for an international XP 
adocating consultancy) when you can refactor all uses of that thing as 
and when you need to whithout seeking permission.  Can you change this 
now without upsetting users?  Possibly not, therefor Do the simpelst 
thing does not apply. The API creater does have to do a lot of un-XP 
modelling and trial-and error before publishing the API.

>What I'm not happy about is that if you have a JVM with 2 MBeanServers they both get redirected,
since Log.redirectTo is static. However, I did not have the time to look into this more deeply,
if you want to take a go at it, you're welcome.
>Making Log a singleton introduces other problems: there is no point to make it a singleton
if I don't give the possibility to return a Log subclass, which means I have to find a smart
way to configure this subclass, and the call to get the Log instance is more verbose for clients
that need a very simple logging facility. Don't know if the additional work will really pay
me back...

My nearly perfect-world scenarion would be Inversion of Control 
inspired.  This....

       mx4j.log.Log.redirectTo(new MX4JLoggerAdapter());
       MBeanServerFactory.createMBeanServer( "Phoenix" );

... would be replaced by...

       MBeanServer mbs = MBeanServerFactory.createMBeanServer( "Phoenix" );
       mbs.setLogger(new MX4JLoggerAdapter(getMyActualLogger()));

To be honest though, singleton or a Commons-Logger model, or an 
Avalon-Framework Logger would be fine for me.

My real perfect-world scenario would be a a full component design 
leveraging all the lifecycle methods of Avalon-Framework
)  The MX4J server could run completely independantly ( it just needs 
the Avalon-framework jar ), or we could mount it's components insde and 
enterprise container like Phoenix.  For the record nothing suggested 
here would preclude it's deployment in any other container

For the record our adapter is currently :

  package org.apache.avalon.phoenix.components.manager;
  import mx4j.log.Logger;
  public class MX4JLoggerAdapter extends Logger
      private static org.apache.avalon.framework.logger.Logger avalonLogger;
      public static void setLogger(org.apache.avalon.framework.logger.Logger logger) {
          avalonLogger = logger;
      protected void log(int level, Object message, Throwable throwable) {
          switch (level) {
              case mx4j.log.Logger.DEBUG:
                  avalonLogger.debug(message.toString(), throwable);
              case mx4j.log.Logger.ERROR:
                  avalonLogger.error(message.toString(), throwable);
              case mx4j.log.Logger.FATAL:
                  avalonLogger.fatalError(message.toString(), throwable);
              case mx4j.log.Logger.INFO:
                  avalonLogger.info(message.toString(), throwable);
              case mx4j.log.Logger.TRACE:
                  avalonLogger.debug(message.toString(), throwable);
              case mx4j.log.Logger.WARN:
                  avalonLogger.warn(message.toString(), throwable);


- Paul

To unsubscribe, e-mail:   <mailto:avalon-phoenix-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:avalon-phoenix-dev-help@jakarta.apache.org>

View raw message