X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=srcjar_unused%2Forg%2Fapache%2Flog4j%2Fjdbc%2FJDBCAppender.java;fp=srcjar_unused%2Forg%2Fapache%2Flog4j%2Fjdbc%2FJDBCAppender.java;h=25369df94d5157b17d5ad438b11431bf75a75410;hb=ec8f3cedf60fb1feed6d34de6b49f6bfa78b9dd8;hp=0000000000000000000000000000000000000000;hpb=056dad85a910551cc95e44d451a61f6b8c4dd35d;p=jalview.git diff --git a/srcjar_unused/org/apache/log4j/jdbc/JDBCAppender.java b/srcjar_unused/org/apache/log4j/jdbc/JDBCAppender.java new file mode 100644 index 0000000..25369df --- /dev/null +++ b/srcjar_unused/org/apache/log4j/jdbc/JDBCAppender.java @@ -0,0 +1,400 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.log4j.jdbc; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.ArrayList; +import java.util.Iterator; + +import org.apache.log4j.PatternLayout; +import org.apache.log4j.spi.ErrorCode; +import org.apache.log4j.spi.LoggingEvent; + + +/** + The JDBCAppender provides for sending log events to a database. + +
WARNING: This version of JDBCAppender + is very likely to be completely replaced in the future. Moreoever, + it does not log exceptions. + +
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 {@link #getLogStatement} method allows more + explicit control of the statement used for logging. + +
For use as a base class: + +
getConnection()
to pass any connection
+ you want. Typically this is used to enable application wide
+ connection pooling.
+
+ 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.
+
+ getLogStatement(LoggingEvent event)
to
+ produce specialized or dynamic statements. The default uses the
+ sql option value.
+
+ getConnection
and
+ * closeConnection
methods.
+ */
+ protected Connection connection = null;
+
+ /**
+ * Stores the string given to the pattern layout for conversion into a SQL
+ * statement, eg: insert into LogTable (Thread, Class, Message) values
+ * ("%t", "%c", "%m").
+ *
+ * Be careful of quotes in your messages!
+ *
+ * Also see PatternLayout.
+ */
+ protected String sqlStatement = "";
+
+ /**
+ * size of LoggingEvent buffer before writting to the database.
+ * Default is 1.
+ */
+ protected int bufferSize = 1;
+
+ /**
+ * ArrayList holding the buffer of Logging Events.
+ */
+ protected ArrayList buffer;
+
+ /**
+ * Helper object for clearing out the buffer
+ */
+ protected ArrayList removes;
+
+ private boolean locationInfo = false;
+
+ public JDBCAppender() {
+ super();
+ buffer = new ArrayList(bufferSize);
+ removes = new ArrayList(bufferSize);
+ }
+
+ /**
+ * Gets whether the location of the logging request call
+ * should be captured.
+ *
+ * @since 1.2.16
+ * @return the current value of the LocationInfo option.
+ */
+ public boolean getLocationInfo() {
+ return locationInfo;
+ }
+
+ /**
+ * The LocationInfo option takes a boolean value. By default, it is
+ * set to false which means there will be no effort to extract the location
+ * information related to the event. As a result, the event that will be
+ * ultimately logged will likely to contain the wrong location information
+ * (if present in the log format).
+ *
+ *
+ * Location information extraction is comparatively very slow and should be
+ * avoided unless performance is not a concern.
+ *
+ * @since 1.2.16
+ * @param flag true if location information should be extracted.
+ */
+ public void setLocationInfo(final boolean flag) {
+ locationInfo = flag;
+ }
+
+
+ /**
+ * Adds the event to the buffer. When full the buffer is flushed.
+ */
+ public void append(LoggingEvent event) {
+ event.getNDC();
+ event.getThreadName();
+ // Get a copy of this thread's MDC.
+ event.getMDCCopy();
+ if (locationInfo) {
+ event.getLocationInformation();
+ }
+ event.getRenderedMessage();
+ event.getThrowableStrRep();
+ 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);
+ } finally {
+ if(stmt != null) {
+ stmt.close();
+ }
+ closeConnection(con);
+ }
+
+ //System.out.println("Execute: " + sql);
+ }
+
+
+ /**
+ * 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) {
+ }
+
+ /**
+ * 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 (!DriverManager.getDrivers().hasMoreElements()) {
+ setDriver("sun.jdbc.odbc.JdbcOdbcDriver");
+ }
+
+ if (connection == null) {
+ connection = DriverManager.getConnection(databaseURL, databaseUser,
+ databasePassword);
+ }
+
+ 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!
+ */
+ public void flushBuffer() {
+ //Do the actual logging
+ removes.ensureCapacity(buffer.size());
+ for (Iterator i = buffer.iterator(); i.hasNext();) {
+ LoggingEvent logEvent = (LoggingEvent)i.next();
+ try {
+ String sql = getLogStatement(logEvent);
+ execute(sql);
+ }
+ catch (SQLException e) {
+ errorHandler.error("Failed to excute sql", e,
+ ErrorCode.FLUSH_FAILURE);
+ } finally {
+ removes.add(logEvent);
+ }
+ }
+
+ // 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 sql) {
+ sqlStatement = sql;
+ if (getLayout() == null) {
+ this.setLayout(new PatternLayout(sql));
+ }
+ else {
+ ((PatternLayout)getLayout()).setConversionPattern(sql);
+ }
+ }
+
+
+ /**
+ * Returns pre-formated statement eg: insert into LogTable (msg) values ("%m")
+ */
+ public String getSql() {
+ return sqlStatement;
+ }
+
+
+ public void setUser(String user) {
+ databaseUser = user;
+ }
+
+
+ public void setURL(String url) {
+ databaseURL = url;
+ }
+
+
+ public void setPassword(String password) {
+ databasePassword = password;
+ }
+
+
+ public void setBufferSize(int newBufferSize) {
+ bufferSize = newBufferSize;
+ buffer.ensureCapacity(bufferSize);
+ removes.ensureCapacity(bufferSize);
+ }
+
+
+ public String getUser() {
+ return databaseUser;
+ }
+
+
+ public String getURL() {
+ return databaseURL;
+ }
+
+
+ public String getPassword() {
+ return databasePassword;
+ }
+
+
+ public int getBufferSize() {
+ return bufferSize;
+ }
+
+
+ /**
+ * Ensures that the given driver class has been loaded for sql connection
+ * creation.
+ */
+ public void setDriver(String driverClass) {
+ try {
+ Class.forName(driverClass);
+ } catch (Exception e) {
+ errorHandler.error("Failed to load driver", e,
+ ErrorCode.GENERIC_FAILURE);
+ }
+ }
+}
+