package edu.ualberta.med.biobank.server.logging; import java.util.Date; import java.util.Properties; import java.util.StringTokenizer; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.Layout; import org.apache.log4j.spi.LoggingEvent; import edu.ualberta.med.biobank.common.wrappers.LogWrapper; import edu.ualberta.med.biobank.model.Log; /** * A custom Apache Log4J Appender will be responsible for formatting and * inserting Log4J messages into the configurable RDBMS. * * <br> * <br> * Features include: <br> * --Inserts Logs Messages into the database in near real time <br> * --Uses a configurable buffer to perform batch processing <br> * --Spawns threads to execute the batch inserts to maximise performance <br> * --Prepares all data for RDBMS by escaping quotes. * * See use in log4j.xml * * Copy from CLM JDBCAppender */ public class BiobankJDBCAppender extends AppenderSkeleton { public static final String MYSQL_DIALECT = "org.hibernate.dialect.MySQLDialect"; //$NON-NLS-1$ private String application = null; private String dbUrl = null; private String dbDriverClass = null; private String dbUser = null; private String dbPwd = null; public BiobankJDBCAppender() { } public BiobankJDBCAppender(Layout layout) { super(); setLayout(layout); } @Override public void append(LoggingEvent le) { LocalInfo userInfo = BiobankThreadVariable.get(); if (null == userInfo) { userInfo = new LocalInfo(); } // Determine Log Type String msg = ""; //$NON-NLS-1$ if (le.getMessage() != null) { msg = le.getMessage().toString(); } Log log = null; try { log = populateObjectStateLogMesage(msg); } catch (Exception ex) { ExceptionUtils.writeMsgToTmpFile(ex); } if (log != null) { java.util.Date d = new java.util.Date(); d.setTime(System.currentTimeMillis()); log.setCreatedAt(new Date()); log.setUsername(userInfo.getUsername()); JDBCLogExecutor exe = new JDBCLogExecutor(log, getJDBCProperties()); // execute the batch insert new Thread(exe).start(); } } /** * Method parses the string to populate the log object */ private Log populateObjectStateLogMesage(String objectAttributeMessage) throws Exception { Log log = new Log(); StringTokenizer stringTokenizer = new StringTokenizer( objectAttributeMessage, "&"); //$NON-NLS-1$ while (stringTokenizer.hasMoreElements()) { String messagetemp = (String) stringTokenizer.nextElement(); if (messagetemp.indexOf("=") <= 0) //$NON-NLS-1$ continue; String attributeName = messagetemp.substring(0, messagetemp.indexOf("=")); //$NON-NLS-1$ String value = messagetemp.substring(messagetemp.indexOf("=") + 1); //$NON-NLS-1$ LogWrapper logW = new LogWrapper(null, log); logW.setLogStringValue(attributeName, value); } return log; } /** * This method returns the Hibernate Properties. * * @return Properties */ private Properties getJDBCProperties() { Properties props = new Properties(); props.setProperty("hibernate.connection.driver_class", //$NON-NLS-1$ getDbDriverClass()); props.setProperty("hibernate.connection.url", getDbUrl()); //$NON-NLS-1$ props.setProperty("hibernate.connection.username", getDbUser()); //$NON-NLS-1$ props.setProperty("hibernate.connection.password", getDbPwd()); //$NON-NLS-1$ if (getDbUrl().indexOf(":mysql") > -1) { //$NON-NLS-1$ props.setProperty("hibernate.dialect", MYSQL_DIALECT); //$NON-NLS-1$ } return props; } @Override public boolean requiresLayout() { return true; } public String getApplication() { return application; } public void setApplication(String value) { application = value; } /** * @return Returns the dbDriverClass. */ public String getDbDriverClass() { return dbDriverClass; } /** * @param dbDriverClass The dbDriverClass to set. */ public void setDbDriverClass(String dbDriverClass) { this.dbDriverClass = dbDriverClass; } /** * @return Returns the dbPwd. */ public String getDbPwd() { return dbPwd; } /** * @param dbPwd The dbPwd to set. */ public void setDbPwd(String dbPwd) { this.dbPwd = dbPwd; } /** * @return Returns the dbUrl. */ public String getDbUrl() { return dbUrl; } /** * @param dbUrl The dbUrl to set. */ public void setDbUrl(String dbUrl) { this.dbUrl = dbUrl; } /** * @return Returns the dbUser. */ public String getDbUser() { return dbUser; } /** * @param dbUser The dbUser to set. */ public void setDbUser(String dbUser) { this.dbUser = dbUser; } @Override public void close() { } }