一直都在想如何用log4j將message寫到數據庫中,在以後查看的時候會方便些。(數據庫都是使用MSSQL)
在網上搜了下, 有兩種方法比較合適。
1.插入數據庫中的表的字段有多個(不包括自動增長列),這種情況適合在瀏覽時要對某個字段進行排序等其他需求。
配置文件主要部分如下:
<param name="Driver" value="com.microsoft.jdbc.sqlserver.SQLServerDriver" />
<param name="URL" value="jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=LOG" />
<param name="user" value="sa" />
<param name="password" value="sa" />
<param name="sql" value="INSERT INTO t(date,user,b,message) VALUES (getDate(), '%X{user}', '%X{b}', '%m')" />
<param name="BufferSize" value="1" />
</appender>
<category name="accesslog_category">
<priority value="debug" />
<appender-ref ref="access_Log_JDBC" />
<appender-ref ref="CONSOLE" />
</category>
java 部分代碼如下:
//MDC的幫助頁面:http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html
private static final String ACCESSLOG_CATEGORY = "accesslog_category";
static{
DOMConfigurator.configure("./conf/log4j.xml");
}
public static Log getLog() {
Log logger = null;
try {
logger = LogFactory.getLog(ACCESSLOG_CATEGORY);
} catch (LogConfigurationException e) {
e.printStackTrace();
}
return logger;
}
public static void main(String[] args){
Log logger = AccessLogFactory .getLog();
String msg = "b03";
String user = "u03";
String b = "b03";
MDC.put("user", user); //和配置文件中的%X{user}對應
MDC.put("b", b); //和配置文件中的%X{b}對應
logger.error(msg); //和配置文件中的%m對應
msg = "b04";
user = "u04";
b = "b04";
MDC.put("user ", user );
MDC.put("b", b);
logger.error(msg);
}
}
2.插入數據庫中的表的字段有一個(不包括自動增長列),這種情況適合只是要顯示在頁面上而無其他需求,當然第一種情況也適合(這部分的代碼來自http://hi.baidu.com/kekemao1/blog/item/199d3d31ed6d901aebc4afff.html)。
放在WEB_INF/class文件夾下的log.properties文件的內容如下
#log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender//(root日誌記錄器的存儲器)
#log4j.appender.DATABASE.URL=jdbc:microsoft:sqlserver://localhost:1433;SelectMethod=cursor
#log4j.appender.DATABASE.driver=com.microsoft.jdbc.sqlserver.SQLServerDriver
#log4j.appender.DATABASE.user=sd //用戶名
#log4j.appender.DATABASE.password=
#log4j.appender.DATABASE.sql=INSERT INTO LOG4J (Message) VALUES ('%d %c %p %m%n')//寫入pubs數據庫中的表LOG4J的Message字段中,內容%d(日期)%c: 日誌信息所在地(類名)%p: 日誌信息級別%m: 產生的日誌具體信息 %n: 輸出日誌信息換行
#log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
#log4j.appender.DATABASE.layout.ConversionPattern=%d %c %p %m%n
java 代碼:
import org.apache.log4j.MDC;
import javax.sql.DataSource;
import javax.naming.Context;
import javax.naming.InitialContext;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Vector;
/**
* 封裝DataSource
*
* @version 1.0, 2005-9-16 11:18:44
*/
public class DataSourcePackBean {
/**
* log4j
*/
private Logger logger = Logger.getLogger(DataSourcePackBean.class);
//DataSourcePackBean.class日誌記錄器的名與類名相同;
/**
* 引用名
*/
private String ref;
/**
* DataSource對象
*/
private DataSource ds;
/**
* 保存當前DataSource對象中所有打開的Connection對象的引用。
*/
private Vector openedConnections = new Vector();
/**
* 接收DataSource引用名,查找DataSource對象。
*
* @param ref DataSource引用名
*/
protected DataSourcePackBean(String ref) {
this.ref = ref;
this.ds = lookup(ref);
}
public String getRef() {
return ref;
}
public int getActive() {
return openedConnections.size();
}
/**
* 打開一個連接
*
* @param username 連接數據庫的登錄用戶名,如果爲null,表示用默認用戶連接
* @param password 連接數據庫的登錄密碼
* @return
* @throws SQLException
*/
public Connection getConnection(String username, String password) throws SQLException {
Connection conn = (username == null) ? ds.getConnection() : ds.getConnection(username, password);
// add to vector
openedConnections.add(conn);
// log
StringBuffer log = new StringBuffer();
log.append("Open").append(" a connection(").append(conn.hashCode()).append(") of [").append(ref).append("] ");
log.append(openedConnections.size()).append(" connection").append(" in use");
logger.debug(log);
// return
return conn;
}
/**
* 關閉一個連接
*
* @param conn
* @throws SQLException
*/
public void closeConnection(Connection conn) throws SQLException {
conn.close();
// remove from Vector
openedConnections.remove(conn);
// log
StringBuffer log = new StringBuffer();
log.append("Close").append(" a connection(").append(conn.hashCode()).append(") of [").append(ref).append("] ");//添加內容到日誌記錄中
log.append(openedConnections.size()).append(" connection").append(" in use");
logger.debug(log);
}
/**
* close all Connection of this DataSource
* @throws SQLException
*/
public void closeAll() throws SQLException {
for (int i = 0; i < openedConnections.size(); i++) {
((Connection)openedConnections.get(i)).close();
}
// clear Vector
openedConnections.removeAllElements();
}
/**
* get a DataSource
* @param ref the JNDI name of the DataSource
* @return
*/
private DataSource lookup(String ref) {
DataSource dataSource = null;
// 查找ref數據源對象
try {
Context env = new InitialContext();
dataSource = (DataSource) env.lookup(ref);
// 測試數據庫有效性
dataSource.getConnection().close();
logger.debug(new StringBuffer().append("DataSource[").append(ref).append("] has been initialized successfully."));
} catch (Exception e) {
e.printStackTrace();
}
// return
return dataSource;
}
public SQLRunnerIfc getSQLRunner(String username, String password) throws SQLException {
return new SQLRunner(username, password, this);
}
public SQLRunnerIfc getSQLRunner() throws SQLException {
return getSQLRunner(null, null);
}
}