View Javadoc

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