I don't think we made the decision to move these specific classes into the core cvs yet. Did we?
-Mark > -----Original Message----- > From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED] > Sent: Tuesday, June 24, 2003 1:19 AM > To: [EMAIL PROTECTED] > Subject: cvs commit: jakarta-log4j/src/java/org/apache/log4j/jdbc > PreparedStatementSource.java PreparedStatementParameter.java > ConnectionSource.java JDBCReceiver.java UrlConnectionSource.java > PreparedStatementAppender.java JNDIConnectionSource.java > > > psmith 2003/06/24 01:19:11 > > Added: src/java/org/apache/log4j/jdbc > PreparedStatementSource.java > PreparedStatementParameter.java > ConnectionSource.java JDBCReceiver.java > UrlConnectionSource.java > PreparedStatementAppender.java > JNDIConnectionSource.java > Log: > moving to jakarta-log4j from jakarta-log4j-sandbox. > > Revision Changes Path > 1.1 > jakarta-log4j/src/java/org/apache/log4j/jdbc/PreparedStatement > Source.java > > Index: PreparedStatementSource.java > =================================================================== > /* > * > ============================================================== > ============== > * The Apache Software License, Version 1.1 > * > ============================================================== > ============== > * > * Copyright (C) 1999 The Apache Software Foundation. > All rights reserved. > * > * Redistribution and use in source and binary forms, with > or without modifica- > * tion, are permitted provided that the following > conditions are met: > * > * 1. Redistributions of source code must retain the > above copyright notice, > * this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the > above copyright notice, > * this list of conditions and the following disclaimer > in the documentation > * and/or other materials provided with the distribution. > * > * 3. The end-user documentation included with the > redistribution, if any, must > * include the following acknowledgment: "This > product includes software > * developed by the Apache Software Foundation > (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the > software itself, if > * and wherever such third-party acknowledgments normally appear. > * > * 4. The names "log4j" and "Apache Software Foundation" > must not be used to > * endorse or promote products derived from this > software without prior > * written permission. For written permission, please contact > * [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be > called "Apache", nor may > * "Apache" appear in their name, without prior > written permission of the > * Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR > IMPLIED WARRANTIES, > * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > MERCHANTABILITY AND > * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN > NO EVENT SHALL THE > * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE > LIABLE FOR ANY DIRECT, > * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL DAMAGES (INCLU- > * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS OR SERVICES; LOSS > * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > HOWEVER CAUSED AND ON > * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, OR TORT > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY > WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * > * This software consists of voluntary contributions made > by many individuals > * on behalf of the Apache Software Foundation. For more > information on the > * Apache Software Foundation, please see <http://www.apache.org/>. > * > */ > > package org.apache.log4j.jdbc; > > import org.apache.log4j.spi.ErrorHandler; > import org.apache.log4j.spi.OptionHandler; > > import java.sql.Connection; > import java.sql.PreparedStatement; > import java.sql.SQLException; > > > /** > * The <code>PreparedStatementSource</code> interface > provides a pluggable > * means of creating [EMAIL PROTECTED] java.sql.PreparedStatement}s > for use with the > * [EMAIL PROTECTED] PreparedStatementAppender}. Create an > implementation of this > * interface if the default [EMAIL PROTECTED] > java.sql.PreparedStatement} created > * by the appender is not sufficient. > * <p> > * Note that since a [EMAIL PROTECTED] java.sql.CallableStatement} is a > * [EMAIL PROTECTED] java.sql.PreparedStatement} you can use this > * interface to set up calls to stored procedures if desired. > * > * @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a> > */ > public interface PreparedStatementSource extends OptionHandler { > /** > * Generate a [EMAIL PROTECTED] java.sql.PreparedStatement} for use > by the client. > * The client is responsible for closing the statement. > */ > public PreparedStatement generate( > PreparedStatementAppender psa, Connection conn) throws > SQLException; > > /** > * Set the error handler. > * > * @param errorHanlder the new error handler > */ > void setErrorHandler(ErrorHandler errorHandler); > } > > > > 1.1 > jakarta-log4j/src/java/org/apache/log4j/jdbc/PreparedStatement > Parameter.java > > Index: PreparedStatementParameter.java > =================================================================== > /* > * > ============================================================== > ============== > * The Apache Software License, Version 1.1 > * > ============================================================== > ============== > * > * Copyright (C) 1999 The Apache Software Foundation. > All rights reserved. > * > * Redistribution and use in source and binary forms, with > or without modifica- > * tion, are permitted provided that the following > conditions are met: > * > * 1. Redistributions of source code must retain the > above copyright notice, > * this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the > above copyright notice, > * this list of conditions and the following disclaimer > in the documentation > * and/or other materials provided with the distribution. > * > * 3. The end-user documentation included with the > redistribution, if any, must > * include the following acknowledgment: "This > product includes software > * developed by the Apache Software Foundation > (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the > software itself, if > * and wherever such third-party acknowledgments normally appear. > * > * 4. The names "log4j" and "Apache Software Foundation" > must not be used to > * endorse or promote products derived from this > software without prior > * written permission. For written permission, please contact > * [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be > called "Apache", nor may > * "Apache" appear in their name, without prior > written permission of the > * Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR > IMPLIED WARRANTIES, > * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > MERCHANTABILITY AND > * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN > NO EVENT SHALL THE > * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE > LIABLE FOR ANY DIRECT, > * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL DAMAGES (INCLU- > * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS OR SERVICES; LOSS > * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > HOWEVER CAUSED AND ON > * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, OR TORT > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY > WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * > * This software consists of voluntary contributions made > by many individuals > * on behalf of the Apache Software Foundation. For more > information on the > * Apache Software Foundation, please see <http://www.apache.org/>. > * > */ > > package org.apache.log4j.jdbc; > > import org.apache.log4j.Level; > import org.apache.log4j.spi.ErrorHandler; > import org.apache.log4j.spi.ThrowableInformation; > > import java.io.PrintWriter; > import java.io.StringReader; > import java.io.StringWriter; > > import java.math.BigDecimal; > > import java.sql.Date; > import java.sql.PreparedStatement; > import java.sql.SQLException; > import java.sql.Time; > import java.sql.Timestamp; > > > /** > * The <code>PreparedStatementParameter</code> class > encapsulates the > * information needed to set a parameter on a > * [EMAIL PROTECTED] java.sql.PreparedStatement}. > * > * @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a> > */ > public class PreparedStatementParameter implements Comparable { > private String columnName; > private int order; > private String jdbcSetter; > private ErrorHandler errorHandler; > > /** > * Default constructor. > */ > public PreparedStatementParameter() { > } > > /** > * Returns the columnName. > * @return String > */ > public String getColumnName() { > return columnName; > } > > /** > * Returns the jdbcSetter. > * @return String > */ > public String getJdbcSetter() { > return jdbcSetter; > } > > /** > * Returns the order. > * @return int > */ > public int getOrder() { > return order; > } > > /** > * Sets the columnName. > * @param columnName The columnName to set > */ > public void setColumnName(String columnName) { > this.columnName = columnName; > } > > /** > * Sets the jdbcSetter. > * @param jdbcSetter The jdbcSetter to set > */ > public void setJdbcSetter(String jdbcSetter) { > this.jdbcSetter = jdbcSetter; > } > > /** > * Sets the order. > * @param order The order to set > */ > public void setOrder(int order) { > this.order = order; > } > > /** > * Compares based on the order. > */ > public int compareTo(Object obj) { > PreparedStatementParameter that = > (PreparedStatementParameter) obj; > > if (this.order < that.order) { > return -1; > } else if (this.order == that.order) { > return 0; > } else { > return 1; > } > } > > /** > * Set this parameter on the given statement with the > given value. > * > * @param stmt the statement > * @param value the value to set > * > * @throws SQLException if the parameter could not be set > */ > public void setParameter(PreparedStatement stmt, String value) > throws SQLException { > if ("setString".equals(jdbcSetter)) { > stmt.setString(order, value); > } else if ("setCharacterStream".equals(jdbcSetter)) { > if (value == null) { > value = ""; > } > > stmt.setCharacterStream(order, new > StringReader(value), value.length()); > } else if ("setObject".equals(jdbcSetter)) { > stmt.setObject(order, value); > } else { > errorHandler.error("Unsupported setter for String: " > + jdbcSetter); > } > } > > /** > * Set this parameter on the given statement with the > given value. > * > * @param stmt the statement > * @param value the value to set > * > * @throws SQLException if the parameter could not be set > */ > public void setParameter(PreparedStatement stmt, > ThrowableInformation value) > throws SQLException { > final StringWriter buf = new StringWriter(); > > if ((value != null) && (value.getThrowable() != null)) { > value.getThrowable().printStackTrace(new PrintWriter(buf)); > } > > final String str = buf.getBuffer().toString(); > > if ("setString".equals(jdbcSetter)) { > stmt.setString(order, str); > } else if ("setCharacterStream".equals(jdbcSetter)) { > stmt.setCharacterStream(order, new StringReader(str), > str.length()); > } else if ("setObject".equals(jdbcSetter)) { > stmt.setObject(order, str); > } else { > errorHandler.error("Unsupported setter for Throwable: > " + jdbcSetter); > } > } > > /** > * Set this parameter on the given statement with the > given value. > * > * @param stmt the statement > * @param value the value to set > * > * @throws SQLException if the parameter could not be set > */ > public void setParameter(PreparedStatement stmt, Level value) > throws SQLException { > if ("setString".equals(jdbcSetter)) { > stmt.setString(order, String.valueOf(value)); > } else if ("setInt".equals(jdbcSetter)) { > stmt.setInt(order, value.toInt()); > } else if ("setObject".equals(jdbcSetter)) { > stmt.setObject(order, String.valueOf(value)); > } else if ("setLong".equals(jdbcSetter)) { > stmt.setLong(order, value.toInt()); > } else if ("setDouble".equals(jdbcSetter)) { > stmt.setDouble(order, value.toInt()); > } else if ("setBigDecimal".equals(jdbcSetter)) { > stmt.setBigDecimal(order, new BigDecimal(value.toInt())); > } else if ("setFloat".equals(jdbcSetter)) { > stmt.setFloat(order, value.toInt()); > } else { > errorHandler.error("Unsupported setter for Level: " + > jdbcSetter); > } > } > > /** > * Set this parameter on the given statement with the > given value. > * > * @param stmt the statement > * @param value the value to set > * > * @throws SQLException if the parameter could not be set > */ > public void setParameter(PreparedStatement stmt, long value) > throws SQLException { > if ("setTimestamp".equals(jdbcSetter)) { > stmt.setTimestamp(order, new Timestamp(value)); > } else if ("setDate".equals(jdbcSetter)) { > stmt.setDate(order, new Date(value)); > } else if ("setTime".equals(jdbcSetter)) { > stmt.setTime(order, new Time(value)); > } else if ("setString".equals(jdbcSetter)) { > stmt.setString(order, String.valueOf(value)); > } else if ("setObject".equals(jdbcSetter)) { > stmt.setObject(order, new Long(value)); > } else if ("setLong".equals(jdbcSetter)) { > stmt.setLong(order, value); > } else if ("setDouble".equals(jdbcSetter)) { > stmt.setDouble(order, value); > } else if ("setBigDecimal".equals(jdbcSetter)) { > stmt.setBigDecimal(order, new BigDecimal(value)); > } else if ("setInt".equals(jdbcSetter)) { > stmt.setInt(order, (int) value); > } else if ("setFloat".equals(jdbcSetter)) { > stmt.setFloat(order, (float) value); > } else { > errorHandler.error("Unsupported setter for long: " + > jdbcSetter); > } > } > > /** > * Sets the errorHandler. > * @param errorHandler The errorHandler to set > */ > public void setErrorHandler(ErrorHandler errorHandler) { > this.errorHandler = errorHandler; > } > } > > > > 1.1 > jakarta-log4j/src/java/org/apache/log4j/jdbc/ConnectionSource.java > > Index: ConnectionSource.java > =================================================================== > /* > * > ============================================================== > ============== > * The Apache Software License, Version 1.1 > * > ============================================================== > ============== > * > * Copyright (C) 1999 The Apache Software Foundation. > All rights reserved. > * > * Redistribution and use in source and binary forms, with > or without modifica- > * tion, are permitted provided that the following > conditions are met: > * > * 1. Redistributions of source code must retain the > above copyright notice, > * this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the > above copyright notice, > * this list of conditions and the following disclaimer > in the documentation > * and/or other materials provided with the distribution. > * > * 3. The end-user documentation included with the > redistribution, if any, must > * include the following acknowledgment: "This > product includes software > * developed by the Apache Software Foundation > (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the > software itself, if > * and wherever such third-party acknowledgments normally appear. > * > * 4. The names "log4j" and "Apache Software Foundation" > must not be used to > * endorse or promote products derived from this > software without prior > * written permission. For written permission, please contact > * [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be > called "Apache", nor may > * "Apache" appear in their name, without prior > written permission of the > * Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR > IMPLIED WARRANTIES, > * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > MERCHANTABILITY AND > * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN > NO EVENT SHALL THE > * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE > LIABLE FOR ANY DIRECT, > * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL DAMAGES (INCLU- > * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS OR SERVICES; LOSS > * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > HOWEVER CAUSED AND ON > * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, OR TORT > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY > WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * > * This software consists of voluntary contributions made > by many individuals > * on behalf of the Apache Software Foundation. For more > information on the > * Apache Software Foundation, please see <http://www.apache.org/>. > * > */ > > package org.apache.log4j.jdbc; > > import org.apache.log4j.spi.ErrorHandler; > import org.apache.log4j.spi.OptionHandler; > > import java.sql.Connection; > import java.sql.SQLException; > > > /** > * The <code>ConnectionSource</code> interface provides a > pluggable means of > * transparently obtaining JDBC [EMAIL PROTECTED] > java.sql.Connection}s for log4j classes > * that require the use of a [EMAIL PROTECTED] java.sql.Connection}. > * > * @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a> > */ > public interface ConnectionSource extends OptionHandler { > /** > * Obtain a [EMAIL PROTECTED] java.sql.Connection} for use. The client is > * responsible for closing the [EMAIL PROTECTED] > java.sql.Connection} when it is no > * longer required. > * > * @throws SQLException if a [EMAIL PROTECTED] > java.sql.Connection} could not be > * obtained > */ > Connection getConnection() throws SQLException; > > /** > * Set the error handler. > * > * @param errorHanlder the new error handler > */ > void setErrorHandler(ErrorHandler errorHandler); > } > > > > 1.1 > jakarta-log4j/src/java/org/apache/log4j/jdbc/JDBCReceiver.java > > Index: JDBCReceiver.java > =================================================================== > /* > * > ============================================================== > ============== > * The Apache Software License, Version 1.1 > * > ============================================================== > ============== > * > * Copyright (C) 1999 The Apache Software Foundation. > All rights reserved. > * > * Redistribution and use in source and binary forms, with > or without modifica- > * tion, are permitted provided that the following > conditions are met: > * > * 1. Redistributions of source code must retain the > above copyright notice, > * this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the > above copyright notice, > * this list of conditions and the following disclaimer > in the documentation > * and/or other materials provided with the distribution. > * > * 3. The end-user documentation included with the > redistribution, if any, must > * include the following acknowledgment: "This > product includes software > * developed by the Apache Software Foundation > (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the > software itself, if > * and wherever such third-party acknowledgments normally appear. > * > * 4. The names "log4j" and "Apache Software Foundation" > must not be used to > * endorse or promote products derived from this > software without prior > * written permission. For written permission, please contact > * [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be > called "Apache", nor may > * "Apache" appear in their name, without prior > written permission of the > * Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR > IMPLIED WARRANTIES, > * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > MERCHANTABILITY AND > * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN > NO EVENT SHALL THE > * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE > LIABLE FOR ANY DIRECT, > * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL DAMAGES (INCLU- > * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS OR SERVICES; LOSS > * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > HOWEVER CAUSED AND ON > * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, OR TORT > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY > WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * > * This software consists of voluntary contributions made > by many individuals > * on behalf of the Apache Software Foundation. For more > information on the > * Apache Software Foundation, please see <http://www.apache.org/>. > * > */ > > package org.apache.log4j.jdbc; > > import org.apache.log4j.Level; > import org.apache.log4j.Logger; > import org.apache.log4j.plugins.Receiver; > import org.apache.log4j.spi.LocationInfo; > import org.apache.log4j.spi.LoggingEvent; > > import java.sql.Connection; > import java.sql.DriverManager; > import java.sql.ResultSet; > import java.sql.SQLException; > import java.sql.Statement; > > import java.util.Hashtable; > import java.util.StringTokenizer; > > > /** > * Convert Log data stored in a database into LoggingEvents. > * > * This receiver executes the SQL statement defined in the > plugin configuration once, > * converting the rows it finds into LoggingEvents, and then ends. > * > * The configuration of this plugin is very similar to the > JDBCAppender, however a > * SELECT statement must be provided instead of an INSERT statement. > * > * The select statement must provide all fields which > define a LoggingEvent, with > * the column names matching this list: LOGGER, TIMESTAMP, > LEVEL, THREAD, MESSAGE, > * NDC, MDC, CLASS, METHOD, FILE, LINE, PROPERTIES, EXCEPTION > * > * If the source table doesn't provide a column for any of > the fields, the field must > * still be provided in the SELECT statement. For example, > if a JDBCAppender was used > * to write only a timestamp, level and patternlayout > combination of message and other > * fields, here is a sample SQL statement you would provide > as the plugin 'sql' param: > * > * EXAMPLE MYSQL SELECT STATEMENT WHICH CAN BE USED TO > PROVIDE EVENTS TO CHAINSAW - > * (counter is an autoincrement int column and timestamp is > a datetime column): > * > * param name="sql" value='select logger as LOGGER, > timestamp as TIMESTAMP, > * level as LEVEL, thread as THREAD, message as MESSAGE, > ndc as NDC, mdc as MDC, > * class as CLASS, method as METHOD, file as FILE, line as LINE, > * > concat("{{log4japp,databaselogs,log4jmachinename,mymachine,log > 4jid,", COUNTER, "}}") > * as PROPERTIES, "" as EXCEPTION from logtable' > * > * In other words, if a number of LoggingEvent properties > were combined into one field > * in the database, the combined field should be set as the > MESSAGE column in the > * SELECT statement. Missing columns should be set to "". > * > * Make sure to alias the column names if needed to match > the list provided above. > * > * NOTE: Patternlayout doesn't support Properties and > JDBCAppender doesn't support > * exceptions, but the fields can be defined in the SQL > statement and included in > * the event. > * > * This means that log4japp and/or log4jmachinename > properties can be provided and > * the properties may be used to create a unique tab for the events. > * > * Both {{name, value, name2, value2}} formats and formats > without the double braces > * are supported for MDC and properties fields. > * > * NOTE: If refreshMillis is not set, the receiver will run > the SQL ONCE. If it is set, > * the SQL will be ran every refreshMillis milliseconds. > * > * WARNING: Using refreshMillis with an event processing > tool that doesn't know how > * to ignore duplicate events will result in duplicate > events being processed. > * > * CREATING EVENTS USABLE BY CHAINSAW: > * Chainsaw's event reception ignores duplicate event > delivery, so refreshMillis can be > * set and JDBCReceiver can be used as a primary receiver > with Chainsaw - allowing > * a timed re-retrieve of events from a database into the > UI for analysis of events. > * > * Include the properties as provided in the example SQL > above to successfully get > * events to be delivered into Chainsaw. The log4jid > property must be provided by the > * database and the timestamp field must be a datetime. > The log4jmachinename and log4japp > * properties are specific to your application and define > which unique tab the events are > * delivered to. > * > * @author Scott Deboy <[EMAIL PROTECTED]> > * > */ > public class JDBCReceiver extends Receiver { > private boolean isActive = false; > > /** > * URL of the DB for default connection handling > */ > protected String databaseURL = "jdbc:odbc:myDB"; > > /** > * User to connect as for default connection handling > */ > protected String databaseUser = "me"; > > /** > * User to use for default connection handling > */ > protected String databasePassword = "mypassword"; > protected Connection connection = null; > protected String sqlStatement = ""; > protected String refreshMillis = null; > > public JDBCReceiver() { > } > > /** > * Start a thread which will handle the retrieval. > */ > public void activateOptions() { > new JDBCReceiverThread().start(); > } > > 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; > } > > public void close() { > try { > if ((connection != null) && !connection.isClosed()) { > connection.close(); > } > } catch (SQLException e) { > e.printStackTrace(); > } > } > > public void finalize() { > close(); > } > > public synchronized void shutdown() { > } > > public void setRefreshMillis(String s) { > refreshMillis = s; > } > > public String getRefreshMillis() { > return refreshMillis; > } > > public void setSql(String s) { > sqlStatement = s; > } > > public String getSql() { > return sqlStatement; > } > > public void setUser(String user) { > databaseUser = user; > } > > public String getUser() { > return databaseUser; > } > > public void setURL(String url) { > databaseURL = url; > } > > public String getURL() { > return databaseURL; > } > > public void setPassword(String password) { > databasePassword = password; > } > > public String getPassword() { > return databasePassword; > } > > /** > * 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) { > e.printStackTrace(); > } > } > > class JDBCReceiverThread extends Thread { > public JDBCReceiverThread() { > setDaemon(true); > } > > public void run() { > active = true; > > do { > try { > Logger logger = null; > long timeStamp = 0L; > String level = null; > String threadName = null; > Object message = null; > String ndc = null; > Hashtable mdc = null; > String[] exception = null; > String className = null; > String methodName = null; > String fileName = null; > String lineNumber = null; > Hashtable properties = null; > > Statement statement = getConnection().createStatement(); > ResultSet rs = statement.executeQuery(sqlStatement); > > while (rs.next()) { > logger = Logger.getLogger(rs.getString("LOGGER")); > timeStamp = rs.getTimestamp("TIMESTAMP").getTime(); > > level = rs.getString("LEVEL"); > threadName = rs.getString("THREAD"); > message = rs.getString("MESSAGE"); > ndc = rs.getString("NDC"); > > String mdcString = rs.getString("MDC"); > mdc = new Hashtable(); > > if (mdcString != null) { > //support MDC being wrapped in {{name, > value}} or just name, value > if ( > (mdcString.indexOf("{{") > -1) > && (mdcString.indexOf("}}") > -1)) { > mdcString = > mdcString.substring( > mdcString.indexOf("{{") + 2, > mdcString.indexOf("}}")); > } > > StringTokenizer tok = new > StringTokenizer(mdcString, ","); > > while (tok.countTokens() > 1) { > mdc.put(tok.nextToken(), tok.nextToken()); > } > } > > //although exception is not supported by > jdbcappender, it needs to be provided in the SQL string > exception = new String[] { rs.getString("EXCEPTION") }; > className = rs.getString("CLASS"); > methodName = rs.getString("METHOD"); > fileName = rs.getString("FILE"); > lineNumber = rs.getString("LINE"); > > //although properties are not supported by > JDBCAppender, if they are provided in the > //SQL they can be used here (for example, to > route events to a unique tab if > //the machinename and/or appname property are set) > String propertiesString = rs.getString("PROPERTIES"); > properties = new Hashtable(); > > if (propertiesString != null) { > //support properties being wrapped in {{name, > value}} or just name, value > if ( > (propertiesString.indexOf("{{") > -1) > && (propertiesString.indexOf("}}") > -1)) { > propertiesString = > propertiesString.substring( > propertiesString.indexOf("{{") + 2, > propertiesString.indexOf("}}")); > } > > StringTokenizer tok2 = > new StringTokenizer(propertiesString, ","); > > while (tok2.countTokens() > 1) { > properties.put(tok2.nextToken(), tok2.nextToken()); > } > } > > Level levelImpl = Level.toLevel(level); > > LoggingEvent event = > new LoggingEvent( > logger.getName(), logger, timeStamp, > levelImpl, threadName, > message, ndc, mdc, exception, > new LocationInfo(fileName, className, > methodName, lineNumber), > properties); > > doPost(event); > } > } catch (SQLException se) { > se.printStackTrace(); > } > > if (refreshMillis != null) { > try { > Thread.sleep(Integer.parseInt(refreshMillis)); > } catch (InterruptedException ie) { > } > } > } while (refreshMillis != null); > } > } > } > > > > 1.1 > jakarta-log4j/src/java/org/apache/log4j/jdbc/UrlConnectionSource.java > > Index: UrlConnectionSource.java > =================================================================== > /* > * > ============================================================== > ============== > * The Apache Software License, Version 1.1 > * > ============================================================== > ============== > * > * Copyright (C) 1999 The Apache Software Foundation. > All rights reserved. > * > * Redistribution and use in source and binary forms, with > or without modifica- > * tion, are permitted provided that the following > conditions are met: > * > * 1. Redistributions of source code must retain the > above copyright notice, > * this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the > above copyright notice, > * this list of conditions and the following disclaimer > in the documentation > * and/or other materials provided with the distribution. > * > * 3. The end-user documentation included with the > redistribution, if any, must > * include the following acknowledgment: "This > product includes software > * developed by the Apache Software Foundation > (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the > software itself, if > * and wherever such third-party acknowledgments normally appear. > * > * 4. The names "log4j" and "Apache Software Foundation" > must not be used to > * endorse or promote products derived from this > software without prior > * written permission. For written permission, please contact > * [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be > called "Apache", nor may > * "Apache" appear in their name, without prior > written permission of the > * Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR > IMPLIED WARRANTIES, > * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > MERCHANTABILITY AND > * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN > NO EVENT SHALL THE > * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE > LIABLE FOR ANY DIRECT, > * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL DAMAGES (INCLU- > * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS OR SERVICES; LOSS > * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > HOWEVER CAUSED AND ON > * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, OR TORT > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY > WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * > * This software consists of voluntary contributions made > by many individuals > * on behalf of the Apache Software Foundation. For more > information on the > * Apache Software Foundation, please see <http://www.apache.org/>. > * > */ > > package org.apache.log4j.jdbc; > > import org.apache.log4j.spi.ErrorCode; > import org.apache.log4j.spi.ErrorHandler; > > import java.sql.Connection; > import java.sql.DriverManager; > import java.sql.SQLException; > > > /** > * The UrlConnectionSource is an implementation of [EMAIL PROTECTED] > ConnectionSource} > * that obtains the Connection in the traditional JDBC > manner based on the > * connection URL. > * <p> > * Note that this class will estanblish a new Connection > for each call to > * [EMAIL PROTECTED] #getConnection()}. It is recommended that you > either use a JDBC > * driver that natively supported Connection pooling or > that you create > * your own implementation of [EMAIL PROTECTED] ConnectionSource} > that taps into whatever > * pooling mechanism you are already using. (If you have > access to a JNDI > * implementation that supports [EMAIL PROTECTED] > javax.sql.DataSource}s, e.g. within > * a J2EE application server, see [EMAIL PROTECTED] JNDIConnectionSource}). > * <p> > * Sample configuration:<br> > * <pre> > * <connectionSource > class="org.apache.log4j.jdbc.UrlConnectionSource"> > * <param name="driver" > value="com.mysql.jdbc.Driver" /> > * <param name="url" > value="jdbc:mysql://localhost:3306/mydb" /> > * <param name="username" value="myUser" /> > * <param name="password" value="myPassword" /> > * </connectionSource> > * </pre> > * > * @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a> > */ > public class UrlConnectionSource implements ConnectionSource { > private String driver = null; > private String url = null; > private String username = null; > private String password = null; > private ErrorHandler errorHandler = null; > > public void activateOptions() { > try { > Class.forName(driver); > } catch (final ClassNotFoundException cnfe) { > if (errorHandler != null) { > errorHandler.error( > "Could not load JDBC driver class: " + driver, cnfe, > ErrorCode.GENERIC_FAILURE); > } else { > cnfe.printStackTrace(); > } > } > } > > /** > * @see org.apache.log4j.jdbc.ConnectionSource#getConnection() > */ > public Connection getConnection() throws SQLException { > if (username == null) { > return DriverManager.getConnection(url); > } else { > return DriverManager.getConnection(url, username, password); > } > } > > /** > * Returns the password. > * @return String > */ > public String getPassword() { > return password; > } > > /** > * Returns the url. > * @return String > */ > public String getUrl() { > return url; > } > > /** > * Returns the username. > * @return String > */ > public String getUsername() { > return username; > } > > /** > * Sets the password. > * @param password The password to set > */ > public void setPassword(String password) { > this.password = password; > } > > /** > * Sets the url. > * @param url The url to set > */ > public void setUrl(String url) { > this.url = url; > } > > /** > * Sets the username. > * @param username The username to set > */ > public void setUsername(String username) { > this.username = username; > } > > /** > * Returns the driver. > * @return String > */ > public String getDriver() { > return driver; > } > > /** > * Sets the driver. > * @param driver The driver to set > */ > public void setDriver(String driver) { > this.driver = driver; > } > > /** > * Sets the error handler. > * @param errorHandler the error handler to set > */ > public void setErrorHandler(ErrorHandler errorHandler) { > this.errorHandler = errorHandler; > } > } > > > > 1.1 > jakarta-log4j/src/java/org/apache/log4j/jdbc/PreparedStatement > Appender.java > > Index: PreparedStatementAppender.java > =================================================================== > /* > * > ============================================================== > ============== > * The Apache Software License, Version 1.1 > * > ============================================================== > ============== > * > * Copyright (C) 1999 The Apache Software Foundation. > All rights reserved. > * > * Redistribution and use in source and binary forms, with > or without modifica- > * tion, are permitted provided that the following > conditions are met: > * > * 1. Redistributions of source code must retain the > above copyright notice, > * this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the > above copyright notice, > * this list of conditions and the following disclaimer > in the documentation > * and/or other materials provided with the distribution. > * > * 3. The end-user documentation included with the > redistribution, if any, must > * include the following acknowledgment: "This > product includes software > * developed by the Apache Software Foundation > (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the > software itself, if > * and wherever such third-party acknowledgments normally appear. > * > * 4. The names "log4j" and "Apache Software Foundation" > must not be used to > * endorse or promote products derived from this > software without prior > * written permission. For written permission, please contact > * [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be > called "Apache", nor may > * "Apache" appear in their name, without prior > written permission of the > * Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR > IMPLIED WARRANTIES, > * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > MERCHANTABILITY AND > * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN > NO EVENT SHALL THE > * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE > LIABLE FOR ANY DIRECT, > * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL DAMAGES (INCLU- > * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS OR SERVICES; LOSS > * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > HOWEVER CAUSED AND ON > * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, OR TORT > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY > WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * > * This software consists of voluntary contributions made > by many individuals > * on behalf of the Apache Software Foundation. For more > information on the > * Apache Software Foundation, please see <http://www.apache.org/>. > * > */ > > package org.apache.log4j.jdbc; > > import org.apache.log4j.AppenderSkeleton; > import org.apache.log4j.spi.ErrorCode; > import org.apache.log4j.spi.LoggingEvent; > > import java.sql.Connection; > import java.sql.PreparedStatement; > import java.sql.SQLException; > > import java.util.ArrayList; > > > /** > * The <code>PreparedStatementAppender</code> class > provides a JDBC-based > * appender that uses [EMAIL PROTECTED] java.sql.PreparedStatement}s > for efficiency. > * Note that this appender takes advantage of the advanced > capabilities of the > * [EMAIL PROTECTED] org.apache.log4j.xml.DOMConfigurator} and > therefore must be > * configured with an XML configuration file. > * <p> > * This appender has a number of configurable options. > First and foremost is > * the <code>connectionSource</code>, an implementation of > * [EMAIL PROTECTED] ConnectionSource}. For example, [EMAIL PROTECTED] > UrlConnectionSource} and > * [EMAIL PROTECTED] JNDIConnectionSource} are provider by log4j. It > is recommended that > * you use [EMAIL PROTECTED] JNDIConnectionSource} whenever possible > and create your own > * implementation of [EMAIL PROTECTED] ConnectionSource} otherwise. Use > * [EMAIL PROTECTED] UrlConnectionSource} if you just want to get > something working fast. > * <p> > * Second is the optional <code>preparedStatementSource</code>, an > * implementation of [EMAIL PROTECTED] PreparedStatementSource}. > Only specify this if > * the default statement > * provider by <code>PreparedStatementAppender</code> is > not sufficient. > * By default a statement similar to "<code>INSERT > INTO LOG4J (message, > * logger, level) VALUES (?, ?, ?)</code>" will be > generated based on the > * other parameters (see the example below). > * <p> > * Next, there is a parameter for each part of the logging > event you might > * want to include in database:<br> > * <table border="1" rules="all" cellpadding="3"> > * <tr> > * <th>Parameter</th> > * <th>Description</th> > * <th>Default JDBC Setter</th> > * </tr> > * <tr> > * <td>messageParameter</td> > * <td>The raw log message</td> > * <td>setString</td> > * </tr> > * <tr> > * <td>formattedMessageParameter</td> > * <td>The formatted log message</td> > * <td>setString</td> > * </tr> > * <tr> > * <td>loggerParameter</td> > * <td>The logger</td> > * <td>setString</td> > * </tr> > * <tr> > * <td>levelParameter</td> > * <td>The log message level</td> > * <td>setString</td> > * </tr> > * <tr> > * <td>ndcParameter</td> > * <td>The NDC (nested diagnostic context) of the log > message</td> > * <td>setString</td> > * </tr> > * <tr> > * <td>exceptionParameter</td> > * <td>The message of the exception, i.e. the value of > * <code>Exception.getMessage()</code>, for the > exception passed to the > * logger</td> > * <td>setString</td> > * </tr> > * <tr> > * <td>stackParameter</td> > * <td>The stack trace of the exception passed to the > logger. Beware that > * no effort is made to ensure that the stack > trace will fit inside the > * database column provided.</td> > * <td>setCharacterStream</td> > * </tr> > * <tr> > * <td>timeStampParameter</td> > * <td>The time stamp of the log message</td> > * <td>setTimerStamp</td> > * </tr> > * </table><br> > * Define whichever subset of these you wish to include in > your database table. > * If the JDBC setter referenced above is sufficient for > the column in > * question, you may omit the setter value in the configuration. > * <p> > * Finally, the table parameter is used to indicate the > table into which to > * insert the rows for the default prepared statement. > * > * <h3>Example Configurations</h3> > * All of the example configurations assume that the > database vendor is MySQL, > * the instance is test, the user is myUser and the > password is myPassword. > * The database table is LOG4J and looks like:<br> > * <pre> > * mysql> desc LOG4J; > * +-----------+--------------+------+-----+---------+-------+ > * | Field | Type | Null | Key | Default | Extra | > * +-----------+--------------+------+-----+---------+-------+ > * | msg | blob | YES | | NULL | | > * | logger | varchar(255) | YES | | NULL | | > * | level | varchar(5) | YES | | NULL | | > * | ndc | varchar(255) | YES | | NULL | | > * | exception | blob | YES | | NULL | | > * | stack | blob | YES | | NULL | | > * | formatted | blob | YES | | NULL | | > * | stamp | datetime | YES | | NULL | | > * +-----------+--------------+------+-----+---------+-------+ > * </pre> > * > * <h4>Quick and dirty</h4> > * Include the following in your log4j.xml file:<br> > * <pre> > * <appender name="X" > class="org.apache.log4j.jdbc.PreparedStatementAppender"> > * <layout class="org.apache.log4j.PatternLayout"> > * <param name="ConversionPattern" value="%d %-5p > %c - %m%n"/> > * </layout> > * <connectionSource > class="org.apache.log4j.jdbc.UrlConnectionSource"> > * <param name="driver" value="com.mysql.jdbc.Driver" /> > * <param name="url" > value="jdbc:mysql://localhost:3306/test" /> > * <param name="username" value="myUser" /> > * <param name="password" value="myPassword" /> > * </connectionSource> > * <param name="table" value="LOG4J"/> > * <messageParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="msg" /> > * </messageParameter> > * <loggerParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="logger" /> > * </loggerParameter> > * <levelParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="level" /> > * </levelParameter> > * <ndcParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="ndc" /> > * </ndcParameter> > * <exceptionParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="exception" /> > * </exceptionParameter> > * <stackParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="stack" /> > * </stackParameter> > * <formattedMessageParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="formatted" /> > * </formattedMessageParameter> > * <timeStampParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="stamp" /> > * </timeStampParameter> > * </appender> > * </pre> > * <p> > * This configuration will generate a prepared statement > of the form > * <code>INSERT INTO LOG4J (msg, logger, level, ndc, > exception, stack, > * formatted, stamp) VALUES (?, ?, ?, ?, ?, ?, ?, > ?)</code>. If you do not > * need one of the columns, for example <code>msg</code>, > simply do not include > * it in the configuration. > * > * <h4>JNDI-based Configuration</h4> > * This example demonstrates the JNDIConnectionSource:<br> > * <pre> > * <appender name="X" > class="org.apache.log4j.jdbc.PreparedStatementAppender"> > * <layout class="org.apache.log4j.PatternLayout"> > * <param name="ConversionPattern" value="%d %-5p > %c - %m%n"/> > * </layout> > * <b> > * <connectionSource > class="org.apache.log4j.jdbc.JNDIConnectionSource"> > * <param name="jndiLocation" value="jdbc/MySQLDS" /> > * </connectionSource> > * </b> > * <param name="table" value="LOG4J"/> > * <loggerParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="logger" /> > * </loggerParameter> > * <levelParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="level" /> > * </levelParameter> > * <exceptionParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="exception" /> > * </exceptionParameter> > * <stackParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="stack" /> > * </stackParameter> > * <formattedMessageParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="formatted" /> > * </formattedMessageParameter> > * <timeStampParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="stamp" /> > * </timeStampParameter> > * </appender> > * </pre> > * Note that this configuration will produce a slightly > different prepared > * statement: <code>INSERT INTO LOG4J (logger, level, > exception, stack, > * formatted, stamp) VALUES (?, ?, ?, ?, ?)</code>. This > was done purely for > * demonstration purposes, there is no reason > <code>messageParameter</code> and > * <code>ndcParameter</code> could not be included. > * > * <h4>Custom PreparedStatementSopurce Configuration</h4> > * This example demonstrates a custom [EMAIL PROTECTED] > PreparedStatementSource}:<br> > * <pre> > * <appender name="X" > class="org.apache.log4j.jdbc.PreparedStatementAppender"> > * <layout class="org.apache.log4j.PatternLayout"> > * <param name="ConversionPattern" value="%d %-5p > %c - %m%n"/> > * </layout> > * <connectionSource > class="org.apache.log4j.jdbc.JNDIConnectionSource"> > * <param name="jndiLocation" value="jdbc/MySQLDS" /> > * </connectionSource> > * <b> > * <preparedStatementSource > class="my.wonderful.implmentation.of.PreparedStatementSource"> > * <param name="myParam1" value="myValue1" /> > * <param name="myParam2" value="myValue2" /> > * </preparedStatementSource> > * </b> > * <loggerParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="logger" /> > * </loggerParameter> > * <levelParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="level" /> > * </levelParameter> > * <exceptionParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="exception" /> > * </exceptionParameter> > * <stackParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="stack" /> > * </stackParameter> > * <formattedMessageParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="formatted" /> > * </formattedMessageParameter> > * <timeStampParameter > class="org.apache.log4j.jdbc.PreparedStatementParameter"> > * <param name="columnName" value="stamp" /> > * </timeStampParameter> > * </appender> > * </pre> > * Use this configuration when you want to provide your own > * [EMAIL PROTECTED] PreparedStatementSource} becuase the default > statements are > * insufficient. For example, you want to call a stored > procedure or the like. > * Note that you still must provide the <code>xxxParameter</code> > * configurations. > * > * @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a> > */ > public class PreparedStatementAppender extends AppenderSkeleton { > private String table = "LOG4J"; > private PreparedStatementParameter messageParameter = null; > private PreparedStatementParameter loggerParameter = null; > private PreparedStatementParameter levelParameter = null; > private PreparedStatementParameter ndcParameter = null; > private PreparedStatementParameter exceptionParameter = null; > private PreparedStatementParameter stackParameter = null; > private PreparedStatementParameter timeStampParameter = null; > private PreparedStatementParameter > formattedMessageParameter = null; > private ConnectionSource connectionSource = null; > private PreparedStatementSource preparedStatementSource = null; > private StringBuffer sql = new StringBuffer(); > private final ArrayList params = new ArrayList(); > > /** > * Default constructor. > */ > public PreparedStatementAppender() { > } > > public String getTable() { > return table; > } > > public void setTable(String newTable) { > table = newTable; > } > > public void activateOptions() { > super.activateOptions(); > > // Set up default setters and create the params list > if (messageParameter != null) { > params.add(messageParameter); > messageParameter.setErrorHandler(errorHandler); > > if (messageParameter.getJdbcSetter() == null) { > messageParameter.setJdbcSetter("setString"); > } > } > > if (loggerParameter != null) { > params.add(loggerParameter); > loggerParameter.setErrorHandler(errorHandler); > > if (loggerParameter.getJdbcSetter() == null) { > loggerParameter.setJdbcSetter("setString"); > } > } > > if (levelParameter != null) { > params.add(levelParameter); > levelParameter.setErrorHandler(errorHandler); > > if (levelParameter.getJdbcSetter() == null) { > levelParameter.setJdbcSetter("setString"); > } > } > > if (ndcParameter != null) { > params.add(ndcParameter); > ndcParameter.setErrorHandler(errorHandler); > > if (ndcParameter.getJdbcSetter() == null) { > ndcParameter.setJdbcSetter("setString"); > } > } > > if (exceptionParameter != null) { > params.add(exceptionParameter); > exceptionParameter.setErrorHandler(errorHandler); > > if (exceptionParameter.getJdbcSetter() == null) { > exceptionParameter.setJdbcSetter("setString"); > } > } > > if (stackParameter != null) { > params.add(stackParameter); > stackParameter.setErrorHandler(errorHandler); > > if (stackParameter.getJdbcSetter() == null) { > stackParameter.setJdbcSetter("setCharacterStream"); > } > } > > if (timeStampParameter != null) { > params.add(timeStampParameter); > timeStampParameter.setErrorHandler(errorHandler); > > if (timeStampParameter.getJdbcSetter() == null) { > timeStampParameter.setJdbcSetter("setTimestamp"); > } > } > > if (formattedMessageParameter != null) { > params.add(formattedMessageParameter); > formattedMessageParameter.setErrorHandler(errorHandler); > > if (formattedMessageParameter.getJdbcSetter() == null) { > formattedMessageParameter.setJdbcSetter("setString"); > } > } > > params.trimToSize(); > > connectionSource.setErrorHandler(errorHandler); > connectionSource.activateOptions(); > > if (preparedStatementSource == null) { > generateSql(); > } else { > preparedStatementSource.activateOptions(); > } > } > > public void append(LoggingEvent event) { > Throwable throwable = null; > > if (event.getThrowableInformation() != null) { > throwable = event.getThrowableInformation().getThrowable(); > } > > Connection conn = null; > PreparedStatement stmt = null; > > try { > conn = connectionSource.getConnection(); > > if (preparedStatementSource != null) { > stmt = preparedStatementSource.generate(this, conn); > } else { > stmt = conn.prepareStatement(sql.toString()); > } > > // Set stmt parameters > if (messageParameter != null) { > messageParameter.setParameter( > stmt, String.valueOf(event.getMessage())); > } > > if (loggerParameter != null) { > loggerParameter.setParameter(stmt, event.getLoggerName()); > } > > if (levelParameter != null) { > levelParameter.setParameter(stmt, event.getLevel()); > } > > if (ndcParameter != null) { > ndcParameter.setParameter(stmt, event.getNDC()); > } > > if (exceptionParameter != null) { > if (throwable != null) { > exceptionParameter.setParameter(stmt, > throwable.getMessage()); > } else { > exceptionParameter.setParameter(stmt, ""); > } > } > > if (stackParameter != null) { > stackParameter.setParameter(stmt, > event.getThrowableInformation()); > } > > if (timeStampParameter != null) { > timeStampParameter.setParameter(stmt, event.timeStamp); > } > > if (formattedMessageParameter != null) { > formattedMessageParameter.setParameter( > stmt, getLayout().format(event)); > } > > // OK, do the dirty deed > stmt.executeUpdate(); > } catch (final SQLException sqle) { > errorHandler.error( > "Error executing SQL: " + sql, sqle, > ErrorCode.GENERIC_FAILURE, event); > } finally { > closeJdbc(stmt, conn); > } > } > > public boolean requiresLayout() { > return true; > } > > public void close() { > } > > private void generateSql() { > int colCount = 0; > sql.setLength(0); > sql.append("INSERT INTO ").append(table).append(" ("); > > for (int i = 0; i < params.size(); i++) { > colCount = appendColumn(getParameter(i), colCount); > } > > sql.append(") VALUES ("); > > for (int i = 0; i < colCount; i++) { > sql.append((i == 0) ? "?" : ", ?"); > } > > sql.append(")"); > System.out.println(sql); > } > > private int appendColumn(PreparedStatementParameter psp, > int colCount) { > if ((psp != null) && (psp.getColumnName() != null)) { > sql.append((colCount == 0) ? "" : ", > ").append(psp.getColumnName()); > psp.setOrder(++colCount); > > System.out.println( > "JDBC setter for " + psp.getColumnName() + " is " > + psp.getJdbcSetter()); > } > > return colCount; > } > > private void closeJdbc(PreparedStatement stmt, Connection conn) { > try { > if (stmt != null) { > stmt.close(); > } > } catch (final SQLException sqle) { > errorHandler.error( > "Error closing prepared statement", sqle, > ErrorCode.GENERIC_FAILURE); > } > > try { > if (conn != null) { > conn.close(); > } > } catch (final SQLException sqle) { > errorHandler.error( > "Error closing connection", sqle, > ErrorCode.GENERIC_FAILURE); > } > } > > private PreparedStatementParameter getParameter(int i) { > return (PreparedStatementParameter) params.get(i); > } > > /** > * Returns the timeStampParameter. > * @return PreparedStatementParameter > */ > public PreparedStatementParameter getTimeStampParameter() { > return timeStampParameter; > } > > /** > * Returns the exceptionParameter. > * @return PreparedStatementParameter > */ > public PreparedStatementParameter getExceptionParameter() { > return exceptionParameter; > } > > /** > * Returns the formattedMessageParameter. > * @return PreparedStatementParameter > */ > public PreparedStatementParameter getFormattedMessageParameter() { > return formattedMessageParameter; > } > > /** > * Returns the levelParameter. > * @return PreparedStatementParameter > */ > public PreparedStatementParameter getLevelParameter() { > return levelParameter; > } > > /** > * Returns the loggerParameter. > * @return PreparedStatementParameter > */ > public PreparedStatementParameter getLoggerParameter() { > return loggerParameter; > } > > /** > * Returns the messageParameter. > * @return PreparedStatementParameter > */ > public PreparedStatementParameter getMessageParameter() { > return messageParameter; > } > > /** > * Returns the ndcParameter. > * @return PreparedStatementParameter > */ > public PreparedStatementParameter getNdcParameter() { > return ndcParameter; > } > > /** > * Returns the stackParameter. > * @return PreparedStatementParameter > */ > public PreparedStatementParameter getStackParameter() { > return stackParameter; > } > > /** > * Sets the timeStampParameter. > * @param timeStampParameter The timeStampParameter to set > */ > public void > setTimeStampParameter(PreparedStatementParameter date) { > this.timeStampParameter = date; > } > > /** > * Sets the exceptionParameter. > * @param exceptionParameter The exceptionParameter to set > */ > public void > setExceptionParameter(PreparedStatementParameter exception) { > this.exceptionParameter = exception; > } > > /** > * Sets the formattedMessageParameter. > * @param formattedMessageParameter The > formattedMessageParameter to set > */ > public void setFormattedMessageParameter( > PreparedStatementParameter formattedMsg) { > this.formattedMessageParameter = formattedMsg; > } > > /** > * Sets the levelParameter. > * @param levelParameter The levelParameter to set > */ > public void setLevelParameter(PreparedStatementParameter level) { > this.levelParameter = level; > } > > /** > * Sets the loggerParameter. > * @param loggerParameter The loggerParameter to set > */ > public void setLoggerParameter(PreparedStatementParameter > logger) { > this.loggerParameter = logger; > } > > /** > * Sets the messageParameter. > * @param messageParameter The messageParameter to set > */ > public void setMessageParameter(PreparedStatementParameter msg) { > this.messageParameter = msg; > } > > /** > * Sets the ndcParameter. > * @param ndcParameter The ndcParameter to set > */ > public void setNdcParameter(PreparedStatementParameter ndc) { > this.ndcParameter = ndc; > } > > /** > * Sets the stackParameter. > * @param stackParameter The stackParameter to set > */ > public void setStackParameter(PreparedStatementParameter stack) { > this.stackParameter = stack; > } > > /** > * Returns the connectionSource. > * @return ConnectionSource > */ > public ConnectionSource getConnectionSource() { > return connectionSource; > } > > /** > * Sets the connectionSource. > * @param connectionSource The connectionSource to set > */ > public void setConnectionSource(ConnectionSource > connectionSource) { > this.connectionSource = connectionSource; > } > > /** > * Returns the preparedStatementSource. > * @return PreparedStatementSource > */ > public PreparedStatementSource getPreparedStatementSource() { > return preparedStatementSource; > } > > /** > * Sets the preparedStatementSource. > * @param preparedStatementSource The > preparedStatementSource to set > */ > public void setPreparedStatementSource( > PreparedStatementSource preparedStatementSource) { > this.preparedStatementSource = preparedStatementSource; > } > } > > > > 1.1 > jakarta-log4j/src/java/org/apache/log4j/jdbc/JNDIConnectionSource.java > > Index: JNDIConnectionSource.java > =================================================================== > /* > * > ============================================================== > ============== > * The Apache Software License, Version 1.1 > * > ============================================================== > ============== > * > * Copyright (C) 1999 The Apache Software Foundation. > All rights reserved. > * > * Redistribution and use in source and binary forms, with > or without modifica- > * tion, are permitted provided that the following > conditions are met: > * > * 1. Redistributions of source code must retain the > above copyright notice, > * this list of conditions and the following disclaimer. > * > * 2. Redistributions in binary form must reproduce the > above copyright notice, > * this list of conditions and the following disclaimer > in the documentation > * and/or other materials provided with the distribution. > * > * 3. The end-user documentation included with the > redistribution, if any, must > * include the following acknowledgment: "This > product includes software > * developed by the Apache Software Foundation > (http://www.apache.org/)." > * Alternately, this acknowledgment may appear in the > software itself, if > * and wherever such third-party acknowledgments normally appear. > * > * 4. The names "log4j" and "Apache Software Foundation" > must not be used to > * endorse or promote products derived from this > software without prior > * written permission. For written permission, please contact > * [EMAIL PROTECTED] > * > * 5. Products derived from this software may not be > called "Apache", nor may > * "Apache" appear in their name, without prior > written permission of the > * Apache Software Foundation. > * > * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR > IMPLIED WARRANTIES, > * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF > MERCHANTABILITY AND > * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN > NO EVENT SHALL THE > * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE > LIABLE FOR ANY DIRECT, > * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > CONSEQUENTIAL DAMAGES (INCLU- > * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE > GOODS OR SERVICES; LOSS > * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) > HOWEVER CAUSED AND ON > * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT > LIABILITY, OR TORT > * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY > WAY OUT OF THE USE OF > * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > * > * This software consists of voluntary contributions made > by many individuals > * on behalf of the Apache Software Foundation. For more > information on the > * Apache Software Foundation, please see <http://www.apache.org/>. > * > */ > > package org.apache.log4j.jdbc; > > import org.apache.log4j.spi.ErrorHandler; > > import java.sql.Connection; > import java.sql.SQLException; > > import javax.naming.Context; > import javax.naming.InitialContext; > import javax.naming.NamingException; > > import javax.rmi.PortableRemoteObject; > > import javax.sql.DataSource; > > > /** > * The <code>JNDIConnectionSource</code> is an implementation of > * [EMAIL PROTECTED] ConnectionSource} that obtains a [EMAIL PROTECTED] > javax.sql.DataSource} from a > * JNDI provider and uses it to obtain a [EMAIL PROTECTED] > java.sql.Connection}. It is > * primarily designed to be used inside of J2EE > application servers or > * application server clients, assuming the application > server supports remote > * access of [EMAIL PROTECTED] javax.sql.DataSource}s. In this way > one can take > * advantage of connection pooling and whatever other > goodies the application > * server provides. > * <p> > * Sample configuration:<br> > * <pre> > * <connectionSource > class="org.apache.log4j.jdbc.JNDIConnectionSource"> > * <param name="jndiLocation" value="jdbc/MySQLDS" /> > * </connectionSource> > * </pre> > * <p> > * Sample configuration (with username and password):<br> > * <pre> > * <connectionSource > class="org.apache.log4j.jdbc.JNDIConnectionSource"> > * <param name="jndiLocation" value="jdbc/MySQLDS" /> > * <param name="username" value="myUser" /> > * <param name="password" value="myPassword" /> > * </connectionSource> > * </pre> > * <p> > * Note that this class will obtain an [EMAIL PROTECTED] > javax.naming.InitialContext} > * using the no-argument constructor. This will usually > work when executing > * within a J2EE environment. When outside the J2EE > environment, make sure > * that you provide a jndi.properties file as described by > your JNDI > * provider's documentation. > * > * @author <a href="mailto:[EMAIL PROTECTED]">Ray DeCampo</a> > */ > public class JNDIConnectionSource implements ConnectionSource { > private String jndiLocation = null; > private DataSource dataSource = null; > private ErrorHandler errorHandler = null; > private String username = null; > private String password = null; > > /** > * @see org.apache.log4j.jdbc.ConnectionSource#getConnection() > */ > public Connection getConnection() throws SQLException { > Connection conn = null; > > try { > ensureDataSource(); > > if (username == null) { > conn = dataSource.getConnection(); > } else { > conn = dataSource.getConnection(username, password); > } > } catch (final NamingException ne) { > if (errorHandler != null) { > errorHandler.error(ne.getMessage(), ne, 0); > } > > throw new SQLException( > "NamingException while looking up " + "DataSource: > " + ne.getMessage()); > } catch (final ClassCastException cce) { > if (errorHandler != null) { > errorHandler.error(cce.getMessage(), cce, 0); > } > > throw new SQLException( > "ClassCastException while looking up " + "DataSource: " > + cce.getMessage()); > } > > return conn; > } > > /** > * @see org.apache.log4j.spi.OptionHandler#activateOptions() > */ > public void activateOptions() { > } > > /** > * Returns the jndiLocation. > * @return String > */ > public String getJndiLocation() { > return jndiLocation; > } > > /** > * Sets the jndiLocation. > * @param jndiLocation The jndiLocation to set > */ > public void setJndiLocation(String jndiLocation) { > this.jndiLocation = jndiLocation; > } > > /** > * Sets the error handler. > * @param errorHandler the error handler to set > */ > public void setErrorHandler(ErrorHandler errorHandler) { > this.errorHandler = errorHandler; > } > > /** > * Returns the password. > * @return String > */ > public String getPassword() { > return password; > } > > /** > * Returns the username. > * @return String > */ > public String getUsername() { > return username; > } > > /** > * Sets the password. > * @param password The password to set > */ > public void setPassword(String password) { > this.password = password; > } > > /** > * Sets the username. > * @param username The username to set > */ > public void setUsername(String username) { > this.username = username; > } > > private void ensureDataSource() throws NamingException, > SQLException { > if (dataSource == null) { > Context ctx = new InitialContext(); > Object obj = ctx.lookup(jndiLocation); > dataSource = > (DataSource) PortableRemoteObject.narrow(obj, > DataSource.class); > } > > if (dataSource == null) { > throw new SQLException( > "Failed to obtain data source from JNDI " + > "location " + jndiLocation); > } > } > } > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: [EMAIL PROTECTED] > For additional commands, e-mail: [EMAIL PROTECTED] > --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]