
Author: seb Date: Tue Sep 26 16:23:33 2006 New Revision: 604 Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTestBase.java Modified: logback/trunk/logback-classic/pom.xml logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java logback/trunk/pom.xml Log: - added a dependency on HSQLDB, since we use this for DBAppender tests. - corrected hsqldb.sql and mysql.sql - added a testcase that creates an HSQLDB server, with a test database and uses it to test DBAppender. - modified some javadoc Modified: logback/trunk/logback-classic/pom.xml ============================================================================== --- logback/trunk/logback-classic/pom.xml (original) +++ logback/trunk/logback-classic/pom.xml Tue Sep 26 16:23:33 2006 @@ -46,7 +46,13 @@ <artifactId>dom4j</artifactId> <scope>test</scope> </dependency> - + + <dependency> + <groupId>hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <scope>test</scope> + </dependency> + <dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSource.java Tue Sep 26 16:23:33 2006 @@ -23,7 +23,7 @@ /** * The <id>ConnectionSource</id> interface provides a pluggable means of - * transparently obtaining JDBC {@link java.sql.Connection}s for log4j classes + * transparently obtaining JDBC {@link java.sql.Connection}s for logback classes * that require the use of a {@link java.sql.Connection}. * * @author <a href="mailto:rdecampo@twcny.rr.com">Ray DeCampo</a> Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/ConnectionSourceBase.java Tue Sep 26 16:23:33 2006 @@ -48,7 +48,7 @@ try { Connection connection = getConnection(); if (connection == null) { - addWarn("Could not get a conneciton"); + addWarn("Could not get a connection"); return; } DatabaseMetaData meta = connection.getMetaData(); Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DBAppender.java Tue Sep 26 16:23:33 2006 @@ -147,7 +147,6 @@ boolean cnxSupportsGetGeneratedKeys = false; boolean cnxSupportsBatchUpdates = false; SQLDialect sqlDialect; - boolean locationInfo = false; public DBAppender() { } Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DataSourceConnectionSource.java Tue Sep 26 16:23:33 2006 @@ -53,7 +53,7 @@ } /** - * @see org.apache.log4j.db.ConnectionSource#getConnection() + * @see ch.qos.logback.classic.db.ConnectionSource#getConnection() */ public Connection getConnection() throws SQLException { if (dataSource == null) { Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/DriverManagerConnectionSource.java Tue Sep 26 16:23:33 2006 @@ -71,7 +71,7 @@ Class.forName(driverClass); discoverConnnectionProperties(); } else { - addError("WARNING: No JDBC driver specified for log4j DriverManagerConnectionSource."); + addError("WARNING: No JDBC driver specified for logback DriverManagerConnectionSource."); } } catch (final ClassNotFoundException cnfe) { addError("Could not load JDBC driver class: " + driverClass, cnfe); @@ -79,7 +79,7 @@ } /** - * @see org.apache.log4j.db.ConnectionSource#getConnection() + * @see ch.qos.logback.classic.db.ConnectionSource#getConnection() */ public Connection getConnection() throws SQLException { if (getUser() == null) { Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/HSQLDBDialect.java Tue Sep 26 16:23:33 2006 @@ -12,7 +12,7 @@ /** * The HSQLDB dialect. * - * @author <a href="http://www.qos.ch/log4j/">Ceki Gülcü</a> + * @author Ceki Gülcü */ public class HSQLDBDialect implements SQLDialect { public static final String SELECT_CURRVAL = "CALL IDENTITY()"; Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/hsqldb.sql Tue Sep 26 16:23:33 2006 @@ -1,5 +1,5 @@ // This SQL script creates the required tables by -// org.apache.log4j.db.DBAppender and org.apache.log4j.db.DBReceiver. +// ch.qos.logback.classic.db.DBAppender. // // It is intended for HSQLDB. // @@ -11,17 +11,15 @@ CREATE TABLE logging_event ( - sequence_number BIGINT NOT NULL, - timestamp BIGINT NOT NULL, - rendered_message LONGVARCHAR NOT NULL, - logger_name VARCHAR NOT NULL, - level_string VARCHAR NOT NULL, - ndc LONGVARCHAR, - thread_name VARCHAR, + timestmp BIGINT NOT NULL, + formatted_message LONGVARCHAR NOT NULL, + logger_name VARCHAR(256) NOT NULL, + level_string VARCHAR(256) NOT NULL, + thread_name VARCHAR(256), reference_flag SMALLINT, - caller_filename VARCHAR, - caller_class VARCHAR, - caller_method VARCHAR, + caller_filename VARCHAR(256), + caller_class VARCHAR(256), + caller_method VARCHAR(256), caller_line CHAR(4), event_id INT NOT NULL IDENTITY ); @@ -40,7 +38,7 @@ ( event_id INT NOT NULL, i SMALLINT NOT NULL, - trace_line VARCHAR NOT NULL, + trace_line VARCHAR(256) NOT NULL, PRIMARY KEY(event_id, i), FOREIGN KEY (event_id) REFERENCES logging_event(event_id) ); Modified: logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql ============================================================================== --- logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql (original) +++ logback/trunk/logback-classic/src/main/java/ch/qos/logback/classic/db/dialect/mysql.sql Tue Sep 26 16:23:33 2006 @@ -1,7 +1,6 @@ -# This SQL script creates the required tables by org.apache.log4j.db.DBAppender and -# org.apache.log4j.db.DBReceiver. +# This SQL script creates the required tables by ch.qos.logback.classic.db.DBAppender. # -# It is intended for MySQL databases. It has been tested on MySQL 4.1.1 with +# It is intended for MySQL databases. It has been tested on MySQL 5.0.22 with # INNODB tables. @@ -15,12 +14,10 @@ BEGIN; CREATE TABLE logging_event ( - sequence_number BIGINT NOT NULL, - timestamp BIGINT NOT NULL, - rendered_message TEXT NOT NULL, + timestmp BIGINT NOT NULL, + formatted_message TEXT NOT NULL, logger_name VARCHAR(254) NOT NULL, level_string VARCHAR(254) NOT NULL, - ndc TEXT, thread_name VARCHAR(254), reference_flag SMALLINT, caller_filename VARCHAR(254) NOT NULL, Modified: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java ============================================================================== --- logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java (original) +++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTest.java Tue Sep 26 16:23:33 2006 @@ -1,7 +1,146 @@ package ch.qos.logback.classic.db; -import junit.framework.TestCase; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; +import java.util.Map; -public class DBAppenderTest extends TestCase { +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.Logger; +import ch.qos.logback.classic.LoggerContext; +import ch.qos.logback.classic.spi.CallerData; +import ch.qos.logback.classic.spi.LoggingEvent; +public class DBAppenderTest extends DBAppenderTestBase { + + LoggerContext lc; + Logger logger; + DBAppender appender; + DriverManagerConnectionSource connectionSource; + + public DBAppenderTest(String name) { + super(name); + } + + public void setUp() throws SQLException { + super.setUp(); + lc = new LoggerContext(); + lc.setName("default"); + logger = lc.getLogger("root"); + appender = new DBAppender(); + appender.setName("DB"); + appender.setContext(lc); + connectionSource = new DriverManagerConnectionSource(); + connectionSource.setContext(lc); + connectionSource.setDriverClass(DRIVER_CLASS); + connectionSource.setUrl(url); + connectionSource.setUser(user); + connectionSource.setPassword(password); + connectionSource.start(); + appender.setConnectionSource(connectionSource); + appender.start(); + } + + public void tearDown() throws SQLException { + super.tearDown(); + logger = null; + lc = null; + appender = null; + connectionSource = null; + } + + public void testAppendLoggingEvent() throws SQLException { + LoggingEvent event = createLoggingEvent(); + + appender.append(event); + //StatusPrinter.print(lc.getStatusManager()); + + Statement stmt = connectionSource.getConnection().createStatement(); + ResultSet rs = null; + rs = stmt.executeQuery("SELECT * FROM logging_event"); + if (rs.next()) { + assertEquals(event.getTimeStamp(), rs.getLong(1)); + assertEquals(event.getFormattedMessage(), rs.getString(2)); + assertEquals(event.getLoggerRemoteView().getName(), rs.getString(3)); + assertEquals(event.getLevel().toString(), rs.getString(4)); + assertEquals(event.getThreadName(), rs.getString(5)); + assertEquals(DBHelper.computeReferenceMask(event), rs.getShort(6)); + CallerData callerData = event.getCallerData()[0]; + assertEquals(callerData.getFileName(), rs.getString(7)); + assertEquals(callerData.getClassName(), rs.getString(8)); + assertEquals(callerData.getMethodName(), rs.getString(9)); + } else { + fail("No row was inserted in the database"); + } + + rs.close(); + stmt.close(); + } + + public void testAppendThrowable() throws SQLException { + LoggingEvent event = createLoggingEvent(); + + appender.append(event); + //StatusPrinter.print(lc.getStatusManager()); + + Statement stmt = connectionSource.getConnection().createStatement(); + ResultSet rs = null; + rs = stmt.executeQuery("SELECT * FROM logging_event_exception where event_id = 0"); + int i = 0; + while (rs.next()) { + assertEquals(event.getThrowableInformation().getThrowableStrRep()[i], rs.getString(3)); + i++; + } + + rs.close(); + stmt.close(); + } + + public void testContextInfo() throws SQLException { + LoggingEvent event = createLoggingEvent(); + lc.setProperty("testKey1", "testValue1"); + + appender.append(event); + //StatusPrinter.print(lc.getStatusManager()); + + Statement stmt = connectionSource.getConnection().createStatement(); + ResultSet rs = null; + rs = stmt.executeQuery("SELECT * FROM logging_event_property where event_id = 0"); + Map<String, String> map = appender.mergePropertyMaps(event); + while (rs.next()) { + String key = rs.getString(2); + assertEquals(map.get(key), rs.getString(3)); + System.out.println("value: " + map.get(key)); + } + + rs.close(); + stmt.close(); + } + + public void testAppendMultipleEvents() throws SQLException { + for (int i = 0; i < 10; i++) { + LoggingEvent event = createLoggingEvent(); + appender.append(event); + } + //StatusPrinter.print(lc.getStatusManager()); + + Statement stmt = connectionSource.getConnection().createStatement(); + ResultSet rs = null; + rs = stmt.executeQuery("SELECT * FROM logging_event"); + int count = 0; + while (rs.next()) { + count++; + } + assertEquals(10, count); + + rs.close(); + stmt.close(); + } + + + private LoggingEvent createLoggingEvent() { + LoggingEvent le = new LoggingEvent(this.getClass().getName(), logger, + Level.DEBUG, "test message", new Exception("test Ex"), null); + return le; + } } Added: logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTestBase.java ============================================================================== --- (empty file) +++ logback/trunk/logback-classic/src/test/java/ch/qos/logback/classic/db/DBAppenderTestBase.java Tue Sep 26 16:23:33 2006 @@ -0,0 +1,143 @@ +package ch.qos.logback.classic.db; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +import junit.framework.TestCase; + +import org.hsqldb.Server; + +public abstract class DBAppenderTestBase extends TestCase { + + public static final String DRIVER_CLASS = "org.hsqldb.jdbcDriver"; + String serverProps; + String url; + String user = "sa"; + String password = ""; + Server server; + boolean isNetwork = true; + + public DBAppenderTestBase(String name) { + super(name); + } + + public DBAppenderTestBase(String name, String url, boolean isNetwork) { + + super(name); + + this.isNetwork = isNetwork; + this.url = url; + } + + protected void setUp() throws SQLException { + + if (isNetwork) { + if (url == null) { + url = "jdbc:hsqldb:hsql://localhost/test"; + } + + server = new Server(); + + server.setDatabaseName(0, "test"); + server.setDatabasePath(0, "mem:test;sql.enforce_strict_size=true"); + server.setLogWriter(null); + server.setErrWriter(null); + server.start(); + } else { + if (url == null) { + url = "jdbc:hsqldb:file:test;sql.enforce_strict_size=true"; + } + } + + try { + Class.forName(DRIVER_CLASS); + } catch (Exception e) { + e.printStackTrace(); + System.out.println(this + ".setUp() error: " + e.getMessage()); + } + + createTables(); + } + + protected void tearDown() throws SQLException { + dropTables(); + + if (isNetwork) { + server.stop(); + + server = null; + } + } + + Connection newConnection() throws SQLException { + return DriverManager.getConnection(url, user, password); + } + + void createTables() throws SQLException { + Connection conn = newConnection(); + StringBuffer buf = new StringBuffer(); + buf.append("CREATE TABLE logging_event ("); + buf.append("timestmp BIGINT NOT NULL,"); + buf.append("formatted_message LONGVARCHAR NOT NULL,"); + buf.append("logger_name VARCHAR(256) NOT NULL,"); + buf.append("level_string VARCHAR(256) NOT NULL,"); + buf.append("thread_name VARCHAR(256),"); + buf.append("reference_flag SMALLINT,"); + buf.append("caller_filename VARCHAR(256), "); + buf.append("caller_class VARCHAR(256), "); + buf.append("caller_method VARCHAR(256), "); + buf.append("caller_line CHAR(4), "); + buf.append("event_id INT NOT NULL IDENTITY);"); + query(conn, buf.toString()); + + buf = new StringBuffer(); + buf.append("CREATE TABLE logging_event_property ("); + buf.append("event_id INT NOT NULL,"); + buf.append("mapped_key VARCHAR(254) NOT NULL,"); + buf.append("mapped_value LONGVARCHAR,"); + buf.append("PRIMARY KEY(event_id, mapped_key),"); + buf.append("FOREIGN KEY (event_id) REFERENCES logging_event(event_id));"); + query(conn, buf.toString()); + + buf = new StringBuffer(); + buf.append("CREATE TABLE logging_event_exception ("); + buf.append("event_id INT NOT NULL,"); + buf.append("i SMALLINT NOT NULL,"); + buf.append("trace_line VARCHAR(256) NOT NULL,"); + buf.append("PRIMARY KEY(event_id, i),"); + buf.append("FOREIGN KEY (event_id) REFERENCES logging_event(event_id));"); + query(conn, buf.toString()); + } + + void dropTables() throws SQLException { + Connection conn = newConnection(); + StringBuffer buf = new StringBuffer(); + buf.append("DROP TABLE logging_event_exception IF EXISTS;"); + query(conn, buf.toString()); + + buf = new StringBuffer(); + buf.append("DROP TABLE logging_event_property IF EXISTS;"); + query(conn, buf.toString()); + + buf = new StringBuffer(); + buf.append("DROP TABLE logging_event IF EXISTS;"); + query(conn, buf.toString()); + } + + void query(Connection conn, String expression) throws SQLException { + + Statement st = null; + + st = conn.createStatement(); + + int i = st.executeUpdate(expression); + + if (i == -1) { + System.out.println("db error : " + expression); + } + + st.close(); + } +} Modified: logback/trunk/pom.xml ============================================================================== --- logback/trunk/pom.xml (original) +++ logback/trunk/pom.xml Tue Sep 26 16:23:33 2006 @@ -74,6 +74,11 @@ <artifactId>slf4j-api</artifactId> <version>1.1.0-beta0</version> </dependency> + <dependency> + <groupId>hsqldb</groupId> + <artifactId>hsqldb</artifactId> + <version>1.8.0.5</version> + </dependency> <!-- Access Module Dependencies --> <dependency>