Return-Path: Delivered-To: apmail-jakarta-avalon-phoenix-dev-archive@apache.org Received: (qmail 44251 invoked from network); 16 Aug 2002 21:27:16 -0000 Received: from unknown (HELO nagoya.betaversion.org) (192.18.49.131) by daedalus.apache.org with SMTP; 16 Aug 2002 21:27:16 -0000 Received: (qmail 7101 invoked by uid 97); 16 Aug 2002 21:27:46 -0000 Delivered-To: qmlist-jakarta-archive-avalon-phoenix-dev@jakarta.apache.org Received: (qmail 7058 invoked by uid 97); 16 Aug 2002 21:27:45 -0000 Mailing-List: contact avalon-phoenix-dev-help@jakarta.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Subscribe: List-Help: List-Post: List-Id: "Avalon-Phoenix Developers List" Reply-To: "Avalon-Phoenix Developers List" Delivered-To: mailing list avalon-phoenix-dev@jakarta.apache.org Received: (qmail 7042 invoked by uid 98); 16 Aug 2002 21:27:44 -0000 X-Antivirus: nagoya (v4198 created Apr 24 2002) Message-ID: <3D5D6E25.1010400@yahoo.com> Date: Fri, 16 Aug 2002 22:27:01 +0100 From: Paul Hammant User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.1b) Gecko/20020722 X-Accept-Language: en-us, en MIME-Version: 1.0 To: mx4j-devel@lists.sourceforge.net CC: Avalon-Phoenix Developers List Subject: Re: [Mx4j-devel] Logger References: <715A1A264A45CB4CA102C18A50B75C191EA273@mlnexc01.emea.cpqcorp.net> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N X-Spam-Rating: daedalus.apache.org 1.6.2 0/1000/N Simone, >>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 : http://cvs.apache.org/viewcvs/jakarta-commons/logging/src/java/org/apache/commons/logging/ ( Log and LogFactory ) 2) Avalon-Framework's Logger : http://cvs.apache.org/viewcvs/jakarta-avalon/src/java/org/apache/avalon/framework/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.... MX4JLoggerAdapter.setLogger(getMyActualLogger()); mx4j.log.Log.redirectTo(new MX4JLoggerAdapter()); MBeanServerFactory.createMBeanServer( "Phoenix" ); ... would be replaced by... MBeanServer mbs = MBeanServerFactory.createMBeanServer( "Phoenix" ); mbs.setLogger(new MX4JLoggerAdapter(getMyActualLogger())); mbs.start(); 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 ( http://jakarta.apache.org/avalon/framework/guide-patterns-in-avalon.html ) 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); break; case mx4j.log.Logger.ERROR: avalonLogger.error(message.toString(), throwable); break; case mx4j.log.Logger.FATAL: avalonLogger.fatalError(message.toString(), throwable); break; case mx4j.log.Logger.INFO: avalonLogger.info(message.toString(), throwable); break; case mx4j.log.Logger.TRACE: avalonLogger.debug(message.toString(), throwable); break; case mx4j.log.Logger.WARN: avalonLogger.warn(message.toString(), throwable); break; } } } Regards, - Paul -- To unsubscribe, e-mail: For additional commands, e-mail: