Saturday, April 7, 2007

用log4j做filter分流

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j=" http://jakarta.apache.org/log4j/">
       
  <appender name="DNCGCustomWarnFilter" class="org.apache.log4j.FileAppender">
    <param name="File" value="DNCGCustomWarnFilter.log "/>
    <param name="Append" value="false"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%m%n"/>
    </layout>
    <filter class="org.apache.log4j.varia.LevelRangeFilter">
        <param name="LevelMin" value="WARN" />
        <param name="LevelMax" value="WARN" />
    </filter>
  </appender>
 
  <appender name="DNCGCustomErrorFilter" class="org.apache.log4j.FileAppender">
    <param name="File" value="DNCGCustomErrorFilter.log "/>
    <param name="Append" value="false"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d: %m%n"/>
    </layout>
    <filter class="org.apache.log4j.varia.LevelRangeFilter">
        <param name="LevelMin" value="ERROR" />
        <param name="LevelMax" value="ERROR" />
    </filter>
  </appender>
  
  <appender name="logAppender" class="org.apache.log4j.ConsoleAppender">
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d: %m%n"/>
    </layout>
  </appender>

  <appender name="logToFileAppender" class="org.apache.log4j.FileAppender ">
    <param name="File" value="dncgCustom.log"/>
    <param name="Append" value="false"/>
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d: %m%n"/>
    </layout>
  </appender>

  <root>
    <priority value ="info"/>
    <appender-ref ref="logAppender"/>
    <appender-ref ref="logToFileAppender"/>         
    <appender-ref ref="DNCGCustomWarnFilter"/>   
    <appender-ref ref="DNCGCustomErrorFilter"/>   
  </root>

</log4j:configuration>

java code 实现了:
1.logger:
2.动态cache:保存属性
3.get DB connection from Data Source through JNDI

package com.ncs.gw.utils;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties ;
import java.util.StringTokenizer;

import javax.naming.Context;
import javax.naming.InitialContext;

import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

public class DNCGUtils {
   
    public static Logger logger;
   
    private static DNCGPropertiesRefreshListener propertiesCache=null;
    private static Map s_customProperties = null;
   
    static{
        String tracePropertiesLocation=getDNCGCustomProperty(" Sys.CustomJava.TraceProperties.Name");
        DOMConfigurator.configure(Constants.DNCG_CUSTOM_ENV_CONFIG_LOCATION+tracePropertiesLocation);
        logger= Logger.getLogger(DNCGUtils.class);
    }

    public static String getDNCGCustomProperty(String key) {
        return (String)getProperties().get(key);
    }
   
    public static void info(String str){
        logger.info(str);
    }

    public static void warn(String str){
        logger.info(str);
    }
   
    public static void error(String str){
        logger.info(str);
    }
   
    /**
     * Retrieves the cached properties. The result of this call is gauaranteed to be NOT <code>null</code>.
     * @return The properties
     */
    private static Map getProperties(){
        // The reason we do this round about way to get the properties instead of calling
        // s_customProperties.get(prop) straight on the s_customProperties static
        // variable, is there would be a race condition where it is possible for
        // s_customProperties to become null after the initPropertiesCache() call, but before
        // the get() call. This is because a separate thread can call WSGPropertiesRefreshListener#resetCache()
        // during this call. The only other way to stop the race condition is to add a heap
        // of synchronization which would be a performance hit.
        Map props = s_customProperties;
       
        if(props == null){
            // Initialise the cache
            props = initPropertiesCache();
        }
        return props;

    }
   
   /**
     * Initialises the WSG custom properties cache
     * @return The properties that were just initialised. This is guaranteed to be not null.
     *
     */
    private static synchronized Map initPropertiesCache(){
        Map propsMap = s_customProperties;
       
        if(propsMap != null){
            // Already initialised
            return propsMap;
        }
       
        try {
            Properties props = new Properties();
            String path=Constants.DNCG_CUSTOM_ENV_CONFIG_LOCATION+"dncgCustom.properties";
            FileInputStream in = new FileInputStream(path);
            props.load(in);
            in.close();   
           
            // Convert the properties to a HashMap. HashMaps don't have synchronized on it's getters
            // and setters, therefore is more efficient.
            propsMap = new HashMap(props);
        }
        catch (Exception ex) {
            // if we get an Exception while loading the file on the server, something is seriously wrong!
            // Should never happen!
            logger.info(stack2string(ex));
            throw new IllegalStateException("Failed to load dncgCustom.properties");
        }
       
        s_customProperties = propsMap;
       
        // Register the listener to be notified if the properties have been modified
       
        propertiesCache=new DNCGPropertiesRefreshListener();
        CacheManager.registerCacheRefreshListener("DNCG Custom Properties", propertiesCache);

        return propsMap;
    }
   
    public static void refreshDNCGCustomPropertiesCache(){
        propertiesCache.resetCache();
    }
   
    /**
     * Implementation of <code>CacheRefreshListener</code> to reset the WSG properties cache
     * if there are any changes made to the properties file
     *
     */
    private static class DNCGPropertiesRefreshListener implements CacheRefreshListener{
       
        /**
         * This method is invoked to cause the cache to release all cached objects.
         * This occurs when the cache becomes out of synch with it's datasource and forces
         * the cache to reinitialise itself from the original data source.
         *
         */
        public void resetCache() {
            // Clear the cache. This will force the properties to be reloaded next time they
            // are accessed
            s_customProperties = null;       
        }

        /**
         * Retrieves a read-only version of the current cache contents to be used for display purposes.
         * @return A map of the cache contents.
         */
        public Map getCacheContents() {
            return new HashMap(getProperties());
        }
    }
   
    public static String stack2string(Throwable t)
    {
        try
        {
            StringWriter sw = new StringWriter();
            PrintWriter pw = new PrintWriter(sw);
            t.printStackTrace(pw);

            return sw.toString();
        }
        catch (Throwable t2)
        {
            return "Trace.stack2string Exception";
        }
    }

    public static Connection getConnection() throws Exception {
        try {
            Context ctx = new InitialContext();
            javax.sql.DataSource ds = (javax.sql.DataSource) ctx.lookup("ExchangeConnectDS");
            Connection conn=ds.getConnection();
            conn.setAutoCommit(true);
            return conn;
        }
        catch (Exception e) {
            System.err.println("Could not locate datasource!  Reason:");
            e.printStackTrace();
            throw e;
        }
    }   
   
    public static void closeConnection(Connection conn) throws Exception {
         try {
             if (conn != null)
                 conn.close();
         } catch (Exception ex) {
             ex.printStackTrace();
         }
       
    }   
   
    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

    }

}

No comments: