org.apache.log4j.jdbc.JDBCAppender 是利用傳統的 JDBC 連接方法,這種方式連接數據庫效率低下,為了解決這個問題,現在自定義一個 Log4j 的 Appender, 將數據庫連接改為連接池的形式,此 Appender 繼承自 org.apache.log4j.jdbc.JDBCAppender, 並運用了開源項目Poolman(可從http://nchc.dl.sourceforge.net/project/poolman/PoolMan/poolman-2.1-b1/poolman-2.1-b1.zip 下載)數據庫連接池的包。
org.apache.log4j.jdbc.JDBCAppender 的官方 API(http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/jdbc/JDBCAppender.html ) 中有這么一段話:
WARNING: This version of JDBCAppender is very likely to be completely replaced in the future. Moreoever, it does not log exceptions . The JDBCAppender provides for sending log events to a database.
Each append call adds to an ArrayList
buffer. When the buffer is filled each log event is placed in a sql statement (configurable) and executed. BufferSize , db URL , User , & Password are configurable options in the standard log4j ways.
The setSql(String sql)
sets the SQL statement to be used for logging -- this statement is sent to aPatternLayout
(either created automaticly by the appender or added by the user). Therefore by default all the conversion patterns in PatternLayout
can be used inside of the statement. (see the test cases for examples)
Overriding the getLogStatement(org.apache.log4j.spi.LoggingEvent)
method allows more explicit control of the statement used for logging.
For use as a base class:
- Override
getConnection()
to pass any connection you want. Typically this is used to enable application wide connection pooling. - Override
closeConnection(Connection con)
-- if you override getConnection make sure to implementcloseConnection
to handle the connection you generated. Typically this would return the connection to the pool it came from. - Override
getLogStatement(LoggingEvent event)
to produce specialized or dynamic statements. The default uses the sql option value.
大概意思就是建議我們把其提供的 org.apache.log4j.jdbc.JDBCAppender 作為基類來使用,然后 Override 這三個方法: getConnection()、 closeConnection(Connection con) 和 getLogStatement(LoggingEvent event)。
下面是我寫的一個 org.apache.log4j.jdbc.JDBCAppender 的子類:
- package com.hmw.log4j;
- import java.sql.Connection;
- import java.sql.SQLException;
- import org.apache.log4j.spi.ErrorCode;
- import com.codestudio.sql.PoolMan;
- /**
- * Log4j的 Appender, 通過連接池獲取數據庫連接
- * @author Carl He
- */
- public class MyJDBCAppender extends org.apache.log4j.jdbc.JDBCAppender {
- /**通過 PoolMan 獲取數據庫連接對象的 jndiName 屬性*/
- protected String jndiName;
- /**數據庫連接對象*/
- protected Connection connection;
- public MyJDBCAppender() {
- super();
- }
- @Override
- protected void closeConnection(Connection con) {
- try {
- if (connection != null && !connection.isClosed())
- connection.close();
- } catch (SQLException e) {
- errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);
- }
- }
- @Override
- protected Connection getConnection() throws SQLException {
- try {
- //通過 PoolMan 獲取數據庫連接對象(http://nchc.dl.sourceforge.net/project/poolman/PoolMan/poolman-2.1-b1/poolman-2.1-b1.zip)
- Class.forName("com.codestudio.sql.PoolMan");
- connection= PoolMan.connect("jdbc:poolman://" + getJndiName());
- } catch (Exception e) {
- System.out.println(e.getMessage());
- }
- return connection;
- }
- /**
- * @return the jndiName
- */
- public String getJndiName() {
- return jndiName;
- }
- /**
- * @param jndiName the jndiName to set
- */
- public void setJndiName(String jndiName) {
- this.jndiName = jndiName;
- }
- }
log4j.properties 文件中加上如下一段代碼(對此 Appender 的配置):
- log4j.appender.JDBC=com.hmw.log4j.MyJDBCAppender
- log4j.appender.JDBC.jndiName=log
- log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout
- log4j.appender.JDBC.sql=INSERT INTO LOGGING (log_date, log_level, location, message) VALUES ('%d{ISO8601}', '%-5p', '%C,%L', '%m')
最后不要忘了 PoolMan 的配置文件 poolman.xml:
- <?xml version="1.0" encoding="UTF-8"?>
- <poolman>
- <management-mode>local</management-mode>
- <datasource>
- <dbname>log</dbname>
- <jndiName>log</jndiName>
- <driver>com.mysql.jdbc.Driver</driver>
- <url>jdbc:mysql://localhost:3306/test</url>
- <username>use</username>
- <password>password</password>
- <minimumSize>0</minimumSize>
- <maximumSize>10</maximumSize>
- <logFile>logs/mysql.log</logFile>
- </datasource>
- </poolman>