April 24, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Creating a JDBC Log Handler for JDK 1.4, Page 2

  • September 23, 2002
  • By Jeff Heaton, Jeff Heaton
  • Send Email »
  • More Articles »

Conclusions

The Logging API of JDK 1.4 provides many new features that will help standardize the way Java applications store logging information. Because this API is standard to the Java platform, logging utilities can be used by multiple applications. The JDBC handler presented in this article could easily be incorporated into any project that makes use of JDK 1.4's Logging API.

Listing 1: A JDBC log handler

import java.util.logging.*;
import java.sql.*;

/**
 * JDBC Logging Article
 *
 * This is a reusable class that implements
 * a JDK1.4 log handler that will write the
 * contents of the log to a JDBC data source.
 * 
 * ©author Jeff Heaton (http://www.jeffheaton.com)
 * ©version 1.0
 * ©since January 2002
 */
public class JDBCLogHandler extends Handler {

  /**
   * A string that contains the classname of the JDBC driver.
   * This value is filled by the constructor.
   */
  String driverString;

  /**
   * A string that contains the connection string used by the
   * JDBC driver. This value is filled by the constructor.
   */
  String connectionString;

  /**
   * Used to hold the connection to the JDBC data source.
   */
  Connection connection;

  /**
   * A SQL statement used to insert into the log table.
   */
  protected final static String insertSQL=
  "insert into log (level,logger,message,sequence,"
  +"sourceClass,sourceMethod,threadID,timeEntered)"
  +"values(?,?,?,?,?,?,?,?)";

  /**
   * A SQL statement used to clear the log table.
   */
  protected final static String clearSQL=
  "delete from log;";

  /**
   * A PreparedStatement object used to hold the main
   * insert statement.
   */
  protected PreparedStatement prepInsert;

  /**
   * A PreparedStatement object used to hold the clear
   * statement.
   */
  protected PreparedStatement prepClear;


  /**
   * @param driverString The JDBC driver to use.
   * @param connectionString The connection string that
   * specifies the database to use.
   */
  public JDBCLogHandler(String driverString,
                        String connectionString)
  {
    try {
      this.driverString = driverString;
      this.connectionString = connectionString;

      Class.forName(driverString);
      connection = DriverManager.getConnection(connectionString);
      prepInsert = connection.prepareStatement(insertSQL);
      prepClear = connection.prepareStatement(clearSQL);
    } catch ( ClassNotFoundException e ) {
      System.err.println("Error on open: " + e);
    } catch ( SQLException e ) {
      System.err.println("Error on open: " + e);
    }
  }

  /**
   * Internal method used to truncate a string to a specified width.
   * Used to ensure that SQL table widths are not exceeded.
   * 
   * @param str The string to be truncated.
   * @param length The maximum length of the string.
   * @return The string truncated.
   */
  static public String truncate(String str,int length)
  {
    if ( str.length()<length )
      return str;
    return( str.substring(0,length) );
  }

  /**
   * Overridden method used to capture log entries and put them
   * into a JDBC database.
   * 
   * @param record The log record to be stored.
   */
  public void publish(LogRecord record)
  {
    // first see if this entry should be filtered out
    if ( getFilter()!=null ) {
      if ( !getFilter().isLoggable(record) )
        return;
    }

    // now store the log entry into the table
    try {
      prepInsert.setInt(1,record.getLevel().intValue());
      prepInsert.setString(2,truncate(record.getLoggerName(),63));
      prepInsert.setString(3,truncate(record.getMessage(),255));
      prepInsert.setLong(4,record.getSequenceNumber());
      prepInsert.setString(5,truncate
                          (record.getSourceClassName(),63));
      prepInsert.setString(6,truncate
                          (record.getSourceMethodName(),31));
      prepInsert.setInt(7,record.getThreadID());
      prepInsert.setTimestamp(8,
                              new Timestamp
                                  (System.currentTimeMillis()) );
      prepInsert.executeUpdate();
    } catch ( SQLException e ) {
      System.err.println("Error on open: " + e);
    }

  }

  /**
   * Called to close this log handler.
   */
  public void close()
  {
    try {
      if ( connection!=null )
        connection.close();
    } catch ( SQLException e ) {
      System.err.println("Error on close: " + e);
    }
  }

  /**
   * Called to clear all log entries from the database.
   */
  public void clear()
  {
    try {
      prepClear.executeUpdate();
    } catch ( SQLException e ) {
      System.err.println("Error on clear: " + e);
    }
  }


  /**
   * Not really used, but required to implement a handler. Since 
   * all data is immediately sent to the database, there is no 
   * reason to flush.
   */
  public void flush()
  {
  }
}

Listing 2: Example of using the JDBCHandler class

import java.util.logging.*;

public class TestLog {

  /**
   * Set the following string to whatever JDBC
   * driver you wish to use. I have it set to
   * use the MM driver of MySQL. You can get the
   * MM driver from: 
   * http://mmmysql.sourceforge.net/.
   */
  static public final String driver
  = "org.gjt.mm.mysql.Driver";

  /**
   * Set this to your connection string to access
   * your database. Refer to your database
   * documentation on how to set this. The one
   * I have below logs into a MySQL database.
   */
  static public final String connection
  = "jdbc:mysql://192.168.1.100/logging"
    +"?user=logger&password=logpass&database=logging";
  /**
   * Main function. Performs some basic
   * log testing.
   * 
   * @param argv Arguments are not used.
   */

  public static void main(String argv[])
  {
    // set up the JDBCLogger handler
    JDBCLogHandler jdbcHandler 
    = new JDBCLogHandler(driver,connection);
    jdbcHandler.clear();


    // setup
    Logger logger
    = Logger.getLogger("com.heaton.articles.logger");
    logger.addHandler(jdbcHandler);
    logger.setLevel(Level.ALL);

    // try some logging

    logger.info("Sample log entry");

    logger.warning("Sample warning");

    try {
      int i=0/0;
    } catch ( Exception e ) {
      logger.log(Level.WARNING, 
        "This is what an exception looks like", e);
    }
  }
}

Author Bio

Jeff Heaton is the author of the upcoming JSTL: JSP Standard Tag Library (Sams, 2002). Jeff works as a software designer for Reinsurance Group of America. Jeff has written three books and numerous magazine articles about computer programming. Jeff may be contacted through his Web site, http://www.jeffheaton.com.





Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel