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 a
PatternLayout
(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 implement
closeConnection
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;<br />import java.sql.Connection;<br />import java.sql.SQLException;<br />import org.apache.log4j.spi.ErrorCode;<br />import com.codestudio.sql.PoolMan;<br />/**<br /> * Log4j的 Appender, 通過串連池擷取資料庫連接<br /> * @author Carl He<br /> */<br />public class MyJDBCAppender extends org.apache.log4j.jdbc.JDBCAppender {<br />/**通過 PoolMan 擷取資料庫連接對象的 jndiName 屬性*/<br />protected String jndiName;<br />/**資料庫連接對象*/<br />protected Connection connection;<br />public MyJDBCAppender() {<br />super();<br />}<br />@Override<br />protected void closeConnection(Connection con) {<br />try {<br />if (connection != null && !connection.isClosed())<br />connection.close();<br />} catch (SQLException e) {<br />errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);<br />}<br />}<br />@Override<br />protected Connection getConnection() throws SQLException {<br />try {<br />//通過 PoolMan 擷取資料庫連接對象(http://nchc.dl.sourceforge.net/project/poolman/PoolMan/poolman-2.1-b1/poolman-2.1-b1.zip)<br />Class.forName("com.codestudio.sql.PoolMan");<br />connection= PoolMan.connect("jdbc:poolman://" + getJndiName());<br />} catch (Exception e) {<br />System.out.println(e.getMessage());<br />}<br />return connection;<br />}<br />/**<br /> * @return the jndiName<br /> */<br />public String getJndiName() {<br />return jndiName;<br />}<br />/**<br /> * @param jndiName the jndiName to set<br /> */<br />public void setJndiName(String jndiName) {<br />this.jndiName = jndiName;<br />}<br />}
log4j.properties 檔案中加上如下一段代碼(對此 Appender 的配置):
log4j.appender.JDBC=com.hmw.log4j.MyJDBCAppender<br />log4j.appender.JDBC.jndiName=log<br />log4j.appender.JDBC.layout=org.apache.log4j.PatternLayout<br />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"?><br /><poolman><br /><management-mode>local</management-mode><br /><datasource><br /><dbname>log</dbname><br /><jndiName>log</jndiName><br /><driver>com.mysql.jdbc.Driver</driver><br /><url>jdbc:mysql://localhost:3306/test</url><br /><username>use</username><br /><password>password</password><br /><minimumSize>0</minimumSize><br /><maximumSize>10</maximumSize><br /><logFile>logs/mysql.log</logFile><br /></datasource><br /></poolman>