关于在Log4j中使用JDBCAppender时出现死循环的问题
APACHE的log4j是一个非常好用的日志记录管理工具,可以实现到屏幕、文件、远程数据库、自动发送邮件等,功能强大而又简单易用。
但是今天在使用经过扩展的JDBCAppender时却碰到一个莫名其妙的问题,描述如下:
1.为了在日志向数据输出时每次都创建新的连接,在原来JDBCAppender的基础上进行扩展,使用自己写的数据库连接池,主要是重写getConnectioin()和closeConnection()两个方法,未改动前的源代码如下:
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import org.apache.log4j.jdbc.JDBCAppender;
import org.apache.log4j.spi.LoggingEvent;
import com.gftech.util.GFConn;
import com.gftech.util.GFDB;
public class JDBCExtAppender extends JDBCAppender {
protected String driver;
public static GFDB gfdb;
private ArrayList <GFConn> tempList;
public JDBCExtAppender() {
super();
tempList = new ArrayList <GFConn> ();
}
/**
* Override this to return the connection to a pool, or to clean up the
* resource.
*
* The default behavior holds a single connection open until the appender is
* closed (typically when garbage collected).
*/
protected void closeConnection(Connection con) {
if (con != null && tempList != null) {
for (int i = 0; i < tempList.size(); i++) {
GFConn gfconn = tempList.get(i);
if (con == gfconn.getConn()) {
gfconn.close();
tempList.remove(i);
// System.err.println( "remove conn: "+con);
break;
}
}
}
}
/**
* Override this to link with your connection pooling system.
*
* By default this creates a single connection which is held open until the
* object is garbage collected.
*/
protected Connection getConnection() throws SQLException {
if (gfdb == null) {
gfdb = new GFDB( "db9 ", driver, databaseURL, databaseUser, databasePassword);
}
if (gfdb != null) {
GFConn gfconn = gfdb.getConn();
if (gfconn != null) {
connection = gfconn.getConn();
tempList.add(gfconn);
}
}
return connection;
}
public void close() {
flushBuffer();
this.closed = true;
}
public String getLogStatement(LoggingEvent event){
StringBuffer sbuf=new StringBuffer();
sbuf.append(layout.format(event));
if (layout.ignoresThrowable ()) {
sbuf.delete(sbuf.length()-2,sbuf.length() );
String[] s = event.getThrowableStrRep();
if (s != null) {
for (int j = 0; j < s.length; j++) {
sbuf.append( "\r\n ");
sbuf.append(s[j]);
}
}
sbuf.append( " ') ");
}
return sbuf.toString() ;
}
public void setDriver(String driverClass) {
driver = driverClass;
}
数据库连接池的主要源代码如下:
public class GFDB {
private String dbName;
private ArrayList <GFConn> idleConnPool;// 空闲池
private ArrayList <GFConn> usingConnPool;// 使用池
private final int maxConns = 150;// 最大连接数目
private final int maxUserCount = 149;// 每个连接允许的最大用户数目
private final int timeout = 60000;// 连接的最大空闲时间
private final int waitTime = 30000;// 用户的最大等待时间
private String dbUrl = null;// 连接地址
private String dbDriver = null;// 数据库驱动
private String dbUser = null;// 登陆用户名
private String dbPwd = null;// 登陆密码
private ThreadGroup group = null;
static Logger logger=Logger.getLogger(GFDB.class);
public GFDB(String dbName, String driver, String url, String user,
String pwd) {
this.dbName = dbName;
dbDriver = driver;
dbUrl = url;
dbUser = user;
dbPwd = pwd;
if (driver != null && url != null && user != null && pwd != null)
init();
}
private void init() {
Connection conn = null;
GFConn _conn = null;
// init the connection pool
idleConnPool = new ArrayList <GFConn> (0);
usingConnPool = new ArrayList <GFConn> (0);
conn = buildConn();
if (conn != null) {
_conn = new GFConn();
_conn.setConn(conn);
idleConnPool.add(_conn);
} else {
try {
logger.error( "\n\n和数据库的连接被重置,试图重新建立连接。。。 ");
Thread.sleep(10000);
init();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
if (group == null)
group = new ThreadGroup( "ThreadGroup ");
// if the manager thread is not active ,then run it
if (!isActive(group, "manager "))
manager();
}
[解决办法]
大哥,太长了
接分吧
[解决办法]
正在用LOG4J,但是没发现有什么作用
[解决办法]
自己写下LOG4J的配置文件
[解决办法]
学习