12 Commits

Author SHA1 Message Date
arthur_blake 48cb541e58 update 1.6 JDK, increase amount of memory for 1.6 javadoc, and fix outdated javadoc 2008-11-08 22:30:50 +00:00
arthur_blake 201d3b974b update doc in preparation for 1.2 alpha 1 release 2008-11-08 22:01:57 +00:00
arthur_blake 007ff20ed1 initial features and improvements for 1.2 version 2008-09-20 02:52:00 +00:00
arthur_blake 2d8cbd4cdf update copyright message in headers 2008-04-12 02:51:44 +00:00
arthur_blake 21cbf688ec update/add copyright notice in build script and javadoc 2008-04-12 02:42:42 +00:00
arthur_blake 44043261af upgrade to slf4j 1.5.0 2008-04-12 02:38:26 +00:00
arthur_blake 86364a24fa update changes and web site to reflect 1.1 release 2008-04-12 02:37:44 +00:00
arthur_blake 4900e751bb upgrade to slf4j 1.5.0 2008-04-12 02:25:44 +00:00
arthur_blake 9da5241e39 remove beta designation from version number and fix scripts 2008-03-12 21:46:14 +00:00
arthur_blake ddbee4d1b6 add TODO entry about maven2 support 2008-03-12 21:45:31 +00:00
arthur_blake 6bf61ef02b minor bug fix; mark drivers as not found if they fail to load for ANY reason 2008-03-12 21:44:22 +00:00
arthur_blake 18c7e2fd19 minor javadoc generation fix 2007-11-11 01:13:47 +00:00
47 changed files with 1750 additions and 587 deletions
+96 -18
View File
@@ -1,38 +1,116 @@
2008-11-08 1.2 alpha 1 Release
o added a new logger "jdbc.connection" to dump connection open and
close events as well as dumping all open connection numbers. This
is very useful for hunting down connection leak problems.
o several new options to produce better SQL output:
log4jdbc.dump.booleanastruefalse - many RDBMS's don't have a
native boolean type and store booleans as a 1 or 0. Setting this
option to false will show boolean bind variables as 1 or 0.
Setting this to true will show the boolean as true or false.
(Note that the default for this setting is false, contrary to the
previous way log4jdbc worked.)
log4jdbc.dump.sql.maxlinelength - can be used to insert line
breaks into long running SQL (at white space positions.)
previous versions of log4jdbc did this automatically with a value
of 90 (the default value is 90.) This line breaking can be turned
off completely by setting this to 0.
log4jdbc.dump.fulldebugstacktrace - can be used in extreme
debugging circumstances when you want to be able to see the full
stack trace in the debug output. Be extra careful when using
this as it will obviously produce much much more logging output.
o dump a null bind variable as NULL instead of <null> for more
accurate and reuseable SQL output.
o several new options for controlling what types of SQL statements are
logged:
log4jdbc.dump.sql.select default value is true
log4jdbc.dump.sql.insert default value is true
log4jdbc.dump.sql.update default value is true
log4jdbc.dump.sql.delete default value is true
log4jdbc.dump.sql.create default value is true
The default values for all of these are true, but they can be
selectively turned on and off to filter out unwanted types of sql
statements. For example, setting log4jdbc.dump.sql.delete will
cause all DELETE sql commands to not be logged.
o A new option to add a semi colon to the end of the dumped sql:
log4jdbc.dump.sql.addsemicolon default value is false
Sometimes it's useful to use log4jdbc to produce sql scripts that
can later be fed back into a SQL tool to execute against a
database and this option can help to produce more re-useable sql
output script data from a log file.
o added Microsoft SQL Server 2005 Driver
(com.microsoft.sqlserver.jdbc.SQLServerDriver) to
list of "well known" drivers that log4jdbc looks for at startup.
(thanks to Rob Richards for pointing this out)
Note that the SQL Server 2000 Driver with the confusing name
of (com.microsoft.jdbc.sqlserver.SQLServerDriver) is also still
supported.
o other miscellaneous improvements.
2008-04-11 1.1 Release
o upgrade to SLF4J 1.5. Note that log4jdbc should still work with
any older (or newer) version of SLF4J too.
o slightly better fault tolerance for when loading/probing of
popular JDBC drivers fails for any reason.
2007-11-10 1.1 beta 1 Release
o added HSQLDB (org.hsqldb.jdbcDriver) and H2 (org.h2.Driver)
to list of "well known" drivers that log4jdbc looks for at startup.
o added HSQLDB (org.hsqldb.jdbcDriver) and H2 (org.h2.Driver) to
list of "well known" drivers that log4jdbc looks for at startup.
o added log4jdbc.sqltiming.warn.threshold and log4jdbc.sqltiming.error.threshold system property
settings to greatly aid in finding slow running sql. Special thanks to Lilianne E. Blaze for the idea
and initial implementation.
o added log4jdbc.sqltiming.warn.threshold and
log4jdbc.sqltiming.error.threshold system property settings to
greatly aid in finding slow running sql. Special thanks to
Lilianne E. Blaze for the idea and initial implementation.
2007-07-25 1.1 alpha 2 Release
o JDBC 4.0 support!
o fix Null pointer exception bug that could happen with setObject call on PreparedStatementSpy
o fix Null pointer exception bug that could happen with setObject
call on PreparedStatementSpy
o added MySQL (com.mysql.jdbc.Driver) and PostgreSQL (org.postgresql.Driver)
to list of "well known" drivers that log4jdbc looks for at startup.
o added MySQL (com.mysql.jdbc.Driver) and PostgreSQL
(org.postgresql.Driver) to list of "well known" drivers that
log4jdbc looks for at startup.
2007-05-29 1.1 alpha 1 Release
o Fixed problem where when sql timing log was the only log turned on, log4jdbc would not recognize that
logging was on at all.
o Fixed problem where when sql timing log was the only log turned
on, log4jdbc would not recognize that logging was on at all.
o report sql exceptions in the sql timing log as well (when they occured during sql execution) and
prominently show that the sql FAILED, and display how long it tried to chug on the sql
before the exception was thrown
o report sql exceptions in the sql timing log as well (when they
occured during sql execution) and prominently show that the sql
FAILED, and display how long it tried to chug on the sql before
the exception was thrown.
o Switch to Simple Logging Facade for Java SLF4J instead of using log4j directly, so that any underlying
logging system can be easily used.
o Switch to Simple Logging Facade for Java SLF4J instead of using
log4j directly, so that any underlying logging system can be
easily used.
o option added to ant build script to generate javadoc with ydoc to include UML diagrams within the javadoc.
o option added to ant build script to generate javadoc with ydoc
to include UML diagrams within the javadoc.
o dump batched sql correctly.
o add simple command line program (PostLogProfilerProcessor) for processing sqltiming log files to create
a simple profiling report from log data.
o add simple command line program (PostLogProfilerProcessor) for
processing sqltiming log files to create a simple profiling
report from log data.
2007-04-21 Initial 1.0 Release
+1 -1
View File
@@ -1,6 +1,6 @@
log4jdbc is open source software, released under the Apache License, Version 2.0:
Copyright 2007 Arthur Blake
Copyright 2007-2008 Arthur Blake
Licensed under the Apache License, Version 2.0 (the "License");
you may not use log4jdbc except in compliance with the License.
+2
View File
@@ -16,3 +16,5 @@ o ALL String concatenation & dumping methods should take place ONLY if logging
o review dumpedSql method - make auto line breaking option (& num chars used) be options
o need log4jdbc.debug.stack.regex so that the stack matching can take place via regex
o maven2 repository support
+354 -104
View File
File diff suppressed because it is too large Load Diff
+12
View File
@@ -30,6 +30,11 @@ log4j.additivity.jdbc.sqlonly=false
log4j.logger.jdbc.sqltiming=DEBUG,sqltiming
log4j.additivity.jdbc.sqltiming=false
! Log connection open/close events and connection number dump
log4j.logger.jdbc.connection=FATAL,connection
log4j.additivity.jdbc.connection=false
! the appender used for the JDBC API layer call logging above, sql only
log4j.appender.sql=org.apache.log4j.FileAppender
log4j.appender.sql.File=./logs/sql.log
@@ -50,3 +55,10 @@ log4j.appender.jdbc.File=./logs/jdbc.log
log4j.appender.jdbc.Append=false
log4j.appender.jdbc.layout=org.apache.log4j.PatternLayout
log4j.appender.jdbc.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
! the appender used for the JDBC Connection open and close events
log4j.appender.connection=org.apache.log4j.FileAppender
log4j.appender.connection.File=./logs/connection.log
log4j.appender.connection.Append=false
log4j.appender.connection.layout=org.apache.log4j.PatternLayout
log4j.appender.connection.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
+16 -3
View File
@@ -37,15 +37,23 @@
</layout>
</appender>
<appender name="jdbc-connection" class="org.apache.log4j.FileAppender">
<param name="File" value="./logs/connection.log"/>
<param name="Append" value="false"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/>
</layout>
</appender>
<!--
The Following 4 logs can be turned on and off while the server is running
The Following 5 logs can be turned on and off while the server is running
LIVE in order to trace the SQL and/or all JDBC coming out of the application.
To turn a log on, set the level value to INFO or DEBUG (to see class name and
line number information in the log) The DEBUG setting is much more inefficient
but the output is much more useful.
To turn off JDBC logging completely, you must set all 4 logs to a level higher
To turn off JDBC logging completely, you must set all 5 logs to a level higher
than ERROR (FATAL is suggested.)
-->
@@ -75,7 +83,12 @@
<level value="fatal"/>
<appender-ref ref="jdbc-appender"/>
</logger>
<!-- log connection open/close events and dump of all open connection numbers -->
<logger name="jdbc.connection" additivity="false">
<level value="fatal"/>
<appender-ref ref="connection-appender"/>
</logger>
<!-- this log is for internal debugging of log4jdbc, itself -->
<!-- debug logging for log4jdbc itself -->
+6 -2
View File
@@ -26,6 +26,10 @@ code,pre {color:navy;background-color:beige;font-size:11pt;}
pre {border:2px dashed navy;margin-left:3em;margin-right:4em;margin-top:1em;margin-bottom:1em;white-space:pre-line;}
.ad {font-size:0.8em;color:blue}
.copyright {font-size:0.8m;text-align:center}
.copyright a {color:#ef39e9}
.sflogo {float:right; margin-right:30px;}
table.options {margin-left:40px;margin-right:20px;border:1px solid black;border-collapse:collapse;}
table.options thead th {text-align:center;border:1px solid black; padding:5px}
table.options tbody td {text-align:left;border:1px solid black; padding:5px}
Binary file not shown.
Binary file not shown.
+4
View File
@@ -0,0 +1,4 @@
To build log4jdbc, you must have Ant 1.6.5 or later installed,
and JDK 1.4 and JDK 1.6 installed.
The build.cmd file is useful for building both the jdbc 3 version (JDK 1.4) and the jdbc 4 version (under JDK 1.6) under windows.
+1 -1
View File
@@ -11,7 +11,7 @@ call java -version
call ant -Djdbc.level=3 all
set JAVA_HOME=C:\jdk1.6.0_03
set JAVA_HOME=C:\jdk1.6.0_10
set PATH=%JAVA_HOME%\bin;%ANT_HOME%\bin
call java -version
+17 -2
View File
@@ -9,6 +9,20 @@
built with jdk 1.4.2_13 (for use with jdbc3)
and/or jdk 1.6.0 (for use with jdbc4)
Copyright 2007-2008 Arthur Blake
Licensed 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.
-->
<project name="log4jdbc" default="all" basedir="..">
@@ -34,7 +48,7 @@
<!-- release version -->
<property name="version" value="1.1beta1"/>
<property name="version" value="1.2alpha1"/>
<target name="all" depends="cleancompile,compile,cleanjar,jar"/>
@@ -180,6 +194,7 @@
<property name="ps" value="${path.separator}"/>
<javadoc destdir="${apidocs}" packagenames="net.sf.log4jdbc.*"
maxmemory="512m"
Windowtitle="log4${jdbc.prefix} ${version}"
Header="&lt;b&gt;&lt;a href=&quot;http://log4jdbc.sourceforge.net&quot;&gt;log4${jdbc.prefix} ${version}&lt;/a&gt;&lt;/b&gt;"
Use="true" breakiterator="true">
@@ -194,7 +209,7 @@
<!-- note that the jdk source code is referenced here so that javadoc will be generated from
interface class methods when none is specified in the implementation -->
<sourcepath path="/jdk1.6.0/src"/>
<sourcepath path="/jdk1.6.0_10/src"/>
<link href="http://java.sun.com/javase/6/docs/api/"/>
<!--
<link href="http://java.sun.com/j2ee/1.4/docs/api/"/>
+2 -1
View File
@@ -5,6 +5,7 @@ rem run ydoc for jdbc 3 with jdk 1.4 and
rem run ydoc for jdbc 4 with jdk 1.6
set ANT_HOME=c:\apache-ant-1.6.5
set ANT_OPTS=-Xmx512m
set JAVA_HOME=C:\j2sdk1.4.2_13
set PATH=%JAVA_HOME%\bin;%ANT_HOME%\bin
@@ -12,7 +13,7 @@ call java -version
call ant -Djdbc.level=3 ydoc.3
set JAVA_HOME=c:\jdk1.6.0_03
set JAVA_HOME=c:\jdk1.6.0_10
set PATH=%JAVA_HOME%\bin;%ANT_HOME%\bin
call java -version
+2 -2
View File
@@ -2,7 +2,7 @@
rem *************************************************************************************************
rem * *
rem * Copyright 2007 Arthur Blake *
rem * Copyright 2007-2008 Arthur Blake *
rem * *
rem * Licensed under the Apache License, Version 2.0 (the "License"); *
rem * you may not use this file except in compliance with the License. *
@@ -25,4 +25,4 @@ rem * profiling output report.
rem * *
rem *************************************************************************************************
java -Xmx1024m -classpath ..\build\log4jdbc-1.1beta1.jar net.sf.log4jdbc.PostLogProfilerProcessor %*
java -Xmx1024m -classpath ..\build\log4jdbc3-1.2alpha1.jar net.sf.log4jdbc.PostLogProfilerProcessor %*
+2 -2
View File
@@ -2,7 +2,7 @@
# *************************************************************************************************
# * *
# * Copyright 2007 Arthur Blake *
# * Copyright 2007-2008 Arthur Blake *
# * *
# * Licensed under the Apache License, Version 2.0 (the "License"); *
# * you may not use this file except in compliance with the License. *
@@ -25,4 +25,4 @@
# * *
# *************************************************************************************************
java -Xmx1024m -classpath ../build/log4jdbc-1.1beta1.jar net.sf.log4jdbc.PostLogProfilerProcessor $@
java -Xmx1024m -classpath ../build/log4jdbc3-1.2alpha1.jar net.sf.log4jdbc.PostLogProfilerProcessor $@
@@ -1,6 +1,5 @@
/**
*
* Copyright 2007 Arthur Blake
* Copyright 2007-2008 Arthur Blake
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -40,8 +39,6 @@ import java.util.Map;
*/
public class CallableStatementSpy extends PreparedStatementSpy implements CallableStatement
{
private final SpyLogDelegator log;
protected void reportAllReturns(String methodCall, String msg)
{
log.methodReturned(this, methodCall, msg);
@@ -53,7 +50,7 @@ public class CallableStatementSpy extends PreparedStatementSpy implements Callab
private CallableStatement realCallableStatement;
/**
* Create a CallableStatementSpy to spy upon a CallableStatement.
* Create a CallableStatementSpy (JDBC 3 version) to spy upon a CallableStatement.
*
* @param sql The SQL used for this CallableStatement
* @param connectionSpy The ConnectionSpy which produced this CallableStatementSpy
@@ -63,7 +60,6 @@ public class CallableStatementSpy extends PreparedStatementSpy implements Callab
{
super(sql, connectionSpy, realCallableStatement);
this.realCallableStatement = realCallableStatement;
log = SpyLogFactory.getSpyLogDelegator();
}
public String getClassType()
@@ -625,6 +621,7 @@ public class CallableStatementSpy extends PreparedStatementSpy implements Callab
public void setBytes(String parameterName, byte[] x) throws SQLException
{
//todo: dump byte array?
String methodCall = "setBytes(" + parameterName + ", " + x + ")";
try
{
@@ -1041,7 +1038,6 @@ public class CallableStatementSpy extends PreparedStatementSpy implements Callab
reportException(methodCall, s);
throw s;
}
}
public void registerOutParameter(String parameterName, int sqlType, String typeName) throws SQLException
+74 -19
View File
@@ -1,5 +1,5 @@
/**
* Copyright 2007 Arthur Blake
* Copyright 2007-2008 Arthur Blake
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,10 +23,19 @@ import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Savepoint;
import java.sql.Statement;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* Wraps a JDBC Connection and reports method calls, returns and exceptions.
*
* This version is for jdbc 3.
*
* @author Arthur Blake
*/
public class ConnectionSpy implements Connection, Spy
@@ -35,9 +44,51 @@ public class ConnectionSpy implements Connection, Spy
private SpyLogDelegator log;
private int connectionNumber;
private final Integer connectionNumber;
private static int lastConnectionNumber = 0;
private static final Object connectionNumberLock = new Object();
/**
* Contains a Mapping of connectionNumber to currently open ConnectionSpy
* objects.
*/
private static final Map connectionTracker = new HashMap();
/**
* Get a dump of how many connections are open, and which connection numbers
* are open.
*
* @return an open connection dump.
*/
public static String getOpenConnectionsDump()
{
StringBuffer dump = new StringBuffer();
int size;
Integer[] keysArr;
synchronized (connectionTracker)
{
size = connectionTracker.size();
if (size==0)
{
return "open connections: none";
}
Set keys = connectionTracker.keySet();
keysArr = (Integer[]) keys.toArray(new Integer[keys.size()]);
}
Arrays.sort(keysArr);
dump.append("open connections: ");
for (int i=0; i < keysArr.length; i++)
{
dump.append(keysArr[i]);
dump.append(" ");
}
dump.append("(");
dump.append(size);
dump.append(")");
return dump.toString();
}
/**
* Create a new ConnectionSpy that wraps a given Connection.
@@ -46,28 +97,21 @@ public class ConnectionSpy implements Connection, Spy
*/
public ConnectionSpy(Connection realConnection)
{
setRdbmsSpecifics(DriverSpy.defaultRdbmsSpecifics); // just in case it's not initialized
if (realConnection == null)
{
throw new IllegalArgumentException("Must pass in a non null real Connection");
}
this.realConnection = realConnection;
log = SpyLogFactory.getSpyLogDelegator();
synchronized (connectionNumberLock)
{
connectionNumber = ++lastConnectionNumber;
}
this(realConnection, DriverSpy.defaultRdbmsSpecifics);
}
/**
* Create a new ConnectionSpy that wraps a given Connection.
*
* @param realConnection &quot;real&quot; Connection that this ConnectionSpy wraps.
* @param rdbmsSpecifics the RdbmsSpecifics object for formatting logging appropriate for the Rdbms used.
* @param rdbmsSpecifics the RdbmsSpecifics object for formatting logging appropriate for the Rdbms used.
*/
public ConnectionSpy(Connection realConnection, RdbmsSpecifics rdbmsSpecifics)
{
if (rdbmsSpecifics == null)
{
rdbmsSpecifics = DriverSpy.defaultRdbmsSpecifics;
}
setRdbmsSpecifics(rdbmsSpecifics);
if (realConnection == null)
{
@@ -76,10 +120,13 @@ public class ConnectionSpy implements Connection, Spy
this.realConnection = realConnection;
log = SpyLogFactory.getSpyLogDelegator();
synchronized (connectionNumberLock)
synchronized (connectionTracker)
{
connectionNumber = ++lastConnectionNumber;
connectionNumber = new Integer(++lastConnectionNumber);
connectionTracker.put(connectionNumber, this);
}
log.connectionOpened(this);
reportReturn("new Connection");
}
private RdbmsSpecifics rdbmsSpecifics;
@@ -104,7 +151,7 @@ public class ConnectionSpy implements Connection, Spy
return rdbmsSpecifics;
}
public int getConnectionNumber()
public Integer getConnectionNumber()
{
return connectionNumber;
}
@@ -685,6 +732,14 @@ public class ConnectionSpy implements Connection, Spy
reportException(methodCall, s);
throw s;
}
finally
{
synchronized (connectionTracker)
{
connectionTracker.remove(connectionNumber);
}
log.connectionClosed(this);
}
reportReturn(methodCall);
}
}
+203 -61
View File
@@ -1,5 +1,5 @@
/**
* Copyright 2007 Arthur Blake
* Copyright 2007-2008 Arthur Blake
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,11 +31,11 @@ import java.util.TreeSet;
/**
* A JDBC driver which is a facade that delegates to one or more real underlying
* JDBC drivers. The driver will spy on any other JDBC driver that is loaded,
* simply by prepending <code>jdbc:log4</code> to the normal jdbc driver URL
* used by any other JDBC driver. The driver also loads several well known
* drivers at class load time, so that this driver can be "dropped in" to any
* java program that uses these drivers without making any code changes.
* JDBC drivers. The driver will spy on any other JDBC driver that is loaded,
* simply by prepending <code>jdbc:log4</code> to the normal jdbc driver URL
* used by any other JDBC driver. The driver also loads several well known
* drivers at class load time, so that this driver can be "dropped in" to any
* java program that uses these drivers without making any code changes.
* The well known driver classes that are loaded are:
* <p/>
* <p/>
@@ -45,10 +45,13 @@ import java.util.TreeSet;
* <li>com.sybase.jdbc2.jdbc.SybDriver</li>
* <li>net.sourceforge.jtds.jdbc.Driver</li>
* <li>com.microsoft.jdbc.sqlserver.SQLServerDriver</li>
* <li>com.microsoft.sqlserver.jdbc.SQLServerDriver</li>
* <li>weblogic.jdbc.sqlserver.SQLServerDriver</li>
* <li>com.informix.jdbc.IfxDriver</li>
* <li>org.apache.derby.jdbc.ClientDriver</li>
* <li>org.apache.derby.jdbc.EmbeddedDriver</li>
* <li>com.mysql.jdbc.Driver</li>
* <li>org.postgresql.Driver</li>
* <li>org.hsqldb.jdbcDriver</li>
* <li>org.h2.Driver</li>
* </ul>
@@ -56,24 +59,24 @@ import java.util.TreeSet;
* <p/>
* <p/>
* Additional drivers can be set via a system property: <b>log4jdbc.drivers</b>
* This can be either a single driver class name or a list of comma separated
* This can be either a single driver class name or a list of comma separated
* driver class names.
* <p/>
* If any of the above driver classes cannot be loaded, the driver continues on
* If any of the above driver classes cannot be loaded, the driver continues on
* without failing.
* <p/>
* Note that the <code>getMajorVersion</code>, <code>getMinorVersion</code> and
* <code>jdbcCompliant</code> method calls attempt to delegate to the last
* <code>jdbcCompliant</code> method calls attempt to delegate to the last
* underlying driver requested through any other call that accepts a JDBC URL.
* <p/>
* This can cause unexpected behavior in certain circumstances. For example,
* if one of these 3 methods is called before any underlying driver has been
* established, then they will return default values that might not be correct
* This can cause unexpected behavior in certain circumstances. For example,
* if one of these 3 methods is called before any underlying driver has been
* established, then they will return default values that might not be correct
* in all situations. Similarly, if this spy driver is used to spy on more than
* one underlying driver concurrently, the values returned by these 3 method
* one underlying driver concurrently, the values returned by these 3 method
* calls may change depending on what the last underlying driver used was at the
* time. This will not usually be a problem, since the driver is retrieved by
* it's URL from the DriverManager in the first place (thus establishing an
* time. This will not usually be a problem, since the driver is retrieved by
* it's URL from the DriverManager in the first place (thus establishing an
* underlying real driver), and in most applications their is only one database.
*
* @author Arthur Blake
@@ -86,7 +89,7 @@ public class DriverSpy implements Driver
private Driver lastUnderlyingDriverRequested;
/**
* Maps driver class names to RdbmsSpecifics objects for each kind of
* Maps driver class names to RdbmsSpecifics objects for each kind of
* database.
*/
private static Map rdbmsSpecifics;
@@ -94,13 +97,13 @@ public class DriverSpy implements Driver
static final SpyLogDelegator log = SpyLogFactory.getSpyLogDelegator();
/**
* Optional package prefix to use for finding application generating point of
* Optional package prefix to use for finding application generating point of
* SQL.
*/
static String DebugStackPrefix;
/**
* Flag to indicate debug trace info should be from the calling application
* Flag to indicate debug trace info should be from the calling application
* point of view (true if DebugStackPrefix is set.)
*/
static boolean TraceFromApplication;
@@ -110,39 +113,80 @@ public class DriverSpy implements Driver
* SqlTimingWarnThresholdMsec milliseconds to run. See below.
*/
static boolean SqlTimingWarnThresholdEnabled;
/**
* An amount of time in milliseconds for which SQL that executed taking this
* long or more to run shall cause a warning message to be generated on the
* An amount of time in milliseconds for which SQL that executed taking this
* long or more to run shall cause a warning message to be generated on the
* SQL timing logger.
*
*
* This threshold will <i>ONLY</i> be used if SqlTimingWarnThresholdEnabled
* is true.
* is true.
*/
static long SqlTimingWarnThresholdMsec;
/**
* Flag to indicate if an error should be shown if SQL takes more than
* SqlTimingErrorThresholdMsec milliseconds to run. See below.
*/
static boolean SqlTimingErrorThresholdEnabled;
/**
* An amount of time in milliseconds for which SQL that executed taking this
* long or more to run shall cause an error message to be generated on the
* An amount of time in milliseconds for which SQL that executed taking this
* long or more to run shall cause an error message to be generated on the
* SQL timing logger.
*
*
* This threshold will <i>ONLY</i> be used if SqlTimingErrorThresholdEnabled
* is true.
* is true.
*/
static long SqlTimingErrorThresholdMsec;
/**
* Get a Long option from a system property and
* When dumping boolean values, dump them as 'true' or 'false'.
* If this option is not set, they will be dumped as 1 or 0 as many
* databases do not have a boolean type, and this allows for more
* portable sql dumping.
*/
static boolean DumpBooleanAsTrueFalse;
/**
* When dumping SQL, if this is greater than 0, than the SQL will
* be broken up into lines that are no longer than this value.
*/
static int DumpSqlMaxLineLength;
/**
* Options to more finely control which types of SQL statements will
* be dumped, when dumping SQL.
* By default all 5 of the following will be true. If any one is set to
* false, then that particular type of SQL will not be dumped.
*/
static boolean DumpSqlSelect;
static boolean DumpSqlInsert;
static boolean DumpSqlUpdate;
static boolean DumpSqlDelete;
static boolean DumpSqlCreate;
// only true if one ore more of the above 4 flags are false.
static boolean DumpSqlFilteringOn;
/**
* If true, add a semilcolon to the end of each SQL dump.
*/
static boolean DumpSqlAddSemicolon;
/**
* If dumping in debug mode, dump the full stack trace.
* This will result in a VERY voluminous output, but can be very useful
* under some circumstances.
*/
static boolean DumpFullDebugStackTrace;
/**
* Get a Long option from a system property and
* log a debug message about this.
*
*
* @param propName System property key.
*
*
* @return the value of that System property key, converted
* to a Long. Or null if not defined or is invalid.
*/
@@ -163,17 +207,52 @@ public class DriverSpy implements Driver
}
catch (NumberFormatException n)
{
log.debug("x " + propName + " \"" + propValue +
"\" is not a valid long value");
log.debug("x " + propName + " \"" + propValue +
"\" is not a valid number");
}
}
return longPropValue;
}
/**
* Get a String option from a system property and
* Get a Long option from a system property and
* log a debug message about this.
*
*
* @param propName System property key.
*
* @return the value of that System property key, converted
* to a Long. Or null if not defined or is invalid.
*/
private static Long getLongOption(String propName, long defaultValue)
{
String propValue = System.getProperty(propName);
Long longPropValue;
if (propValue == null)
{
log.debug("x " + propName + " is not defined (using default of " + defaultValue +")");
longPropValue = new Long(defaultValue);
}
else
{
try
{
longPropValue = new Long(Long.parseLong(propValue));
log.debug(" " + propName + " = " + longPropValue);
}
catch (NumberFormatException n)
{
log.debug("x " + propName + " \"" + propValue +
"\" is not a valid number (using default of " + defaultValue +")");
longPropValue = new Long(defaultValue);
}
}
return longPropValue;
}
/**
* Get a String option from a system property and
* log a debug message about this.
*
* @param propName System property key.
* @return the value of that System property key.
*/
@@ -191,7 +270,44 @@ public class DriverSpy implements Driver
}
return propValue;
}
/**
* Get a boolean option from a system property and
* log a debug message about this.
*
* @param propName property name to get.
* @param defaultValue default value to use if undefined.
*
* @return boolean value found in property, or defaultValue if no property
* found.
*/
private static boolean getBooleanOption(String propName, boolean defaultValue)
{
String propValue = System.getProperty(propName);
boolean val;
if (propValue == null)
{
log.debug("x " + propName + " is not defined (using default value " +
defaultValue + ")");
return defaultValue;
}
else
{
propValue = propValue.trim().toLowerCase();
if (propValue.length() == 0)
{
val = defaultValue;
}
else
{
val= "true".equals(propValue) ||
"yes".equals(propValue) || "on".equals(propValue);
}
}
log.debug(" " + propName + " = " + val);
return val;
}
static
{
log.debug("... log4jdbc initializing ...");
@@ -213,16 +329,42 @@ public class DriverSpy implements Driver
{
SqlTimingErrorThresholdMsec = thresh.longValue();
}
// The Set of drivers that the log4jdbc driver will preload at instantiation
// time. The driver can spy on any driver type, it's just a little bit
DumpBooleanAsTrueFalse =
getBooleanOption("log4jdbc.dump.booleanastruefalse",false);
DumpSqlMaxLineLength = getLongOption("log4jdbc.dump.sql.maxlinelength", 90L).
intValue();
DumpFullDebugStackTrace =
getBooleanOption("log4jdbc.dump.fulldebugstacktrace",false);
DumpSqlSelect = getBooleanOption("log4jdbc.dump.sql.select",true);
DumpSqlInsert = getBooleanOption("log4jdbc.dump.sql.insert",true);
DumpSqlUpdate = getBooleanOption("log4jdbc.dump.sql.update",true);
DumpSqlDelete = getBooleanOption("log4jdbc.dump.sql.delete",true);
DumpSqlCreate = getBooleanOption("log4jdbc.dump.sql.create",true);
DumpSqlFilteringOn = !(DumpSqlSelect && DumpSqlInsert && DumpSqlUpdate &&
DumpSqlDelete && DumpSqlCreate);
DumpSqlAddSemicolon = getBooleanOption("log4jdbc.dump.sql.addsemicolon",false);
// The Set of drivers that the log4jdbc driver will preload at instantiation
// time. The driver can spy on any driver type, it's just a little bit
// easier to configure log4jdbc if it's one of these types!
Set subDrivers = new TreeSet();
subDrivers.add("oracle.jdbc.driver.OracleDriver");
subDrivers.add("com.sybase.jdbc2.jdbc.SybDriver");
subDrivers.add("net.sourceforge.jtds.jdbc.Driver");
// MS driver for Sql Server 2000
subDrivers.add("com.microsoft.jdbc.sqlserver.SQLServerDriver");
// MS driver for Sql Server 2005
subDrivers.add("com.microsoft.sqlserver.jdbc.SQLServerDriver");
subDrivers.add("weblogic.jdbc.sqlserver.SQLServerDriver");
subDrivers.add("com.informix.jdbc.IfxDriver");
subDrivers.add("org.apache.derby.jdbc.ClientDriver");
@@ -269,7 +411,7 @@ public class DriverSpy implements Driver
Class.forName(driverClass);
log.debug(" FOUND DRIVER " + driverClass);
}
catch (ClassNotFoundException c)
catch (Throwable c)
{
i.remove();
}
@@ -285,10 +427,10 @@ public class DriverSpy implements Driver
/** create lookup Map for specific rdbms formatters */
rdbmsSpecifics = new HashMap();
rdbmsSpecifics.put("oracle.jdbc.driver.OracleDriver",
rdbmsSpecifics.put("oracle.jdbc.driver.OracleDriver",
new OracleRdbmsSpecifics());
rdbmsSpecifics.put("net.sourceforge.jtds.jdbc.Driver", sqlServer);
rdbmsSpecifics.put("com.microsoft.jdbc.sqlserver.SQLServerDriver",
rdbmsSpecifics.put("com.microsoft.jdbc.sqlserver.SQLServerDriver",
sqlServer);
rdbmsSpecifics.put("weblogic.jdbc.sqlserver.SQLServerDriver", sqlServer);
@@ -338,8 +480,8 @@ public class DriverSpy implements Driver
}
/**
* Get the major version of the driver. This call will be delegated to the
* underlying driver that is being spied upon (if there is no underlying
* Get the major version of the driver. This call will be delegated to the
* underlying driver that is being spied upon (if there is no underlying
* driver found, then 1 will be returned.)
*
* @return the major version of the JDBC driver.
@@ -357,8 +499,8 @@ public class DriverSpy implements Driver
}
/**
* Get the minor version of the driver. This call will be delegated to the
* underlying driver that is being spied upon (if there is no underlying
* Get the minor version of the driver. This call will be delegated to the
* underlying driver that is being spied upon (if there is no underlying
* driver found, then 0 will be returned.)
*
* @return the minor version of the JDBC driver.
@@ -376,16 +518,16 @@ public class DriverSpy implements Driver
}
/**
* Report whether the underlying driver is JDBC compliant. If there is no
* underlying driver, false will be returned, because the driver cannot
* Report whether the underlying driver is JDBC compliant. If there is no
* underlying driver, false will be returned, because the driver cannot
* actually do any work without an underlying driver.
*
* @return <code>true</code> if the underlying driver is JDBC Compliant;
* @return <code>true</code> if the underlying driver is JDBC Compliant;
* <code>false</code> otherwise.
*/
public boolean jdbcCompliant()
{
return lastUnderlyingDriverRequested != null &&
return lastUnderlyingDriverRequested != null &&
lastUnderlyingDriverRequested.jdbcCompliant();
}
@@ -394,9 +536,9 @@ public class DriverSpy implements Driver
* an underlying driver that this DriverSpy can spy on.
*
* @param url JDBC URL.
*
*
* @return true if this Driver can handle the URL.
*
*
* @throws SQLException if a database access error occurs
*/
public boolean acceptsURL(String url) throws SQLException
@@ -418,11 +560,11 @@ public class DriverSpy implements Driver
* that accepts the URL.
*
* @param url JDBC connection URL.
*
*
* @return Underlying driver for the given URL. Null is returned if the URL is
* not a <code>jdbc:log4</code> type URL or there is no underlying
* not a <code>jdbc:log4</code> type URL or there is no underlying
* driver that accepts the URL.
*
*
* @throws SQLException if a database access error occurs.
*/
private Driver getUnderlyingDriver(String url) throws SQLException
@@ -458,10 +600,10 @@ public class DriverSpy implements Driver
* @param info a list of arbitrary string tag/value pairs as
* connection arguments. Normally at least a "user" and
* "password" property should be included.
*
*
* @return a <code>Connection</code> object that represents a
* connection to the URL.
*
*
* @throws SQLException if a database access error occurs
*/
public Connection connect(String url, Properties info) throws SQLException
@@ -510,7 +652,7 @@ public class DriverSpy implements Driver
* Gets information about the possible properties for the underlying driver.
*
* @param url the URL of the database to which to connect
*
*
* @param info a proposed list of tag/value pairs that will be sent on
* connect open
* @return an array of <code>DriverPropertyInfo</code> objects describing
@@ -519,7 +661,7 @@ public class DriverSpy implements Driver
*
* @throws SQLException if a database access error occurs
*/
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
public DriverPropertyInfo[] getPropertyInfo(String url, Properties info)
throws SQLException
{
Driver d = getUnderlyingDriver(url);
@@ -1,5 +1,5 @@
/**
* Copyright 2007 Arthur Blake
* Copyright 2007-2008 Arthur Blake
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1,5 +1,5 @@
/**
* Copyright 2007 Arthur Blake
* Copyright 2007-2008 Arthur Blake
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import java.util.Arrays;
* Name of log file is passed in on the command line as the only argument.
*
* Assumptions:
*
*
* 1. Each sql statement in the log is separated by a blank line.
* 2. Each sql statement is terminated with the timing string "{executed in N msec}" where N is the number of
* milliseconds that the sql executed in.
@@ -243,7 +243,7 @@ public class PostLogProfilerProcessor {
* than, equal to, or greater than the specified object.<p>
*
* In this case the comparison is used to sort flagged sql in descending order.
* @param o ProfiledSql Object to compare to this ProfiledSql. Must not be null.
* @param o ProfiledSql Object to compare to this ProfiledSql. Must not be null.
*/
public int compareTo(Object o) {
return ((ProfiledSql)o).execTime.compareTo(execTime);

Some files were not shown because too many files have changed in this diff Show More