5325564b80a812956f91f55f9a829d5cd30fb582.svn-base 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package com.persistence;
  2. import java.sql.Connection;
  3. import java.sql.SQLException;
  4. import java.sql.Statement;
  5. import java.util.Iterator;
  6. import org.apache.log4j.PatternLayout;
  7. import org.apache.log4j.jdbc.JDBCAppender;
  8. import org.apache.log4j.spi.ErrorCode;
  9. import org.apache.log4j.spi.LoggingEvent;
  10. import com.sinosoft.lz.system.configer.service.ServerConfigure;
  11. public class JDBCPoolAppender extends JDBCAppender{
  12. protected Connection connection = null;
  13. protected String sqlStatement = "";
  14. /**
  15. * size of LoggingEvent buffer before writting to the database. Default is
  16. * 1.
  17. */
  18. protected int bufferSize = 1;
  19. public JDBCPoolAppender() {
  20. super();
  21. }
  22. /**
  23. * ArrayList holding the buffer of Logging Events.
  24. */
  25. @SuppressWarnings("unchecked")
  26. public void append(LoggingEvent event) {
  27. buffer.add(event);
  28. if (buffer.size() >= bufferSize)
  29. flushBuffer();
  30. }
  31. /**
  32. * By default getLogStatement sends the event to the required Layout object.
  33. * The layout will format the given pattern into a workable SQL string.
  34. *
  35. * Overriding this provides direct access to the LoggingEvent when
  36. * constructing the logging statement.
  37. *
  38. */
  39. protected String getLogStatement(LoggingEvent event) {
  40. return getLayout().format(event);
  41. }
  42. /**
  43. *
  44. * Override this to provide an alertnate method of getting connections (such
  45. * as caching). One method to fix this is to open connections at the start
  46. * of flushBuffer() and close them at the end. I use a connection pool
  47. * outside of JDBCAppender which is accessed in an override of this method.
  48. * */
  49. protected void execute(String sql) throws SQLException {
  50. Connection con = null;
  51. Statement stmt = null;
  52. try {
  53. con = getConnection();
  54. stmt = con.createStatement();
  55. stmt.executeUpdate(sql);
  56. } catch (SQLException e) {
  57. if (stmt != null)
  58. stmt.close();
  59. throw e;
  60. }
  61. stmt.close();
  62. closeConnection(con);
  63. }
  64. /**
  65. * Override this to return the connection to a pool, or to clean up the
  66. * resource.
  67. *
  68. * The default behavior holds a single connection open until the appender is
  69. * closed (typically when garbage collected).
  70. */
  71. protected void closeConnection(Connection con) {
  72. try {
  73. if (connection != null && !connection.isClosed())
  74. connection.close();
  75. } catch (SQLException e) {
  76. errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);
  77. }
  78. }
  79. /**
  80. * Override 此函数来利用连接池返回一个Connetion对象
  81. *
  82. */
  83. protected Connection getConnection() throws SQLException {
  84. try {
  85. ServerConfigure sc = ServerConfigure.getServerConfigerInstance();
  86. connection = sc.getDataSource().getConnection();
  87. } catch (Exception e) {
  88. errorHandler.error("Error opening connection", e, ErrorCode.GENERIC_FAILURE);
  89. }
  90. return connection;
  91. }
  92. /**
  93. * Closes the appender, flushing the buffer first then closing the default
  94. * connection if it is open.
  95. */
  96. public void close() {
  97. flushBuffer();
  98. try {
  99. if (connection != null && !connection.isClosed())
  100. connection.close();
  101. } catch (SQLException e) {
  102. errorHandler.error("Error closing connection", e, ErrorCode.GENERIC_FAILURE);
  103. }
  104. this.closed = true;
  105. }
  106. /**
  107. * loops through the buffer of LoggingEvents, gets a sql string from
  108. * getLogStatement() and sends it to execute(). Errors are sent to the
  109. * errorHandler.
  110. *
  111. * If a statement fails the LoggingEvent stays in the buffer!
  112. */
  113. @SuppressWarnings({ "rawtypes", "unchecked" })
  114. public void flushBuffer() {
  115. // Do the actual logging
  116. removes.ensureCapacity(buffer.size());
  117. for (Iterator i = buffer.iterator(); i.hasNext();) {
  118. try {
  119. LoggingEvent logEvent = (LoggingEvent) i.next();
  120. String sql = getLogStatement(logEvent);
  121. execute(sql);
  122. removes.add(logEvent);
  123. } catch (SQLException e) {
  124. errorHandler.error("Failed to excute sql", e, ErrorCode.FLUSH_FAILURE);
  125. }
  126. }
  127. // remove from the buffer any events that were reported
  128. buffer.removeAll(removes);
  129. // clear the buffer of reported events
  130. removes.clear();
  131. }
  132. /** closes the appender before disposal */
  133. public void finalize() {
  134. close();
  135. }
  136. /**
  137. * JDBCAppender requires a layout.
  138. * */
  139. public boolean requiresLayout() {
  140. return true;
  141. }
  142. /**
  143. *
  144. */
  145. public void setSql(String s) {
  146. sqlStatement = s;
  147. if (getLayout() == null) {
  148. this.setLayout(new PatternLayout(s));
  149. } else {
  150. ((PatternLayout) getLayout()).setConversionPattern(s);
  151. }
  152. }
  153. /**
  154. * Returns pre-formated statement eg: insert into LogTable (msg) values
  155. * ("%m")
  156. */
  157. public String getSql() {
  158. return sqlStatement;
  159. }
  160. public void setBufferSize(int newBufferSize) {
  161. bufferSize = newBufferSize;
  162. buffer.ensureCapacity(bufferSize);
  163. removes.ensureCapacity(bufferSize);
  164. }
  165. public int getBufferSize() {
  166. return bufferSize;
  167. }
  168. }