123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- package com.persistence;
- import java.sql.Connection;
- import java.sql.SQLException;
- import java.sql.Statement;
- import java.util.Iterator;
- import org.apache.log4j.PatternLayout;
- import org.apache.log4j.jdbc.JDBCAppender;
- import org.apache.log4j.spi.ErrorCode;
- import org.apache.log4j.spi.LoggingEvent;
- import com.sinosoft.lz.system.configer.service.ServerConfigure;
- public class JDBCPoolAppender extends JDBCAppender{
- protected Connection connection = null;
- protected String sqlStatement = "";
- /**
- * size of LoggingEvent buffer before writting to the database. Default is
- * 1.
- */
- protected int bufferSize = 1;
- public JDBCPoolAppender() {
- super();
- }
- /**
- * ArrayList holding the buffer of Logging Events.
- */
- @SuppressWarnings("unchecked")
- public void append(LoggingEvent event) {
- buffer.add(event);
- if (buffer.size() >= bufferSize)
- flushBuffer();
- }
- /**
- * By default getLogStatement sends the event to the required Layout object.
- * The layout will format the given pattern into a workable SQL string.
- *
- * Overriding this provides direct access to the LoggingEvent when
- * constructing the logging statement.
- *
- */
- protected String getLogStatement(LoggingEvent event) {
- return getLayout().format(event);
- }
- /**
- *
- * Override this to provide an alertnate method of getting connections (such
- * as caching). One method to fix this is to open connections at the start
- * of flushBuffer() and close them at the end. I use a connection pool
- * outside of JDBCAppender which is accessed in an override of this method.
- * */
- protected void execute(String sql) throws SQLException {
- Connection con = null;
- Statement stmt = null;
- try {
- con = getConnection();
- stmt = con.createStatement();
- stmt.executeUpdate(sql);
- } catch (SQLException e) {
- if (stmt != null)
- stmt.close();
- throw e;
- }
- stmt.close();
- closeConnection(con);
- }
- /**
- * 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) {
- try {
- if (connection != null && !connection.isClosed())
- connection.close();
- } catch (SQLException e) {
- errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);
- }
- }
- /**
- * Override 此函数来利用连接池返回一个Connetion对象
- *
- */
- protected Connection getConnection() throws SQLException {
- try {
- ServerConfigure sc = ServerConfigure.getServerConfigerInstance();
- connection = sc.getDataSource().getConnection();
- } catch (Exception e) {
- errorHandler.error("Error opening connection", e, ErrorCode.GENERIC_FAILURE);
- }
- return connection;
- }
- /**
- * Closes the appender, flushing the buffer first then closing the default
- * connection if it is open.
- */
- public void close() {
- flushBuffer();
- try {
- if (connection != null && !connection.isClosed())
- connection.close();
- } catch (SQLException e) {
- errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);
- }
- this.closed = true;
- }
- /**
- * loops through the buffer of LoggingEvents, gets a sql string from
- * getLogStatement() and sends it to execute(). Errors are sent to the
- * errorHandler.
- *
- * If a statement fails the LoggingEvent stays in the buffer!
- */
- @SuppressWarnings({ "rawtypes", "unchecked" })
- public void flushBuffer() {
- // Do the actual logging
- removes.ensureCapacity(buffer.size());
- for (Iterator i = buffer.iterator(); i.hasNext();) {
- try {
- LoggingEvent logEvent = (LoggingEvent) i.next();
- String sql = getLogStatement(logEvent);
- execute(sql);
- removes.add(logEvent);
- } catch (SQLException e) {
- errorHandler.error("Failed to excute sql", e, ErrorCode.FLUSH_FAILURE);
- }
- }
- // remove from the buffer any events that were reported
- buffer.removeAll(removes);
- // clear the buffer of reported events
- removes.clear();
- }
- /** closes the appender before disposal */
- public void finalize() {
- close();
- }
- /**
- * JDBCAppender requires a layout.
- * */
- public boolean requiresLayout() {
- return true;
- }
- /**
- *
- */
- public void setSql(String s) {
- sqlStatement = s;
- if (getLayout() == null) {
- this.setLayout(new PatternLayout(s));
- } else {
- ((PatternLayout) getLayout()).setConversionPattern(s);
- }
- }
- /**
- * Returns pre-formated statement eg: insert into LogTable (msg) values
- * ("%m")
- */
- public String getSql() {
- return sqlStatement;
- }
- public void setBufferSize(int newBufferSize) {
- bufferSize = newBufferSize;
- buffer.ensureCapacity(bufferSize);
- removes.ensureCapacity(bufferSize);
- }
- public int getBufferSize() {
- return bufferSize;
- }
- }
|