View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2009, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.access.db;
15  
16  import java.lang.reflect.Method;
17  import java.sql.Connection;
18  import java.sql.PreparedStatement;
19  import java.sql.SQLException;
20  import java.util.Enumeration;
21  
22  import ch.qos.logback.access.spi.AccessEvent;
23  import ch.qos.logback.core.db.DBAppenderBase;
24  
25  /**
26   * The DBAppender inserts access events into three database tables in a format
27   * independent of the Java programming language. 
28   * 
29   * For more information about this appender, please refer to the online manual at
30   * http://logback.qos.ch/manual/appenders.html#AccessDBAppender
31   * 
32   * @author Ceki Gülcü
33   * @author Ray DeCampo
34   * @author Sébastien Pennec
35   */
36  public class DBAppender extends DBAppenderBase<AccessEvent> {
37    protected static final String insertSQL;
38    protected final String insertHeaderSQL = "INSERT INTO  access_event_header (event_id, header_key, header_value) VALUES (?, ?, ?)";
39    protected static final Method GET_GENERATED_KEYS_METHOD; 
40  
41    private boolean insertHeaders = false;
42    
43    static {
44      StringBuffer sql = new StringBuffer();
45      sql.append("INSERT INTO access_event (");
46      sql.append("timestmp, ");
47      sql.append("requestURI, ");
48      sql.append("requestURL, ");
49      sql.append("remoteHost, ");
50      sql.append("remoteUser, ");
51      sql.append("remoteAddr, ");
52      sql.append("protocol, ");
53      sql.append("method, ");
54      sql.append("serverName, ");
55      sql.append("postContent) ");
56      sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?)");
57      insertSQL = sql.toString();
58  
59      Method getGeneratedKeysMethod;
60      try {
61        getGeneratedKeysMethod = PreparedStatement.class.getMethod(
62            "getGeneratedKeys", (Class[]) null);
63      } catch (Exception ex) {
64        getGeneratedKeysMethod = null;
65      }
66      GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod;
67    }
68    
69    public DBAppender() {
70    }
71  
72    @Override
73    protected void subAppend(Object eventObject, Connection connection,
74        PreparedStatement insertStatement) throws Throwable {
75      AccessEvent event = (AccessEvent) eventObject;
76  
77      addAccessEvent(insertStatement, event);
78      
79      int updateCount = insertStatement.executeUpdate();
80      if (updateCount != 1) {
81        addWarn("Failed to insert access event");
82      }
83      
84      if (insertHeaders) {
85        int eventId = selectEventId(insertStatement, connection);
86        addRequestHeaders(event, connection, eventId);
87      }
88    }
89    
90    void addAccessEvent(PreparedStatement stmt, AccessEvent event)
91        throws SQLException {
92      stmt.setLong(1, event.getTimeStamp());
93      stmt.setString(2, event.getRequestURI());
94      stmt.setString(3, event.getRequestURL());
95      stmt.setString(4, event.getRemoteHost());
96      stmt.setString(5, event.getRemoteUser());
97      stmt.setString(6, event.getRemoteAddr());
98      stmt.setString(7, event.getProtocol());
99      stmt.setString(8, event.getMethod());
100     stmt.setString(9, event.getServerName());
101     stmt.setString(10, event.getRequestContent()); 
102   }
103   
104   void addRequestHeaders(AccessEvent event,
105       Connection connection, int eventId) throws SQLException {
106     Enumeration names = event.getRequestHeaderNames();
107     if (names.hasMoreElements()) {
108       PreparedStatement insertHeaderStatement = connection
109           .prepareStatement(insertHeaderSQL);
110 
111       
112       while (names.hasMoreElements()) {
113         String key = (String) names.nextElement();
114         String value = (String) event.getRequestHeader(key);
115 
116         insertHeaderStatement.setInt(1, eventId);
117         insertHeaderStatement.setString(2, key);
118         insertHeaderStatement.setString(3, value);
119 
120         if (cnxSupportsBatchUpdates) {
121           insertHeaderStatement.addBatch();
122         } else {
123           insertHeaderStatement.execute();
124         }
125       }
126 
127       if (cnxSupportsBatchUpdates) {
128         insertHeaderStatement.executeBatch();
129       }
130 
131       insertHeaderStatement.close();
132       insertHeaderStatement = null;
133     }
134   }
135 
136   @Override
137   protected Method getGeneratedKeysMethod() {
138     return GET_GENERATED_KEYS_METHOD;
139   }
140 
141   @Override
142   protected String getInsertSQL() {
143     return insertSQL;
144   }
145   
146   public void setInsertHeaders(boolean insertHeaders) {
147     this.insertHeaders = insertHeaders;
148   }
149 }