[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [xmlblaster] Logging (Factory)



Ok,
now its working:

2002-11-06 17:53:23,715 40078 INFO  [org.xmlBlaster.corba] (XmlBlaster MainThrea
d:xmlBlaster:service=XmlBlasterServer,name=Default) [CorbaDriver-/node/http:80.7
2.2.80:3412] You don't need the naming service, i'll switch to builtin http IOR
download

That was log4j ;-)

Befor committing I would like to present what I have done, and the you
get to say if its going in or not:

1. I have created a org.xmlBlaster.util.log.LogDevicePluginManager,
   which verry much replicates the stuff in PluginManagerBase.

2. It has its LogPluginInfo (stolen from PluginInfo - but without
   logging).

3. A LogDevicePluginManager has the extra method (that differentiate it
   from PluginManagerBase);

   public I_LogDeviceFactory getFactory(String type, String version)
   throws XmlBlasterException

4. The I_LogDeviceFactory uses the same interface as I_Plugin, but is
   not an I_Plugin due to the logging problem, it has this method to be
   used when creatting devices.

      public  LogableDevice getLogDevice(LogChannel channel); 

5. I have create one FileLogDeviceFactory and one
   ConsoleLogDeviceFactory, here is the code for the latter:

   public void init(org.xmlBlaster.util.Global glob, LogPluginInfo pluginInfo) throws XmlBlasterException {

   }
   
   public String getType() {return "console";}
   public String getVersion() { return "1.0";}
   public  LogableDevice getLogDevice(LogChannel channel) {
      return new LogDeviceConsole(channel);
   }

6. Here is an example of how you can use this in a propert-file:
LoggableDevicePlugin[console][1.0]=org.xmlBlaster.util.log.ConsoleLogDeviceFactory
LoggableDevicePlugin[file][1.0]=org.xmlBlaster.util.log.FileLogDeviceFactory,logFile=mylogfile
logDevice=console
logDevice[cb]=console,file
logDevice[corba]=console,file

logFile[corba]=mylogfile.corba

This would mean:
a) for all channels except cb and corba use console. 
b)For cb use console and file with the logfile mylogfile
c) for corba use console and file wuth logfile mylogfile.corba

7. Global has been changed. The plugin manager for logging is created in
   the constructor. And initLog has changed. This is the code to handle
   configuring logging through the plugin stuff:


      String key = lc.getChannelKey();
      boolean useOld = true;//Used to guarante some logging
      
      // There are situations where the manager is actually not there b
      if (logDevicePluginManager != null) {
         // Get the plugins for the lc.key, first try with key, then globaly
         String[] devices = null;
         if (key != null)
            devices = getProperty().get("logDevice[" + key + "]", new String[0], ",");
         if (devices == null  ||  devices.length == 0)
            devices = getProperty().get("logDevice", new String[0], ",");
         
         if (devices != null && devices.length > 0) {
            for(int i = 0;i<devices.length;i++) {
               try {
                  I_LogDeviceFactory fac = logDevicePluginManager.getFactory(devices[i],"1.0");
                  LogableDevice dev = fac.getLogDevice(lc);
                  System.err.println("Setting dev "+dev+"for " +devices[i]+" of key" + key);
                  if (dev != null)
                     lc.addLogDevice(dev);
               }catch(XmlBlasterException ex) {
                  log.error(ME,"Global: error in getting LogDeviceFactory for " + key);
                  continue;
               }
               //If we ever reach here, we have some logging device set up
               useOld=false;
            }
            
            
         }
         
      }
      
      if (useOld) {
         log.info(ME,"Using old logging behaviour");

         ... Here is the old log setup code with will be used if the new
             code fails.


What do you say? Is it usable, acceptable, commitable?

Here's the code for a Log4j factory (based on the one published on the
list a while ago).

package org.backsource.in.blaster;

import org.xmlBlaster.util.Global;
import org.xmlBlaster.util.XmlBlasterException;
import org.xmlBlaster.util.log.I_LogDeviceFactory;
import org.xmlBlaster.util.log.LogPluginInfo;
import org.jutils.log.LogableDevice;
import org.jutils.log.LogChannel;

import org.apache.log4j.Logger;
/**
 * Log4jDeviceFactory.java
 *
 *<pre>
LoggableDevicePlugin[log4j][1.0]=org.backsource.in.blaster.Log4jDeviceFactory
logDevice=log4j
  </pre>
 * Created: Wed Nov  6 15:08:39 2002
 *
 *  at author <a href="mailto:pra at tim.se";>Peter Antman</a>
 *  at version $Revision$
 */

public class Log4jDeviceFactory implements I_LogDeviceFactory {
   private static final String LOG_DOMAIN="org.xmlBlaster";
   private Global glob;
   public Log4jDeviceFactory (){
      
   }
   /**
    * Get default logFile, glob is searched first,the plugin info.
    */
   public void init(Global glob, LogPluginInfo pluginInfo) throws XmlBlasterException {
      this.glob = glob;
      
   }
   
   public String getType() {return "log4j";}
   public String getVersion() {return "1.0";}

   /**
    *
    */
   public  LogableDevice getLogDevice(LogChannel channel) {
      String key = channel.getChannelKey();
      String domain = LOG_DOMAIN;
      if ( key != null) {
         domain = domain + "."+key;
         
      } // end of if ()
      Logger l = Logger.getLogger(domain);
      return new Log4jDevice(l);

   }


   class Log4jDevice implements LogableDevice {
      Logger log = null;
      Log4jDevice(Logger log) {
         if ( log == null) {
            throw new NullPointerException("Logger is not allowed to be null");  
         } // end of if ()
         
         this.log = log;
      }
         public void log(int level, String source, String str) {
         
         StringBuffer logTxt = new StringBuffer();
         logTxt.append("[").append(source).append("] ").append(str);
         
         switch (level) {
         case LogChannel.LOG_CALL:
         case LogChannel.LOG_DUMP:
         case LogChannel.LOG_TIME:
         case LogChannel.LOG_TRACE:
            if (log.isDebugEnabled())
               log.debug(logTxt);
            break;
         case LogChannel.LOG_ERROR:
            log.error(logTxt);
            break;
         case LogChannel.LOG_INFO:
            log.info(logTxt);
            break;
         case LogChannel.LOG_WARN:
            log.warn(logTxt);
            break;
         default:
            log.info(logTxt);
            break;
         }; // end of switch
      } // end of log
   }
}// Log4jDeviceFactory


Set up with
LoggableDevicePlugin[log4j][1.0]=org.backsource.in.blaster.Log4jDeviceFactory
logDevice=log4j

In property file and almost all logging (except the one in Global) will
go through log4j instead.

//Peter

On  6 Nov, Marcel Ruff wrote:
> Peter Antman wrote:
> 
>>Seems as if its verry hard to do this because of circular dependancies:
>>
>>To set up a logg plugin manager to initialize logging entails creating
>>one in a Global constructor (so that it is available in initLog).
>>However the PluginManagerBase uses the Global to set up loging - and
>>that will mean that PluginManager will start trying to use Global before
>>it has actually been created:
>>
>> (java.lang.StackOverflowError)
>>
>>
>>Any ideas about this, or should I just give up ;-(
>>
> Just throw out all logging from PluginManagerBase
> but i have just noticed that we use our Classloader there which
> probably logs as well  ....
> 
> Ok, to not waste too much time on it:
> 
> 1. Do your own instanciation  and forget the PluginManagerBase
>  or
> 2. Allow some first old style logging before you switch to your
>    plugin logging
> 
> Marcel
> 
>>
>>//Peter
>>
>>On  5 Nov, Marcel Ruff wrote:
>>  
>>
>>>>;-) Ok. I will do a test, and check with you later. One last question:
>>>>
>>>>in the currect impl each LogChannel gets its own LogDevice in initLog,
>>>>and the LogDevice gets info from the log channel for its fomatting and
>>>>such (I guess). Is this a requirement, because it will not work with the
>>>>ideas given above, becuse each type will only be instantiated once.
>>>>      
>>>>
>>>I believe that doesn't matter, we don't need any formatting when
>>>send to another logging framework.
>>>But i haven't check the code (it's from Juergen Birkle).
>>>
>>>    
>>>
>>>>Instead the plugins would bhave to be a factories which creates devices
>>>>(which could really be done by a generic factory ;-):
>>>>
>>>>LogDevicePlugin[console][1.0]=org.xmlBlaster.util.log.LogDeviceFactory,DEVICE_CLASS=org.jutils.log.LogDeviceConsole
>>>>LogDevicePlugin[file][1.0]=org.xmlBlaster.util.log.LogDeviceFactory,DEVICE_CLASS=org.jutils.log.LogDeviceFile
>>>>
>>>>Its not pretty.
>>>>      
>>>>
>>>I think its beautiful, but just follow the way you like best.
>>>
>>>regards,
>>>
>>>Marcel
>>>
>>>
>>>    
>>>
>>
>>  
>>

-- 
------------------------------------------------------------
Peter Antman	Chief Technology Officer, Development
Technology in Media, Box 34105 100 26 Stockholm
WWW: http://www.tim.se	WWW: http://www.backsource.org
Email: pra at tim.se	 
Phone: +46-(0)8-506 381 11 Mobile: +46-(0)704 20 58 11
------------------------------------------------------------