<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
    <channel>
        <title>Tutorials :: Analyzing JDBC Logs with LOG4JDBC</title>
        <link>http://www.cubrid.org/?mid=analyzing_jdbc_logs</link>
        <description>Tutorials :: Analyzing JDBC Logs with LOG4JDBC</description>
        <language>en</language>
        <pubDate>Tue, 06 Apr 2010 16:37:00 -0800</pubDate>
        <lastBuildDate>Wed, 28 Sep 2011 04:46:00 -0800</lastBuildDate>
        <generator>XpressEngine 1.4.4.1</generator>
                        										        <item>
            <title>Tutorials :: Analyzing JDBC Logs with LOG4JDBC</title>
            <dc:creator>admin</dc:creator>
            <link>http://www.cubrid.org/analyzing_jdbc_logs</link>
            <guid isPermaLink="true">http://www.cubrid.org/analyzing_jdbc_logs</guid>
                                    <description><![CDATA[<h1>Analyzing JDBC Logs with log4jdbc</h1>
<div class="category"><a href="/tutorials">⇐Tutorials</a><a class="right" href="/store_java_logs_to_databdase_using_log4j">Store Java Logs to Database Using log4j⇒</a></div>

<p>First, let's clarify what exactly this <b>log4jdbc</b> is useful for. Assume you work on a project written in Java which communicates with CUBRID JDBC (or any other JDBC driver), and at some point you encounter some issues with your JDBC connections or SQL statements, which might be running surprisingly slow at the same time. Here <b>log4jdbc</b> would be very handy. Instead of adding tons of lines with <i>System.out.println("Some Debug Message")</i>, which later become difficult to manage, <b>log4jdbc</b> provides very easy to control methods with several level of importance.</p><p>For instance, at some point of a time you wish to see only <b style="font-style: italic; ">error</b> type of messages, at some - simple <i style="font-weight: bold; ">info</i> type. When you debug you want to see <b><i>debug</i></b> type messages. With <b>log4jdbc</b> you can customize exactly what kind of messages you would like to see, and this can be easily configured at run-time as well. There is no need to recompile your project again.</p>

<p>In this tutorial we will show how to analyze CUBRID JDBC logs with <b>log4jdbc</b> in Eclipse environment.</p>

<div class="contents-table">
<h3>Table of Contents</h3>

<ul>
    <li><a class="toTop">Back to Top</a></li>
    <li><a href="#downloads">Downloads</a></li>
    <li><a href="#set-up-eclipse-env">Set up Eclipse Environment</a></li>
        <ul>
            <li><a href="#create-eclipse-project">Create Eclipse Project</a></li>
            <li><a href="#add-jar-libraries">Add JAR Libraries</a></li>
            <li><a href="#add-log4j-classpath">Add log4j.xml Configuration File to Classpath</a></li>
            <li><a href="#add-system-properties">Add System Properties</a></li>
        </ul>
    <li><a href="#log4jdbc-configuration">log4jdbc Configuration</a></li>
    <li><a href="#log4jdbc-example">log4jdbc Example</a></li>
        <ul>
            <li><a href="#sample-output">Sample Output</a></li>
        </ul>
    <li><a href="#see-also">See also</a></li>
    <li><a href="#getting-help">Getting Help</a></li>
</ul>
</div>

<h2 id="downloads">Downloads</h2>

<ul>
<li><b>CUBRID 1.1 or higher<br /></b><a href="/downloads" target="_self">Download</a> the latest version of CUBRID Database, and follow the <a href="/tutorials#getting-started" target="_self">installation instructions</a>.</li><li><b>Eclipse<br /></b>This is the environment we will use to develop our Java application.  You can download it from <a href="http://www.eclipse.org/downloads/" target="_blank">www.eclipse.org/downloads</a>.</li><li><b>log4jdbc<br /></b><a href="http://code.google.com/p/log4jdbc/" target="_blank">log4jdbc</a> is a Java JDBC driver that can log SQL and/or JDBC calls (and optionally SQL timing information) for different JDBC drivers using the <a href="/modules/editor/styles/default/editor.html#slf4j" target="_self">SLF4J</a> logging system, which provides APIs for interworking of logging service with log4jdbc. This is the main JAR library we need to analyse the CUBRID JDBC Driver. <p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; ">Download the latest version of <b>log4jdbc</b> compatible with JDK 1.5 or higher from <a href="http://code.google.com/p/log4jdbc/downloads/list">http://code.google.com/p/log4jdbc/downloads/list</a>. CUBRID JDBC supports JDK 1.5 and higher.</p></li><li><b>SLF4J<br /><span class="Apple-style-span" style="font-weight: normal; ">log4jdbc uses the <a href="http://www.slf4j.org/" target="_blank">SLF4J</a> (Simple Logging Facade for Java), a very simple and flexible small library which enables logging at runtime without modifying the application binary. Moreover users are free to pick any java logging systems such as <b><i>Log4j</i></b>, <b><i>java.util</i></b> logging in JDK 1.4, <b><i>logback</i></b>, <b><i>Jakarta Commons Logging</i></b>. In this tutorial we will be using <b>Log4j</b> as our logging system. </span><span class="Apple-style-span" style="font-weight: normal; "><b><span class="Apple-style-span" style="font-weight: normal; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; display: inline !important; ">SLF4J is distributed in zip archive which has many <i>jar</i> files in it. You will need only two of them:</p></span></b><ol><li><b>slf4j-api-1.5.0.jar</b> or any other latest available version. <i>This library will provide APIs for interworking of logging service with log4jdbc</i>.</li><li><b>slf4j-log4j12-1.5.2.jar</b> or any latest version. <i>This library will provide the implementation libraries for interworking of Log4j-based logging service with log4jdbc</i>.</li></ol></span></b>Download the latest version of <b>slf4j</b> from <a href="http://www.slf4j.org/download.html" target="_blank">http://www.slf4j.org/download.html</a>.</li><li><b>log4j</b><br /><a href="http://logging.apache.org/log4j/1.2/index.html" target="_blank">log4j</a> is a Java logging system which we will use throughout our project.<br />Download log4j from <a href="http://logging.apache.org/log4j/1.2/download.html">http://logging.apache.org/log4j/1.2/download.html</a>.<br />You will also need to download the sample log4j.xml configuration file so that you do not have to type all properties manually.<br />Download the sample log4j.xml file from <a href="http://code.google.com/p/log4jdbc/source/browse/trunk/doc/log4j.xml" target="_blank">http://code.google.com/p/log4jdbc/source/browse/trunk/doc/log4j.xml</a>.</li>
</ul>

<h2 id="set-up-eclipse-env">Set up Eclipse Environment</h2>

<h3 id="create-eclipse-project">Create Eclipse Project</h3>

<p>If you have not created an Eclipse project, we need to have one set up. The Eclipse program does not require installation. Once you have downloaded the zip file, extract it and start the program.</p><p>When the program is launched, create a new Java project: <b>File &gt; New &gt; Java Project </b>as shown in the image below.</p>
<p><img src="http://www.cubrid.org/files/attach/images/49/190/new-java-project.png" alt="New Java Project" width="549" height="150" editor_component="image_link"/></p>
<p>Give the project a name (ex.: CubridDB) and click the <b>Finish</b> button.</p>
<p><img editor_component="image_link" src="/files/attach/images/49/190/cubriddb-java-project.png" alt="New CubridDB Java Project" width="533" height="626"/></p>
<p>In the <i>Package Explorer </i>panel on the left, <b>right click</b> on the <i>src</i> directory, and create new Java class.</p>
<p><img editor_component="image_link" src="/files/attach/images/49/190/new-java-class.png" alt="New Java Class" width="620" height="309"/></p>
<p>Give the class the same name you gave to your project. Under <i>Which method stubs would you like to create?</i> select <b>public static void main (String[] args)</b>.</p>
<p><img editor_component="image_link" src="/files/attach/images/49/190/cubriddb-java-class.png" alt="New CubridDB Java Class" width="542" height="637"/></p>
<p> This should create an empty Java class for you with one static method.</p>
<p><img editor_component="image_link" src="/files/attach/images/49/190/ready-eclipse-project.png" alt="Ready Eclipse Project" width="707" height="612"/></p>

<h3 id="add-jar-libraries">Add JAR Libraries</h3>

<p>At this point you should have four JAR files: <b>log4jdbc4-1.1.jar</b>, <b>slf4j-api-1.6.1.jar</b>, <b>slf4j-log4j12-1.6.1.jar</b>, and <b>apache-log4j-1.2.16.zip</b>. We will need one more JAR file which is the CUBRID JDBC driver itself. It is usually located in <b>c:CUBRIDjdbccubrid_jdbc.jar</b> on Windows platform or in <b>/opt/cubrid/jdbc</b> on Linux.</p>

<p>We need to place all five JAR libraries to the project's <b>Java Build Path</b>. <b>Right click</b> on the project name in the <i>Package Explorer </i>panel on the left and choose the <b>Properties</b>.</p><p>Select the <b>Java Build Path</b> from the pop-up window and navigate to the <b>Libraries</b> tab.</p><p>Press the <b>Add External JARs...</b> button to add the five jars we need and click <b>OK</b>.</p>
<p><img editor_component="image_link" src="/files/attach/images/49/190/add-jar-libraries.png" alt="Add JAR Libraries" width="715" height="577"/></p>
<p>To validate all the steps we made up to now, run the project by pressing the keyboard combination <b>Ctrl+F11</b>. At this point the Console windows should be empty.</p>

<h3 id="add-log4j-classpath">Add log4j.xml Configuration File to Classpath</h3>

<p>The last step in our preparation is to set the log4j.xml configuration file to the project <i>classpath</i>. Copy this configuration file to the project root directory. In our case this is <b>CubridDB</b> directory. Before we continue, make sure you have built your project.</p><p>As in the previous step, <b>right click</b> on the project name in the <i>Package Explorer </i>panel on the left and choose the <b>Properties</b>.</p><p>Select the <b>Run/Debug Settings</b> from the pop-up window and double click on the project name. If you do not see your project name, it means you have not built it. Compile your project in that case.</p>
<p><img editor_component="image_link" src="/files/attach/images/49/190/run-debug-settings.png" alt="Run/Debug Settings" width="695" height="560"/></p>
<p>In the pop-up window navigate to the <b>Classpath</b> tab.</p><p>Select your project name and click on <b>Advanced...</b> button.</p>
<p><img editor_component="image_link" src="/files/attach/images/49/190/advanced-options.png" alt="Advanced Options" width="228" height="280"/></p>
<p>In the pop-up window choose the <b>Add Folder</b> option.</p>
<p><img editor_component="image_link" src="/files/attach/images/49/190/add-folder.png" alt="Folder Selection" width="277" height="244"/></p>
<p>In the Folder Selection window choose your project name and click <b>OK</b>.</p>
<p>Then again click OK to save the changes in your Classpath. And one more time press OK button.</p>

<h3 id="add-system-properties">Add System Properties</h3>

<p>log4jdbc can analyze the JDBC drivers for all popular database systems. In our case we want to analyze the CUBRID JDBC Driver, so we need to set the following system properties to the project.</p>

<div class="code">
<div editor_component="code_highlighter" code_type="plain" first_line="1" collapse="false" nogutter="false" nocontrols="false">
-Dlog4jdbc.drivers=cubrid.JDBC.driver.CUBRIDDriver
</div>
</div>

<p>This property will be used in run-time by the log4jdbc.</p>
<p>As in the previous step, <b>right click</b> on the project name in the <i>Package Explorer </i>panel on the left and choose the <b>Properties</b>.</p>
<p>Select the <b>Run/Debug Settings</b> from the pop-up window and double click on the project name.</p>
<p>In the pop-up window navigate to the <b>Arguments</b> tab.</p>
<p>Copy the above setting to the <b>VM arguments:</b> field and press OK twice.</p>
<p><img editor_component="image_link" src="/files/attach/images/49/190/add-system-properties.png" alt="Add System Properties" width="571" height="613"/></p>

<h2 id="log4jdbc-configuration">log4jdbc Configuration</h2>

<p>First, let's look at the sample log4j.xml configuration file. If you do not have it, see the <a href="#downloads" target="_self">Downloads</a> section.</p>

<div class="code">
<div editor_component="code_highlighter" code_type="xml" first_line="1" collapse="false" nogutter="false" nocontrols="false">

&lt;?xml version="1.0" encoding="UTF-8" ?&gt;
&lt;!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"&gt;
 
&lt;!-- An example log4j configuration xml file for log4jdbc --&gt;
&lt;!-- Logging levels are:                                  --&gt;
&lt;!-- DEBUG &lt; INFO &lt; WARN &lt; ERROR &lt; FATAL                  --&gt;
 
&lt;log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"&gt;
 
  &lt;appender name="stdout-appender" class="org.apache.log4j.ConsoleAppender"&gt;
    &lt;layout class="org.apache.log4j.PatternLayout"&gt;
      &lt;param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %5p %c{1}: %m%n"/&gt;
    &lt;/layout&gt;
  &lt;/appender&gt;
 
  &lt;appender name="sql-appender" class="org.apache.log4j.FileAppender"&gt;
    &lt;param name="File" value="./logs/sql.log"/&gt;
    &lt;param name="Append" value="false"/&gt;
    &lt;layout class="org.apache.log4j.PatternLayout"&gt;
      &lt;param name="ConversionPattern" value="-----&gt; %d{yyyy-MM-dd HH:mm:ss.SSS} &lt;%t&gt; %m%n%n"/&gt;
    &lt;/layout&gt;
  &lt;/appender&gt;
 
  &lt;appender name="sql-timing-appender" class="org.apache.log4j.FileAppender"&gt;
    &lt;param name="File" value="./logs/sqltiming.log"/&gt;
    &lt;param name="Append" value="false"/&gt;
    &lt;layout class="org.apache.log4j.PatternLayout"&gt;
      &lt;param name="ConversionPattern" value="-----&gt; %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n%n"/&gt;
    &lt;/layout&gt;
  &lt;/appender&gt;
 
  &lt;appender name="jdbc-appender" class="org.apache.log4j.FileAppender"&gt;
    &lt;param name="File" value="./logs/jdbc.log"/&gt;
    &lt;param name="Append" value="false"/&gt;
    &lt;layout class="org.apache.log4j.PatternLayout"&gt;
      &lt;param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/&gt;
    &lt;/layout&gt;
  &lt;/appender&gt;
 
  &lt;appender name="jdbc-connection" class="org.apache.log4j.FileAppender"&gt;
    &lt;param name="File" value="./logs/connection.log"/&gt;
    &lt;param name="Append" value="false"/&gt;
    &lt;layout class="org.apache.log4j.PatternLayout"&gt;
      &lt;param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %m%n"/&gt;
    &lt;/layout&gt;
  &lt;/appender&gt;
 
  &lt;!--
       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 5 logs to a level higher 
       than ERROR (FATAL is suggested.)
  --&gt;
 
  &lt;!-- log SQL (pre-execution) plus exceptions caused by SQL --&gt;
  &lt;logger name="jdbc.sqlonly" additivity="false"&gt;
    &lt;level value="debug"/&gt;
    &lt;appender-ref ref="sql-appender"/&gt;
  &lt;/logger&gt;
 
  &lt;!-- log SQL with timing information, post execution --&gt;
  &lt;logger name="jdbc.sqltiming" additivity="false"&gt;
    &lt;level value="fatal"/&gt;
    &lt;appender-ref ref="sql-timing-appender"/&gt;
  &lt;/logger&gt;
 
  &lt;!-- only use the two logs below to trace ALL JDBC information,
       NOTE:  This can be very voluminous!  --&gt;
 
  &lt;!-- log all jdbc calls except ResultSet calls --&gt;
  &lt;logger name="jdbc.audit" additivity="false"&gt;
    &lt;level value="fatal"/&gt;
    &lt;appender-ref ref="jdbc-appender"/&gt;
  &lt;/logger&gt;
 
  &lt;!-- log the jdbc ResultSet calls --&gt;
  &lt;logger name="jdbc.resultset" additivity="false"&gt;
    &lt;level value="fatal"/&gt;
    &lt;appender-ref ref="jdbc-appender"/&gt;
  &lt;/logger&gt;
  
  &lt;!-- log connection open/close events and dump of all open connection numbers --&gt;
  &lt;logger name="jdbc.connection" additivity="false"&gt;
    &lt;level value="fatal"/&gt;
    &lt;appender-ref ref="connection-appender"/&gt;
  &lt;/logger&gt;
 
  &lt;!-- this log is for internal debugging of log4jdbc, itself --&gt;
  &lt;!-- debug logging for log4jdbc itself --&gt;
  &lt;logger name="log4jdbc.debug" additivity="false"&gt;
    &lt;level value="debug"/&gt;
    &lt;appender-ref ref="stdout-appender"/&gt;
  &lt;/logger&gt;
 
  &lt;!-- by default, log everything to the console with a level of WARN or higher --&gt;
  &lt;root&gt;
    &lt;level value="warn"/&gt;
    &lt;appender-ref ref="stdout-appender"/&gt;
  &lt;/root&gt;
&lt;/log4j:configuration&gt;
</div>
</div>

<ol>
<li>In log4j there are <b>5 logging levels</b>:&nbsp;DEBUG &lt; INFO &lt; WARN &lt; ERROR &lt; FATAL. The value of DEBUG is the lowest, so when you set to log DEBUG level messages, log4j will log everything, including INFO, WARN, ERROR, and FATAL messages.</li>
<li>You can see the &lt;<b>appender name="</b><i>stdout-appender</i><b>" class="org.apache.log4j.ConsoleAppender"&gt;</b>. This element indicates the destination of logs.</li>
<ol>
<li><b>ConsoleAppender</b>&nbsp;tell log4j to output all the messages to the console (in our case to the Eclipse console).</li>
<li><b>FileAppender</b>&nbsp;will save all the logs to the file indicated in the parameters like&nbsp;<b>&lt;param name="File" value="./logs/sql.log"/&gt;</b>. Thus, developer can save the log even to the remote server.</li>
</ol>
<li>You can give any arbitrary name to the appender such as <i>stdout-appender</i>. These names will be used later when we create different type of loggers.</li><li>Inside the &lt;appender&gt; you will see the <b>&lt;layout class="org.apache.log4j.PatternLayout"&gt;</b>. This tells log4j how to display the messages. You might want it to log the code line number where the message was logged, or you might want to log the exact time when the message was logged. This gives the developer high flexibility.</li><li>In log4jdbc there are <b>5 different loggers</b>: <i>jdbc.sqlonly,&nbsp;jdbc.sqltiming,&nbsp;jdbc.audit,&nbsp;jdbc.resultset,&nbsp;jdbc.connection</i>. In the configurations they are indicated as&nbsp;&lt;logger name="jdbc.sqlonly" additivity="false"&gt;.</li></ol>

<table class="rowbg border blackcap">
<thead>
<tr>
	<th>Logger name</th>
	<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
	<td width="150px">JDBC.sqlonly</td>
	<td width="575px">Logs SQL statements only.<br /><br />If it is <i>PreparedStatement</i>, there is a SQL statement that is configured as a related argument value.</td>
</tr>
<tr>
	<td>JDBC.sqltimming</td>
	<td>Includes time information (in ms) used to execute a SQL statement and its corresponding SQL.</td>
</tr>
<tr>
	<td>JDBC.audit</td>
	<td>Logs all JDBC call information except for ResultSet.<br /><br />(Because a large number of logs is created, it is not recommended to use this logger except for tracing a specific JDBC error.)</td>
</tr>
<tr>
	<td>JDBC.resultset</td>
	<td>Logs all JDBC call information, including ResultSet; a large number of logs is created.</td>
</tr>
<tr>
	<td>JDBC.connection</td>
	<td>Logs open/close transactions for connections. (log4jdbc version 1.2alpha1 or later.)</td>
</tr>
</tbody>
</table>

<p>If all 5 loggers are set to a level less than error (such as the FATAL level), then log4jdbc will not log anything and in fact the actual (real) connection to the underlying database will be returned by the log4jdbc driver (thus allowing log4jdbc to be installed and available to turn on at runtime at a moment's notice without imposing any actual performance loss when not being used). If any of the 5 logs are set to ERROR level or above (e.g ERROR,INFO or DEBUG) then log4jdbc will be activated, wrapping and logging activity in the JDBC connections returned by the underlying driver.
</p><p>Each of these logs can be set at either DEBUG, INFO or ERROR level.</p>

<ul>
<li><strong>DEBUG</strong>&nbsp;includes the class name and line number (if available) at which the SQL was executed.&nbsp;<strong>Use DEBUG level with extra care, as this imposes an additional performance penalty when in use.</strong></li>
<li><strong>INFO</strong>&nbsp;includes the SQL (or other information as applicable.)</li>
<li><strong>ERROR</strong>&nbsp;will show the stack traces in the log output when SQLExceptions occur.</li></ul>

<p>To check SQL statements, configure JDBC.sqlonly to INFO level.</p>

<div class="code">
<div editor_component="code_highlighter" code_type="xml" first_line="1" collapse="false" nogutter="false" nocontrols="false">
&lt;logger name="jdbc.sqlonly" additivity="false"&gt;
  &lt;level value="info"/&gt;
  &lt;appender-ref ref="sql-appender"/&gt;
&lt;/logger&gt;
</div>
</div>

<p>If you want to know how long SQL statements have been executed, use JDBC.sqltiming.</p>

<div class="code">
<div editor_component="code_highlighter" code_type="xml" first_line="1" collapse="false" nogutter="false" nocontrols="false">
&lt;logger name="jdbc.sqltiming" additivity="false"&gt;
  &lt;level value="fatal"/&gt;
  &lt;appender-ref ref="sql-timing-appender"/&gt;
&lt;/logger&gt;
</div>
</div>

<p>Because Jdbc.audit, JDBC.resultset, or JDBC.connection creates a large number of logs, it is not recommended to use it except for a special case. In the log4jdbc example given above, it is shown how to use them.</p>

<p class="important">In the default log4j.xml configurations given above, notice that&nbsp;<b>jdbc.connection</b> logger uses the <b>connection-appender</b> appender as its log destination. However, notice that at the beginning of the log4j.xml configuration file where the different appenders are declared, there is no connection-appender declared. This will cause log4j to display an error message&nbsp;<b><span style="color: rgb(255, 0, 0); ">log4j:ERROR No appender named [connection-appender] could be found.</span></b> What you can do is change the appender for jdbc.connection logger from connection-appender to&nbsp;<b>jdbc-connection</b>. In fact, probably, this is what was intended in the original sample configuration file.</p>

<h2 id="log4jdbc-example">log4jdbc Example</h2>

<p>The following example is completely self-explanatory. Every line is heavily commented, so you should not have any difficulties what each statement does. Briefly speaking, what we are trying to do in this example is to establish a connect to the CUBRID JDBC Driver using the log4jdbc library, which will log all the actions we perform. Then we retrieve table metadata from the database to see if there is a table called "event". Since there is an "event" table in the "demodb" database in CUBRID, after the first requests log4jdbc logs that there is such a table. In the second request for "someabsenttable" table, it logs that such table does not exist. Below you can see the sample output.</p>

<div class="code">
<div editor_component="code_highlighter" code_type="java" first_line="1" collapse="false" nogutter="false" nocontrols="false">
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import org.apache.log4j.Logger;

import cubrid.jdbc.driver.CUBRIDException;

import net.sf.log4jdbc.ConnectionSpy;
import net.sf.log4jdbc.DriverSpy;

public class CubridDB {
  // This logger is the main instance which will handle the logging.
  // It is derived from the Apache log4j package.
  private static Logger logger = Logger.getLogger(CubridDB.class.getName());
  // Originally CUBRID JDBC connection string is
  // "jdbc:cubrid:localhost:30000:demodb:dba::"
  // However, to be able to log all the actions we perform with the JDBC driver
  // we need to wrap original driver connection by log4jdbc library class,
  // so we modified the connection string.
  private static final String CUBRID_JDBC_WRAPPED_URL = 
    "jdbc:log4jdbc:cubrid:localhost:33000:demodb:::";
  
  public static void main(String[] args) {
    // Below we will load the CUBRID JDBC driver, which "may" not exist,
    // so we need to wrap the code into the try/catch block.
    // Also when connecting to the Driver another exception can be thrown.
    try {
      // This line tell Java to load the CUBRID JDBC driver.
      Class.forName("cubrid.jdbc.driver.CUBRIDDriver");
      // Initialize log4jdbc DriverSpy class.
      DriverSpy driverSpy = new DriverSpy();
      // Here is one example how to log the "info" level messages
      logger.info("Cheking URL");
      // Here we want to see if log4jdbc library class (DriverSpy) accepts
      // the connection string of our driver.
      if (driverSpy.acceptsURL("CUBRID_JDBC_WRAPPED_URL){
        logger.info("URL is accepted so we are good to move on");
        // The following properties could be set in the separate .properties file
        // In our case we just illustrate how to do it programmatically.
        // We create a property and assign CUBRID database user name and password.
        // The default user name for "demodb" database is dba,
        // and the password is blank.
        Properties props = new Properties(); 
        props.setProperty("cubrid.user", "dba");
        props.setProperty("cubrid.password", "");
        // ConnectionSpy is the connection wrapper class. When we pass the JDBC
        // connection string to the DriverSpy it establishes the connection with
        // CUBRID JDBC driver and wraps it with its own class. The connection
        // may take a bit of a time, so be patient.
        try{
          ConnectionSpy connection = 
            (ConnectionSpy) driverSpy.connect(CUBRID_JDBC_WRAPPED_URL, props);
          // After we tried to connect, we do not need to check if the
          // connection != null, because DriverSpy throws an Exception if
          // otherwise.
          
          // Log that the connection has been successfully established
          // and log CUBRID JDBC driver version.
          logger.info("Connection established. CUBRID JDBC version is: " + 
              driverSpy.getMajorVersion() + "." + driverSpy.getMinorVersion());
          // Let's do some more data retrieval. Let's see if in our database
          // there is a table called "event". Such table exists in the "demodb"
          // database, so would result in true.
          
          // Get the database meta data from the wrapped connection 
          DatabaseMetaData metaData = connection.getMetaData();
          // Get the array of tables which have "event" in the name.
          ResultSet rs = metaData.getTables(null, null, "event", new String[]{"TABLE"});
          // If there is any table with "event" in the name, it will be possible
          // to iterate through the array.
          if (rs.next()) {
            // Want to log this time too that the table exists.
            logger.info(""Event" TABLE exists");
          }
          else{
            logger.info(""Event" TABLE does not exists");
          }
          // One more example, but in this case the result should tell us that
          // the table we requested is absent.
          rs = metaData.getTables(null, null, "someabsenttable", new String[]{"TABLE"});
          // If should fail to iterate to the next record.
          if (rs.next()) {
            // Want to log this time too that the table exists.
            logger.info(""someabsenttable" TABLE exists");
          }
          else{
            logger.info(""someabsenttable" TABLE does not exists");
          }
          // Free the ResultSet memory
          rs.close();
        }
        catch(CUBRIDException e){
          // This time we would like to log an ERROR level message. There can be
          // different type of exceptions. 1. "Cannot connect to a broker".
          // In this case, start the CUBRID Broker by typing "cubrid broker start"
          // in the command line. 2. "Failed to connect to database server,
          // 'demodb', on the following host(s): localhost". This indicates that
          // you forgot to start the "demodb" database. Or such database
          // does not exist. To start the dmeodb CUBRID database, type
          // "cubrid server start demodb" in the command line.
          logger.error(e);
        }
      }
    } catch (ClassNotFoundException e) {
      // We let the logger handle the message even all the exceptions.
      logger.error(e);
    } catch (SQLException e) {
      // This exception too.
      logger.error(e);
    }
  }
}
</div>
</div>

<h3 id="sample-output">Sample Output</h3>

<p>This is the output you should see if you run the above example.</p>

<div class="code">
<div editor_component="code_highlighter" code_type="bash" first_line="1" collapse="false" nogutter="false" nocontrols="false">
2010-11-19 10:36:10.406 DEBUG debug: ... log4jdbc initializing ...
2010-11-19 10:36:10.406 DEBUG debug: x log4jdbc.debug.stack.prefix is not defined
2010-11-19 10:36:10.406 DEBUG debug: x log4jdbc.sqltiming.warn.threshold is not defined
2010-11-19 10:36:10.406 DEBUG debug: x log4jdbc.sqltiming.error.threshold is not defined
2010-11-19 10:36:10.406 DEBUG debug:   log4jdbc.drivers = cubrid.JDBC.driver.CUBRIDDriver
2010-11-19 10:36:10.406 DEBUG debug:     will look for additional driver cubrid.JDBC.driver.CUBRIDDriver
2010-11-19 10:36:10.421 DEBUG debug: WARNING!  log4jdbc couldn't find any underlying jdbc drivers.
2010-11-19 10:36:10.421 DEBUG debug: ... log4jdbc initialized! ...
2010-11-19 10:36:10.421  INFO CubridDB: Cheking URL
2010-11-19 10:36:10.421  INFO CubridDB: URL is accepted so we are good to move on
2010-11-19 10:36:10.640  INFO CubridDB: Connection established. CUBRID JDBC version is: 8.3
2010-11-19 10:36:10.640 DEBUG audit: 1. Connection.getMetaData() returned cubrid.jdbc.driver.CUBRIDDatabaseMetaData@93dcd  CubridDB.main(CubridDB.java:68)
2010-11-19 10:36:10.687  INFO CubridDB: "Event" TABLE exists
2010-11-19 10:36:10.703  INFO CubridDB: "someabsenttable" TABLE does not exists
</div>
</div>

<h2 id="see-also">See also</h2>

<ul>
<li>log4jdbc home page <a href="http://code.google.com/p/log4jdbc/" target="_blank">http://code.google.com/p/log4jdbc/</a></li><li>SLF4J manual&nbsp;<a href="http://www.slf4j.org/manual.html">http://www.slf4j.org/manual.html</a></li><li>log4j manual&nbsp;<a href="http://logging.apache.org/log4j/1.2/manual.html">http://logging.apache.org/log4j/1.2/manual.html</a></li></ul>

<h2 id="getting-help">Getting Help</h2>

<p>If you have any difficulties with log4jdbc, post your question to CUBRID Forum at&nbsp;<a href="/?mid=forum&amp;category=195533">http://www.cubrid.org/?mid=forum&amp;category=195533</a>.</p>]]></description>
                        <pubDate>Tue, 06 Apr 2010 16:13:44 -0800</pubDate>
                        <category>jdbc</category>
                        <category>java</category>
                        <category>log4jdbc</category>
                        <category>log4j</category>
                        <category>slf4j</category>
                        <category>eclipse</category>
                                </item>
            </channel>
</rss>
