You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2003/11/20 00:56:14 UTC

cvs commit: jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves JDBCAccessLogValve.java LocalStrings.properties

remm        2003/11/19 15:56:14

  Modified:    catalina/src/share/org/apache/catalina/valves
                        JDBCAccessLogValve.java LocalStrings.properties
  Log:
  - Merge code from JDBC realm, fixing the valve after a restart
    of the database.
  - Bug 24832, submitted by Peter Rossbach.
  
  Revision  Changes    Path
  1.3       +225 -69   jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves/JDBCAccessLogValve.java
  
  Index: JDBCAccessLogValve.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves/JDBCAccessLogValve.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- JDBCAccessLogValve.java	2 Sep 2003 21:22:03 -0000	1.2
  +++ JDBCAccessLogValve.java	19 Nov 2003 23:56:14 -0000	1.3
  @@ -63,6 +63,7 @@
   
   import java.io.IOException;
   import java.sql.Connection;
  +import java.sql.Driver;
   import java.sql.DriverManager;
   import java.sql.PreparedStatement;
   import java.sql.SQLException;
  @@ -82,7 +83,7 @@
   import org.apache.catalina.ValveContext;
   import org.apache.catalina.util.LifecycleSupport;
   import org.apache.catalina.util.StringManager;
  -
  +import org.apache.catalina.Logger;
   
   /**
    * <p>
  @@ -153,15 +154,14 @@
    * <i>TO DO: provide option for excluding logging of certain MIME types.</i>
    * </p>
    * 
  - * @version 1.0
    * @author Andre de Jesus
  + * @author Peter Rossbach
    */
   
   public final class JDBCAccessLogValve 
       extends ValveBase 
       implements Lifecycle {
   
  -
       // ----------------------------------------------------------- Constructors
   
   
  @@ -212,6 +212,23 @@
       // ----------------------------------------------------- Instance Variables
   
   
  +   /**
  +     * The connection username to use when trying to connect to the database.
  +     */
  +    protected String connectionName = null;
  +
  +
  +    /**
  +     * The connection URL to use when trying to connect to the database.
  +     */
  +    protected String connectionPassword = null;
  +
  +   /**
  +     * Instance of the JDBC Driver class we use as a connection factory.
  +     */
  +    protected Driver driver = null;
  +
  +
       private String driverName;
       private String connectionURL;
       private String tableName;
  @@ -262,7 +279,23 @@
   
   
       // ------------------------------------------------------------- Properties
  + 
  +    /**
  +     * Return the username to use to connect to the database.
  +     *
  +     */
  +    public String getConnectionName() {
  +        return connectionName;
  +    }
   
  +    /**
  +     * Set the username to use to connect to the database.
  +     *
  +     * @param connectionName Username
  +     */
  +    public void setConnectionName(String connectionName) {
  +        this.connectionName = connectionName;
  +    }
   
       /**
        * Sets the database driver name.
  @@ -273,6 +306,23 @@
           this.driverName = driverName;
       }
   
  +   /**
  +     * Return the password to use to connect to the database.
  +     *
  +     */
  +    public String getConnectionPassword() {
  +        return connectionPassword;
  +    }
  +
  +    /**
  +     * Set the password to use to connect to the database.
  +     *
  +     * @param connectionPassword User password
  +     */
  +    public void setConnectionPassword(String connectionPassword) {
  +        this.connectionPassword = connectionPassword;
  +    }
  +
       /**
        * Sets the JDBC URL for the database where the log is stored.
        * 
  @@ -457,25 +507,7 @@
           if(bytes < 0)
               bytes = 0;
           int status = ((HttpResponse)response).getStatus();
  -
  -        synchronized (ps) {
  -            try {
  -                ps.setString(1, remoteHost);
  -                ps.setString(2, user);
  -                ps.setTimestamp(3, new Timestamp(getCurrentTimeMillis()));
  -                ps.setString(4, query);
  -                ps.setInt(5, status);
  -                ps.setInt(6, bytes);
  -            } catch(SQLException e) {
  -                throw new ServletException(e);
  -            }
  -            if (pattern.equals("common")) {
  -                try {
  -                    ps.executeUpdate();
  -                } catch(SQLException e) {
  -                    throw new ServletException(e);
  -                }
  -            } else if (pattern.equals("combined")) {
  +        if (pattern.equals("combined")) {
                   String virtualHost = "";
                   if(hreq != null)
                       virtualHost = hreq.getServerName();
  @@ -488,16 +520,50 @@
                   String userAgent = "";
                   if(hreq != null)
                       userAgent = hreq.getHeader("user-agent");
  -                try {
  -                    ps.setString(7, virtualHost);
  -                    ps.setString(8, method);
  -                    ps.setString(9, referer);
  -                    ps.setString(10, userAgent);
  -                    ps.executeUpdate();
  -                } catch (SQLException e) {
  -                    throw new ServletException(e);
  +        }
  +        synchronized (this) {
  +          int numberOfTries = 2;
  +          while (numberOfTries>0) {
  +            try {
  +                open();
  +    
  +                ps.setString(1, remoteHost);
  +                ps.setString(2, user);
  +                ps.setTimestamp(3, new Timestamp(getCurrentTimeMillis()));
  +                ps.setString(4, query);
  +                ps.setInt(5, status);
  +                ps.setInt(6, bytes);
  +                if (pattern.equals("combined")) {
  +     
  +                      String virtualHost = "";
  +                      if(hreq != null)
  +                         virtualHost = hreq.getServerName();
  +                      String method = "";
  +                      if(hreq != null)
  +                         method = hreq.getMethod();
  +                      String referer = "";
  +                      if(hreq != null)
  +                         referer = hreq.getHeader("referer");
  +                      String userAgent = "";
  +                      if(hreq != null)
  +                         userAgent = hreq.getHeader("user-agent");
  +                      ps.setString(7, virtualHost);
  +                      ps.setString(8, method);
  +                      ps.setString(9, referer);
  +                      ps.setString(10, userAgent);
                   }
  -            }
  +                ps.executeUpdate();
  +                return;
  +              } catch (SQLException e) {
  +                // Log the problem for posterity
  +                log(sm.getString("jdbcAccessLogValve.exception"), e);
  +
  +                // Close the connection so that it gets reopened next time
  +                if (conn != null)
  +                    close();
  +              }
  +    	      numberOfTries--;        
  +           }
           }
   
       }	
  @@ -537,42 +603,45 @@
   
       }
   
  -
       /**
  -     * Invoked by Tomcat on startup. The database connection is set here.
  -     * 
  -     * @exception LifecycleException Can be thrown on lifecycle 
  -     * inconsistencies or on database errors (as a wrapped SQLException).
  -     */
  -    public void start() throws LifecycleException {
  +     * Open (if necessary) and return a database connection for use by
  +     * this AccessLogValve.
  +     *
  +     * @exception SQLException if a database error occurs
  +     */
  +    protected void open() throws SQLException {
  +
  +        // Do nothing if there is a database connection already open
  +        if (conn != null)
  +            return ;
   
  -        if (started)
  -            throw new LifecycleException
  -                (sm.getString("accessLogValve.alreadyStarted"));
  -        lifecycle.fireLifecycleEvent(START_EVENT, null);
  -        started = true;
  -
  -        try {
  -            Class.forName(driverName).newInstance(); 
  -        } catch (ClassNotFoundException e) {
  -            throw new LifecycleException(e);
  -        } catch (InstantiationException e) {
  -            throw new LifecycleException(e);
  -        } catch (IllegalAccessException e) {
  -            throw new LifecycleException(e);
  +        // Instantiate our database driver if necessary
  +        if (driver == null) {
  +            try {
  +                Class clazz = Class.forName(driverName);
  +                driver = (Driver) clazz.newInstance();
  +            } catch (Throwable e) {
  +                throw new SQLException(e.getMessage());
  +            }
           }
  -        Properties info = new Properties();
  -        info.setProperty("autoReconnect", "true");
  -        try {
  -            conn = DriverManager.getConnection(connectionURL, info);
  -            if (pattern.equals("common")) {
  +
  +        // Open a new connection
  +        Properties props = new Properties();
  +        props.put("autoReconnect", "true");
  +        if (connectionName != null)
  +            props.put("user", connectionName);
  +        if (connectionPassword != null)
  +            props.put("password", connectionPassword);
  +        conn = driver.connect(connectionURL, props);
  +        conn.setAutoCommit(true);
  +        if (pattern.equals("common")) {
                   ps = conn.prepareStatement
                       ("INSERT INTO " + tableName + " (" 
                        + remoteHostField + ", " + userField + ", "
                        + timestampField +", " + queryField + ", "
                        + statusField + ", " + bytesField 
                        + ") VALUES(?, ?, ?, ?, ?, ?)");
  -            } else if (pattern.equals("combined")) {
  +        } else if (pattern.equals("combined")) {
                   ps = conn.prepareStatement
                       ("INSERT INTO " + tableName + " (" 
                        + remoteHostField + ", " + userField + ", "
  @@ -581,7 +650,56 @@
                        + virtualHostField + ", " + methodField + ", "
                        + refererField + ", " + userAgentField
                        + ") VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
  -            }
  +        }
  +    }
  +
  +    /**
  +     * Close the specified database connection.
  +     *
  +     * @param dbConnection The connection to be closed
  +     */
  +    protected void close() {
  +
  +        // Do nothing if the database connection is already closed
  +        if (conn == null)
  +            return;
  +
  +        // Close our prepared statements (if any)
  +        try {
  +            ps.close();
  +        } catch (Throwable f) {
  +            ;
  +        }
  +        this.ps = null;
  +
  +
  +
  +        // Close this database connection, and log any errors
  +        try {
  +            conn.close();
  +        } catch (SQLException e) {
  +            log(sm.getString("jdbcAccessLogValeve.close"), e); // Just log it here            
  +        } finally {
  +           this.conn = null;
  +        }
  +
  +    }
  +    /**
  +     * Invoked by Tomcat on startup. The database connection is set here.
  +     * 
  +     * @exception LifecycleException Can be thrown on lifecycle 
  +     * inconsistencies or on database errors (as a wrapped SQLException).
  +     */
  +    public void start() throws LifecycleException {
  +
  +        if (started)
  +            throw new LifecycleException
  +                (sm.getString("accessLogValve.alreadyStarted"));
  +        lifecycle.fireLifecycleEvent(START_EVENT, null);
  +        started = true;
  +
  +        try {
  +            open() ;        
           } catch (SQLException e) {
               throw new LifecycleException(e);
           }
  @@ -602,16 +720,9 @@
                   (sm.getString("accessLogValve.notStarted"));
           lifecycle.fireLifecycleEvent(STOP_EVENT, null);
           started = false;
  -
  -        try {
  -            if (ps != null)
  -                ps.close();
  -            if (conn != null)
  -                conn.close();
  -    	} catch (SQLException e) {
  -            throw new LifecycleException(e);	
  -        }
  -
  +        
  +        close() ;
  +    	
       }
   
   
  @@ -623,5 +734,50 @@
           return currentTimeMillis;
       }
   
  +    /**
  +     * Log a message on the Logger associated with our Container (if any)
  +     *
  +     * @param message Message to be logged
  +     */
  +    protected void log(String message) {
  +
  +        Logger logger = null;
  +        String name = null;
  +        if (container != null) {
  +            logger = container.getLogger();
  +            name = container.getName();
  +        }
  +
  +        if (logger != null) {
  +            logger.log(connectionURL+"[" + name + "]: " + message);
  +        } else {
  +            System.out.println(connectionURL+"[" + name + "]: " + message);
  +        }
  +
  +    }
  +
  +
  +    /**
  +     * Log a message on the Logger associated with our Container (if any)
  +     *
  +     * @param message Message to be logged
  +     * @param throwable Associated exception
  +     */
  +    protected void log(String message, Throwable throwable) {
  +
  +        Logger logger = null;
  +        String name = null;
  +        if (container != null) {
  +            logger = container.getLogger();
  +            name = container.getName();
  +        }
  +
  +        if (logger != null) {
  +            logger.log(connectionURL+"[" + name + "]: " + message, throwable);
  +        } else {
  +            System.out.println(connectionURL+"[" + name + "]: " + message);
  +            throwable.printStackTrace(System.out);
  +        }
  +    }
   
   }
  
  
  
  1.6       +2 -0      jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves/LocalStrings.properties
  
  Index: LocalStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves/LocalStrings.properties,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- LocalStrings.properties	19 Jul 2003 14:30:07 -0000	1.5
  +++ LocalStrings.properties	19 Nov 2003 23:56:14 -0000	1.6
  @@ -9,6 +9,8 @@
   requestListenerValve.requestInit=Exception sending request initialized lifecycle event to listener instance of class {0}
   requestListenerValve.requestDestroy=Exception sending request destroyed lifecycle event to listener instance of class {0}
   valveBase.noNext=Configuration error: No 'next' valve configured
  +jdbcAccessLogValve.exception=Exception performing insert access entry
  +jdbcAccessLogValve.close=Exception closing database connection
   
   # Error report valve
   errorReportValve.errorReport=Error report
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org