/** * Logback: the reliable, generic, fast and flexible logging framework. * Copyright (C) 1999-2015, QOS.ch. All rights reserved. * * This program and the accompanying materials are dual-licensed under * either the terms of the Eclipse Public License v1.0 as published by * the Eclipse Foundation * * or (per the licensee's choosing) * * under the terms of the GNU Lesser General Public License version 2.1 * as published by the Free Software Foundation. */ package ch.qos.logback.access.db; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.Enumeration; import ch.qos.logback.access.spi.IAccessEvent; import ch.qos.logback.core.db.DBAppenderBase; /** * The DBAppender inserts access events into three database tables in a format * independent of the Java programming language. * * For more information about this appender, please refer to the online manual at * http://logback.qos.ch/manual/appenders.html#AccessDBAppender * * @author Ceki Gülcü * @author Ray DeCampo * @author Sébastien Pennec */ public class DBAppender extends DBAppenderBase<IAccessEvent> { protected static final String insertSQL; protected final String insertHeaderSQL = "INSERT INTO access_event_header (event_id, header_key, header_value) VALUES (?, ?, ?)"; protected static final Method GET_GENERATED_KEYS_METHOD; private boolean insertHeaders = false; static { StringBuilder sql = new StringBuilder(); sql.append("INSERT INTO access_event ("); sql.append("timestmp, "); sql.append("requestURI, "); sql.append("requestURL, "); sql.append("remoteHost, "); sql.append("remoteUser, "); sql.append("remoteAddr, "); sql.append("protocol, "); sql.append("method, "); sql.append("serverName, "); sql.append("postContent) "); sql.append(" VALUES (?, ?, ? ,?, ?, ?, ?, ?, ?, ?)"); insertSQL = sql.toString(); Method getGeneratedKeysMethod; try { getGeneratedKeysMethod = PreparedStatement.class.getMethod("getGeneratedKeys", (Class[]) null); } catch (Exception ex) { getGeneratedKeysMethod = null; } GET_GENERATED_KEYS_METHOD = getGeneratedKeysMethod; } @Override protected void subAppend(IAccessEvent event, Connection connection, PreparedStatement insertStatement) throws Throwable { addAccessEvent(insertStatement, event); int updateCount = insertStatement.executeUpdate(); if (updateCount != 1) { addWarn("Failed to insert access event"); } } @Override protected void secondarySubAppend(IAccessEvent event, Connection connection, long eventId) throws Throwable { if (insertHeaders) { addRequestHeaders(event, connection, eventId); } } void addAccessEvent(PreparedStatement stmt, IAccessEvent event) throws SQLException { stmt.setLong(1, event.getTimeStamp()); stmt.setString(2, event.getRequestURI()); stmt.setString(3, event.getRequestURL()); stmt.setString(4, event.getRemoteHost()); stmt.setString(5, event.getRemoteUser()); stmt.setString(6, event.getRemoteAddr()); stmt.setString(7, event.getProtocol()); stmt.setString(8, event.getMethod()); stmt.setString(9, event.getServerName()); stmt.setString(10, event.getRequestContent()); } void addRequestHeaders(IAccessEvent event, Connection connection, long eventId) throws SQLException { Enumeration names = event.getRequestHeaderNames(); if (names.hasMoreElements()) { PreparedStatement insertHeaderStatement = connection.prepareStatement(insertHeaderSQL); while (names.hasMoreElements()) { String key = (String) names.nextElement(); String value = (String) event.getRequestHeader(key); insertHeaderStatement.setLong(1, eventId); insertHeaderStatement.setString(2, key); insertHeaderStatement.setString(3, value); if (cnxSupportsBatchUpdates) { insertHeaderStatement.addBatch(); } else { insertHeaderStatement.execute(); } } if (cnxSupportsBatchUpdates) { insertHeaderStatement.executeBatch(); } insertHeaderStatement.close(); } } @Override protected Method getGeneratedKeysMethod() { return GET_GENERATED_KEYS_METHOD; } @Override protected String getInsertSQL() { return insertSQL; } public void setInsertHeaders(boolean insertHeaders) { this.insertHeaders = insertHeaders; } }