亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 46393 | 回復(fù): 1
打印 上一主題 下一主題

log4j+數(shù)據(jù)庫連接池添加自定義信息 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報告]
發(fā)表于 2009-11-29 16:46 |只看該作者 |倒序瀏覽
   log4j寫數(shù)據(jù)庫,通常只能寫入log4j提供的信息,如果用來記錄用戶ID號,操作等的記錄,則無法實現(xiàn).
   這里,我在log4j里加了一個字段userID (當(dāng)然你可以再加幾個)用來記錄用戶ID,操作
1.log4j配置文件
#向控制臺和數(shù)據(jù)庫輸出
log4j.rootLogger=DEBUG,stdout,JDBC
log4j.addivity.org.apache=true
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[Datetime]%d{yyyy-MM-dd hh:mm:ss}%n[Priority]%p%n[Location]%l%n[Message]%m%n
log4j.appender.JDBC.Threshold=INFO
log4j.appender.JDBC=xaut.common.log.JDBCExtAppender
log4j.appender.JDBC.driver=oracle.jdbc.driver.OracleDriver
log4j.appender.JDBC.URL=jdbc:oracle:thin:@192.168.88.26:1521:hdptdb
log4j.appender.JDBC.user=hdptdep
log4j.appender.JDBC.password=123456
log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout
log4j.appender.JDBC.sql=INSERT INTO SYS_LOG(LOGTIME,LOGLEVEL,LOCATION,MESSAGE,USERID)VALUES('%d{yyyy-MM-dd HH:mm:ss}','%p','%l','%m',
   大家注意最后一句log4j.appender.JDBC.sql ,這個sql語句以逗號結(jié)束,并沒有寫完,缺少最后一個字段userID的值(這個值由程序填寫)。
2.數(shù)據(jù)庫表結(jié)構(gòu)
   我是在oracle下測試的,表結(jié)構(gòu)如下
create table SYS_LOG
(
  LOGTIME  VARCHAR2(32),
  USERID   VARCHAR2(20),
  LOGLEVEL VARCHAR2(10),
  LOCATION VARCHAR2(80),
  MESSAGE  VARCHAR2(100)
)
3.數(shù)據(jù)庫連接池和自定義信息
   org.apache.log4j.jdbc.JDBCAppender是log4j提供的默認向數(shù)據(jù)庫插入數(shù)據(jù)的類。這個類采用的是直接通過JDBC連接數(shù)據(jù)庫,效率低,而且不能插入自定義信息。
   如果你的服務(wù)器上配置了數(shù)據(jù)庫連接池,而且想插入自定義信息,比如用戶ID,必須重載此類。
代碼見附錄1
說明:
   (1)網(wǎng)上大量的人說至少重載三個方法getconnect,closeconnection,excute,我看了一下源代碼,悲從心生。最早應(yīng)該有一個程序員,對面向?qū)ο蠹夹g(shù)是懂非懂,看了一些資料就草率的下了這個結(jié)論,而且還想當(dāng)然的結(jié)出了例子代碼。
      比如:
如何給 Log4j 配上數(shù)據(jù)庫連接池
      從面向?qū)ο蠹夹g(shù)上看,重載意味著先當(dāng)實例化出一個子類對象時,如果子類重載了父類的方法,則執(zhí)行子類的方法,如果沒有重載,則執(zhí)行父類的方法。
      也就是說你覺得哪個方法達不到你的要求,你就要定制自己的實現(xiàn)代碼。很多人把JDBCAppender中的成員變量和方法又重新在自己的類里面又寫了一遍,呵呵。
      
   (2)由于我們使用了數(shù)據(jù)庫連接池,所以必須重載getConnection和closeConnection
   (3)由于我們要加入自定義信息,必須重載getLogStatement
   (4)DatabaseConfigure類請在博客內(nèi)找,這里就不提供超鏈接了
4.添加自定義信息
   (1)先添加一個ParameterizedMessage接口,見附錄2
   (2)再用JDBCLogMessage類實現(xiàn)ParameterizedMessage接口,見附錄3
   (3)JDBCExtAppender類重載getLogStatement()方法,在SQL字符串的最后添加用戶ID等信息,將SQL語句補充完整
   (4)有的人很巧妙,通過PreparedStatement完成了SQL數(shù)據(jù)的插入,但是徹底影響了log4j的整體結(jié)構(gòu),這里不推薦大家使用。參見《
Log4j記錄日志到數(shù)據(jù)庫

      這個重載的最根本問題,是重新定義了getLogStatement方法的功能(從提供合法的SQL語句變成了直接進行SQL操作),由于log4j是通常的類庫,又不是你自己寫的,會引起致命的錯誤的。
5.測試代碼
public class Logtest {
  static Logger logger = Logger.getLogger(Logtest.class.getName());
  public static void main(String[] args) {
     ParameterizedMessage msg = new JDBCLogMessage("question error","1001");   
     logger.error(msg);   
  }
}
說明:
   1001是指用戶ID
   惟一美中不足是message字段里會顯示
           [question error, 1001]
   多一個中括號和1001信息,呵呵
附錄1:
public class JDBCExtAppender extends org.apache.log4j.jdbc.JDBCAppender {
    public JDBCExtAppender() {
        super();
    }
   
    /**
     * 重載JDBCAppender的getConnection()方法
     */
    protected Connection getConnection() throws SQLException {
        if (DatabaseConfigure.getInstance().getDatapool() != null) {
            try{
            Context initCtx = new InitialContext();
            DataSource ds = (DataSource) initCtx.lookup(DatabaseConfigure.getInstance().getDatapool());
            if (ds != null)
                this.connection = ds.getConnection();
            }catch(NamingException namingex){
                namingex.printStackTrace();
                throw new SQLException("-datapool init error ");
            }
        } else {
            
            //如果沒有數(shù)據(jù)庫連接池,則直接連接
            try {
                Class.forName(DatabaseConfigure.getInstance().getJdbcDriver());
            } catch (ClassNotFoundException e) {
                System.out.println(" class not found: " + e.getMessage());
                e.printStackTrace();
                throw new SQLException("-Database driver notFind ");
            }
            try {
                this.connection = DriverManager.getConnection(DatabaseConfigure.getInstance()
                        .getDatabaseURL(), DatabaseConfigure.getInstance()
                        .getDatabaseName(), DatabaseConfigure.getInstance()
                        .getDatebasePassword());
            } catch (SQLException sqlex) {
                System.err.println("DatabaseBean connection error"
                        + sqlex.getMessage());
                sqlex.printStackTrace();
                throw new SQLException("-Database connection error ");
            }
        }
        return this.connection;
    }
   
   
   
    /**
     * 重載getLogStatement()方法,
     * 在SQL字符串最后添加用戶ID等信息
     */
     protected String getLogStatement(LoggingEvent event) {
         StringBuffer stringBuffer = new StringBuffer();
         stringBuffer.append(layout.format(event));
         
         if (event.getMessage() instanceof ParameterizedMessage) {
            
             //檢測SQL的最后一個字符是不是逗號,如果不是,則在這里補上
             if(stringBuffer.charAt(stringBuffer.length()-1)!=',')
                 stringBuffer.append(",");
            
             Object[] params = ((ParameterizedMessage) event.getMessage()).getParameters();   
             for (int i = 1; i 附錄2
public interface ParameterizedMessage extends Serializable {   
   
     /**  
      * 獲取參數(shù)列表  
      * @return 返回參數(shù)列表  
      */  
     public Object[] getParameters();   
        
     /**  
      * 獲取指定索引位置的參數(shù)  
      * @param index 索引位置  
      * @return 返回參數(shù)列表中指定索引位置的參數(shù)值  
      * @throws IndexOutOfBoundsException 當(dāng)index >= 參數(shù)列表個數(shù)時,拋出此異常  
      * @see getParameterCount()  
      */  
     public Object getParameter(int index) throws IndexOutOfBoundsException;   
        
     /**  
      * 獲取參數(shù)個數(shù)  
      * @return 返回參數(shù)個數(shù)  
      */  
     public int getParameterCount();   
        
}   
附錄3
public class JDBCLogMessage implements ParameterizedMessage {
    private static final long serialVersionUID = 1709063421963292637L;
    private Object[] params;
    public JDBCLogMessage(Object... params) {
        this.params = params;
    }
    public Object[] getParameters() {
        return this.params;
    }
    public Object getParameter(int index) throws IndexOutOfBoundsException {
        return this.params[index];
    }
    public int getParameterCount() {
        return this.params.length;
    }
    @Override
    public String toString() {
        return Arrays.toString(this.params);
    }
}
參考文獻
1.Log4j記錄日志到數(shù)據(jù)庫. http://www.hxhack.com/bbs/read.php?tid-324467.html
2.如何給 Log4j 配上數(shù)據(jù)庫連接池. http://hi.baidu.com/hwaspf/blog/item/e1583dc73562861c9c163d29.html


本文來自ChinaUnix博客,如果查看原文請點:http://blog.chinaunix.net/u/21752/showart_2106760.html

論壇徽章:
0
2 [報告]
發(fā)表于 2012-07-03 19:23 |只看該作者
為了回復(fù)你特意注冊的。。。。。
DatabaseConfigure類請在博客內(nèi)找,這里就不提供超鏈接了  根本就沒有!。。。。。。。。。。。。。。。。。。!
您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP