View Javadoc

1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2011, 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.IAccessEvent;
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<IAccessEvent> {
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(IAccessEvent event, Connection connection,
74        PreparedStatement insertStatement) throws Throwable {
75  
76      addAccessEvent(insertStatement, event);
77      
78      int updateCount = insertStatement.executeUpdate();
79      if (updateCount != 1) {
80        addWarn("Failed to insert access event");
81      }
82    }
83    
84    protected void secondarySubAppend(IAccessEvent event, Connection connection,
85        long eventId) throws Throwable {
86      if (insertHeaders) {
87        addRequestHeaders(event, connection, eventId);
88      }
89    }
90    
91    void addAccessEvent(PreparedStatement stmt, IAccessEvent event)
92        throws SQLException {
93      stmt.setLong(1, event.getTimeStamp());
94      stmt.setString(2, event.getRequestURI());
95      stmt.setString(3, event.getRequestURL());
96      stmt.setString(4, event.getRemoteHost());
97      stmt.setString(5, event.getRemoteUser());
98      stmt.setString(6, event.getRemoteAddr());
99      stmt.setString(7, event.getProtocol());
100     stmt.setString(8, event.getMethod());
101     stmt.setString(9, event.getServerName());
102     stmt.setString(10, event.getRequestContent()); 
103   }
104   
105   void addRequestHeaders(IAccessEvent event,
106       Connection connection, long eventId) throws SQLException {
107     Enumeration names = event.getRequestHeaderNames();
108     if (names.hasMoreElements()) {
109       PreparedStatement insertHeaderStatement = connection
110           .prepareStatement(insertHeaderSQL);
111 
112       
113       while (names.hasMoreElements()) {
114         String key = (String) names.nextElement();
115         String value = (String) event.getRequestHeader(key);
116 
117         insertHeaderStatement.setLong(1, eventId);
118         insertHeaderStatement.setString(2, key);
119         insertHeaderStatement.setString(3, value);
120 
121         if (cnxSupportsBatchUpdates) {
122           insertHeaderStatement.addBatch();
123         } else {
124           insertHeaderStatement.execute();
125         }
126       }
127 
128       if (cnxSupportsBatchUpdates) {
129         insertHeaderStatement.executeBatch();
130       }
131 
132       insertHeaderStatement.close();
133       insertHeaderStatement = null;
134     }
135   }
136 
137   @Override
138   protected Method getGeneratedKeysMethod() {
139     return GET_GENERATED_KEYS_METHOD;
140   }
141 
142   @Override
143   protected String getInsertSQL() {
144     return insertSQL;
145   }
146   
147   public void setInsertHeaders(boolean insertHeaders) {
148     this.insertHeaders = insertHeaders;
149   }
150 }