blob: c77cd7e121274814f855aff93d9d94a8ba7089c0 [file] [log] [blame]
///*
// * 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.db;
//
//import org.apache.log4j.AppenderSkeleton;
//import org.apache.log4j.db.dialect.SQLDialect;
//import org.apache.log4j.db.dialect.Util;
//import org.apache.log4j.helpers.LogLog;
//import org.apache.log4j.spi.LocationInfo;
//import org.apache.log4j.spi.LoggingEvent;
//import org.apache.log4j.xml.DOMConfigurator;
//import org.apache.log4j.xml.UnrecognizedElementHandler;
//import org.w3c.dom.Element;
//
//import java.sql.Connection;
//import java.sql.PreparedStatement;
//import java.sql.ResultSet;
//import java.sql.Statement;
//import java.util.Properties;
//import java.util.Set;
//
//
///**
// * The DBAppender inserts loggin events into three database tables in a format
// * independent of the Java programming language. The three tables that
// * DBAppender inserts to must exists before DBAppender can be used. These tables
// * may be created with the help of SQL scripts found in the
// * <em>src/java/org/apache/log4j/db/dialect</em> directory. There is a
// * specific script for each of the most popular database systems. If the script
// * for your particular type of database system is missing, it should be quite
// * easy to write one, taking example on the already existing scripts. If you
// * send them to us, we will gladly include missing scripts in future releases.
// * <p>
// * <p>
// * If the JDBC driver you are using supports the
// * {@link java.sql.Statement#getGeneratedKeys}method introduced in JDBC 3.0
// * specification, then you are all set. Otherwise, there must be an
// * {@link SQLDialect}appropriate for your database system. Currently, we have
// * dialects for PostgreSQL, MySQL, Oracle and MsSQL. As mentioed previously, an
// * SQLDialect is required only if the JDBC driver for your database system does
// * not support the {@link java.sql.Statement#getGeneratedKeys getGeneratedKeys}
// * method.
// * </p>
// * <p>
// * <table border="1" cellpadding="4">
// * <caption>supported dialects</caption>
// * <tr>
// * <th>RDBMS</th>
// * <th>supports <br><code>getGeneratedKeys()</code> method</th>
// * <th>specific <br>SQLDialect support</th>
// * <tr>
// * <tr>
// * <td>PostgreSQL</td>
// * <td align="center">NO</td>
// * <td>present and used</td>
// * <tr>
// * <tr>
// * <td>MySQL</td>
// * <td align="center">YES</td>
// * <td>present, but not actually needed or used</td>
// * <tr>
// * <tr>
// * <td>Oracle</td>
// * <td align="center">YES</td>
// * <td>present, but not actually needed or used</td>
// * <tr>
// * <tr>
// * <td>DB2</td>
// * <td align="center">YES</td>
// * <td>not present, and not needed or used</td>
// * <tr>
// * <tr>
// * <td>MsSQL</td>
// * <td align="center">YES</td>
// * <td>not present, and not needed or used</td>
// * <tr>
// * <tr>
// * <td>HSQL</td>
// * <td align="center">NO</td>
// * <td>present and used</td>
// * <tr>
// * <p>
// * </table>
// * <p>
// * <b>Performance: </b> Experiments show that writing a single event into the
// * database takes approximately 50 milliseconds, on a "standard" PC. If pooled
// * connections are used, this figure drops to under 10 milliseconds. Note that
// * most JDBC drivers already ship with connection pooling support.
// * </p>
// * <p>
// * <p>
// * <p>
// * <p>
// * <b>Configuration </b> DBAppender can be configured programmatically, or using
// * {@link org.apache.log4j.xml.DOMConfigurator JoranConfigurator}. Example
// * scripts can be found in the <em>tests/input/db</em> directory.
// *
// * @author Ceki G&uuml;lc&uuml;
// * @author Ray DeCampo
// */
//public class DBAppender extends AppenderSkeleton implements UnrecognizedElementHandler {
// static final String insertPropertiesSQL =
// "INSERT INTO logging_event_property (event_id, mapped_key, mapped_value) VALUES (?, ?, ?)";
// static final String insertExceptionSQL =
// "INSERT INTO logging_event_exception (event_id, i, trace_line) VALUES (?, ?, ?)";
// static final String insertSQL;
//
//
// static {
// String sql = "INSERT INTO logging_event (" +
// "sequence_number, " +
// "timestamp, " +
// "rendered_message, " +
// "logger_name, " +
// "level_string, " +
// "ndc, " +
// "thread_name, " +
// "reference_flag, " +
// "caller_filename, " +
// "caller_class, " +
// "caller_method, " +
// "caller_line) " +
// " VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?, ?, ?)";
// insertSQL = sql;
// }
//
// ConnectionSource connectionSource;
// boolean cnxSupportsGetGeneratedKeys = false;
// boolean cnxSupportsBatchUpdates = false;
// SQLDialect sqlDialect;
// boolean locationInfo = false;
//
//
// public DBAppender() {
// super(false);
// }
//
// public void activateOptions() {
// LogLog.debug("DBAppender.activateOptions called");
//
// if (connectionSource == null) {
// throw new IllegalStateException(
// "DBAppender cannot function without a connection source");
// }
//
// sqlDialect = Util.getDialectFromCode(connectionSource.getSQLDialectCode());
// cnxSupportsGetGeneratedKeys = connectionSource.supportsGetGeneratedKeys();
// cnxSupportsBatchUpdates = connectionSource.supportsBatchUpdates();
// if (!cnxSupportsGetGeneratedKeys && (sqlDialect == null)) {
// throw new IllegalStateException(
// "DBAppender cannot function if the JDBC driver does not support getGeneratedKeys method *and* without a specific SQL dialect");
// }
//
// // all nice and dandy on the eastern front
// super.activateOptions();
// }
//
// /**
// * @return Returns the connectionSource.
// */
// public ConnectionSource getConnectionSource() {
// return connectionSource;
// }
//
// /**
// * @param connectionSource The connectionSource to set.
// */
// public void setConnectionSource(ConnectionSource connectionSource) {
// LogLog.debug("setConnectionSource called for DBAppender");
// this.connectionSource = connectionSource;
// }
//
// protected void append(LoggingEvent event) {
// Connection connection = null;
// try {
// connection = connectionSource.getConnection();
// connection.setAutoCommit(false);
//
// PreparedStatement insertStatement;
// if (cnxSupportsGetGeneratedKeys) {
// insertStatement = connection.prepareStatement(insertSQL, Statement.RETURN_GENERATED_KEYS);
// } else {
// insertStatement = connection.prepareStatement(insertSQL);
// }
//
// /* insertStatement.setLong(1, event.getSequenceNumber());*/
// insertStatement.setLong(1, 0);
//
// insertStatement.setLong(2, event.getTimeStamp());
// insertStatement.setString(3, event.getRenderedMessage());
// insertStatement.setString(4, event.getLoggerName());
// insertStatement.setString(5, event.getLevel().toString());
// insertStatement.setString(6, event.getNDC());
// insertStatement.setString(7, event.getThreadName());
// insertStatement.setShort(8, DBHelper.computeReferenceMask(event));
//
// LocationInfo li;
//
// if (event.locationInformationExists() || locationInfo) {
// li = event.getLocationInformation();
// } else {
// li = LocationInfo.NA_LOCATION_INFO;
// }
//
// insertStatement.setString(9, li.getFileName());
// insertStatement.setString(10, li.getClassName());
// insertStatement.setString(11, li.getMethodName());
// insertStatement.setString(12, li.getLineNumber());
//
// int updateCount = insertStatement.executeUpdate();
// if (updateCount != 1) {
// LogLog.warn("Failed to insert loggingEvent");
// }
//
// ResultSet rs = null;
// Statement idStatement = null;
// boolean gotGeneratedKeys = false;
// if (cnxSupportsGetGeneratedKeys) {
// rs = insertStatement.getGeneratedKeys();
// gotGeneratedKeys = true;
// }
//
// if (!gotGeneratedKeys) {
// insertStatement.close();
// insertStatement = null;
//
// idStatement = connection.createStatement();
// idStatement.setMaxRows(1);
// rs = idStatement.executeQuery(sqlDialect.getSelectInsertId());
// }
//
// // A ResultSet cursor is initially positioned before the first row; the
// // first call to the method next makes the first row the current row
// rs.next();
// int eventId = rs.getInt(1);
//
// rs.close();
//
// // we no longer need the insertStatement
// if (insertStatement != null) {
// insertStatement.close();
// }
//
// if (idStatement != null) {
// idStatement.close();
// }
//
// Set propertiesKeys = event.getPropertyKeySet();
//
// if (propertiesKeys.size() > 0) {
// PreparedStatement insertPropertiesStatement =
// connection.prepareStatement(insertPropertiesSQL);
//
// for (Object propertiesKey : propertiesKeys) {
// String key = (String) propertiesKey;
// String value = event.getProperty(key);
//
// //LogLog.info("id " + eventId + ", key " + key + ", value " + value);
// insertPropertiesStatement.setInt(1, eventId);
// insertPropertiesStatement.setString(2, key);
// insertPropertiesStatement.setString(3, value);
//
// if (cnxSupportsBatchUpdates) {
// insertPropertiesStatement.addBatch();
// } else {
// insertPropertiesStatement.execute();
// }
// }
//
// if (cnxSupportsBatchUpdates) {
// insertPropertiesStatement.executeBatch();
// }
//
// insertPropertiesStatement.close();
// }
//
// String[] strRep = event.getThrowableStrRep();
//
// if (strRep != null) {
// LogLog.debug("Logging an exception");
//
// PreparedStatement insertExceptionStatement =
// connection.prepareStatement(insertExceptionSQL);
//
// for (short i = 0; i < strRep.length; i++) {
// insertExceptionStatement.setInt(1, eventId);
// insertExceptionStatement.setShort(2, i);
// insertExceptionStatement.setString(3, strRep[i]);
// if (cnxSupportsBatchUpdates) {
// insertExceptionStatement.addBatch();
// } else {
// insertExceptionStatement.execute();
// }
// }
// if (cnxSupportsBatchUpdates) {
// insertExceptionStatement.executeBatch();
// }
// insertExceptionStatement.close();
// }
//
// connection.commit();
// } catch (Throwable sqle) {
// LogLog.error("problem appending event", sqle);
// } finally {
// DBHelper.closeConnection(connection);
// }
// }
//
// public void close() {
// closed = true;
// }
//
// /**
// * Returns value of the <b>LocationInfo </b> property which determines whether
// * caller's location info is written to the database.
// */
// public boolean getLocationInfo() {
// return locationInfo;
// }
//
// /**
// * If true, the information written to the database will include caller's
// * location information. Due to performance concerns, by default no location
// * information is written to the database.
// */
// public void setLocationInfo(boolean locationInfo) {
// this.locationInfo = locationInfo;
// }
//
// /**
// * Gets whether appender requires a layout.
// *
// * @return false
// */
// public boolean requiresLayout() {
// return false;
// }
//
// /**
// * {@inheritDoc}
// */
// public boolean parseUnrecognizedElement(Element element, Properties props) throws Exception {
// if ("connectionSource".equals(element.getNodeName())) {
// Object instance =
// DOMConfigurator.parseElement(element, props, ConnectionSource.class);
// if (instance instanceof ConnectionSource) {
// ConnectionSource source = (ConnectionSource) instance;
// source.activateOptions();
// setConnectionSource(source);
// }
// return true;
// }
// return false;
// }
//}