/*******************************************************************************
* Copyright 2012 Pradeep Nambiar, Pexus LLC
*
* Source File: src/org/perf/log/logger/DBWriter.java
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package org.perf.log.logger;
/**
*
* @author Pradeep Nambiar 2/10/2012
*/
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import org.perf.log.properties.LoggerProperties;
import org.perf.log.properties.TunableProperties;
import org.perf.log.utils.PropertyFileLoader;
import org.perf.log.utils.StringUtils;
public class DBWriter {
static String delims = "[-]";
private static Logger logger = LoggerFactory.getLogger(DBWriter.class.getName());
// Properties used by this class
private static final String LOGGER_DBWRITER_DB_WRITE_ENABLED = "dynamic.logger.DBWriter.dbWriteEnabled";// dynamic
static boolean dbWriterEnabled = true;
static boolean propertiesInited = false;
private static TunableProperties tunableProperties = LoggerProperties.getInstance().getTunableProperties();
private static String perfDBDS = "jdbc/perfDB";
private static Context ctx = null;
private static DataSource ds = null;
static {
initProperties();
try {
ctx = new InitialContext();
ds = (DataSource) ctx.lookup(perfDBDS);
} catch (NamingException e) {
logger.error(e.getMessage());
e.printStackTrace();
}
}
private static synchronized void initProperties() {
if (!propertiesInited) {
try {
String propVal;
ClassLoader ctxClassLoader = Thread.currentThread().getContextClassLoader();
Properties props = PropertyFileLoader.load(
"perfLog.properties",
"perfLogDefault.properties",
ctxClassLoader,
DBWriter.class.getClass().getClassLoader(),
DBWriter.class.getName());
if (props != null) {
propVal = props
.getProperty(LOGGER_DBWRITER_DB_WRITE_ENABLED);
if (propVal != null)
setDbWriterEnabled(new Boolean(propVal).booleanValue());
} else {
System.out.println(DBWriter.class.getName()+":Error in reading perfLog.properties or perfLogDefault.properties");
}
} catch (Exception exception) {
System.out.println(DBWriter.class.getName()+":Error Loading perfLog.properties or perfLogDefault.properties"
+ exception.getMessage());
}
propertiesInited = true;
}
}
private static String getTransactionStatus(PerfLogData perfLogData) {
// convert txnType for storing into DB code
if (perfLogData.getThrowable() == null) {
// success code
return "Success";
} else {
// failure code
return "Failure:" + perfLogData.getThrowableClassName() + ":"
+ perfLogData.getThrowableMessage();
}
}
private static String getSourceIdForDB(PerfLogData perfLogData) {
// sourceId (Tokenize the requestId - GUID)
String guid = perfLogData.getGuid();
if (guid != null && guid.length()>37) {
return guid.substring(0,guid.length()-37);
}
else
return null;
}
/**
* @param perfLogDataJSONObj
* @return int value indicating whether the database insert is SUCCESS/FAILURE
*/
public static int write(PerfLogData perfLogData) throws Exception
{
long inserPerfDBRecordStartTime = System.currentTimeMillis();
Connection connection = null;
String query = null;
PreparedStatement preparedStatement = null;
int statusIndicator = 0 ;
connection = getConnection(perfDBDS);
if(connection!=null)
{
query = "INSERT INTO PERF_LOG(TXN_DT,TXN_START,TXN_START_MS, HOST_NAME,INSTANCE_NAME,TXN_TYPE,USER_ID,TXN_NAME,SUB_TXN_NAME," +
"TXN_CLASS,TXN_TIME_MS,INFO_CONTEXT,REQUEST_GUID,REQUEST_SESSION_ID,REQUEST_GUID_SOURCE,HOST_IP,THREAD_NAME,THREAD_ID,TXN_STATUS,JVM_DEPTH,TXN_FILTER_DEPTH)" +
"VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
try
{
connection.setAutoCommit(true);
preparedStatement = connection.prepareStatement(query);
java.util.Calendar cal = Calendar.getInstance();
preparedStatement.setDate(1,new java.sql.Date(cal.getTime().getTime()));
preparedStatement.setTimestamp(2,new java.sql.Timestamp(perfLogData.getTransactionDate().getTime()));
preparedStatement.setLong(3,perfLogData.getTransactionDate().getTime());
preparedStatement.setString(4,StringUtils.truncateString(perfLogData.getServerName(),255));
preparedStatement.setString(5,StringUtils.truncateString(perfLogData.getCloneName(),255));
preparedStatement.setString(6,StringUtils.truncateString(perfLogData.getTransactionType(),255));
preparedStatement.setString(7,StringUtils.truncateString(perfLogData.getUserId(),255));
preparedStatement.setString(8,StringUtils.truncateString(perfLogData.getTransactionName(),255));
preparedStatement.setString(9,StringUtils.truncateString(perfLogData.getSubTransactionName(),255));
preparedStatement.setString(10,StringUtils.truncateString(perfLogData.getTransactionClass(),255));
preparedStatement.setLong(11,perfLogData.getTransactionTime());
preparedStatement.setString(12,StringUtils.truncateString(perfLogData.getInfoContextString(), 2048));
preparedStatement.setString(13,StringUtils.truncateString(perfLogData.getGuid(),255));
preparedStatement.setString(14,StringUtils.truncateString(perfLogData.getSessionId(),255));
preparedStatement.setString(15,StringUtils.truncateString(getSourceIdForDB(perfLogData),255));
preparedStatement.setString(16,StringUtils.truncateString(perfLogData.getServerIp(),64));
preparedStatement.setString(17,StringUtils.truncateString(perfLogData.getThreadName(),255));
preparedStatement.setString(18,StringUtils.truncateString(perfLogData.getThreadId(),255));
preparedStatement.setString(19,StringUtils.truncateString(getTransactionStatus(perfLogData),255));
preparedStatement.setInt(20,perfLogData.getJvmDepth());
preparedStatement.setInt(21,perfLogData.getTxnFilterDepth());
statusIndicator = preparedStatement.executeUpdate();
} catch (SQLException sqlException)
{
logger.error("SQL Exception occured: " + sqlException.getMessage());
throw sqlException;
} finally {
try {
if (preparedStatement != null)
preparedStatement.close();
// Close the SQL connection
if (connection != null)
connection.close();
}
catch (SQLException sqlException) {
logger.error("SQL Exception occured: "
+ sqlException.getMessage());
}
}
if (statusIndicator == 1) {
logger.debug("Succesfully inserted DB record in to the PERF_LOG table");
} else {
logger.error("Failed to insert DB record in to the PERF_LOG table");
}
logger.debug("insertPerfDBRecord ElapsedTime :"
+ (System.currentTimeMillis() - inserPerfDBRecordStartTime)
+ "(ms)");
}
else {
logger.error("DB connection == null");
}
return statusIndicator;
}
/**
* This method will return the JDBC connection as specified in the JNDI context
* @param jndi
* @return a instance of java.sql.Connection
*/
private static Connection getConnection(String jndi) throws Exception
{
Connection con = null;
if(ctx!=null && ds!=null) {
try {
con = ds.getConnection();
}
catch ( SQLException sqlException )
{
logger.error("SQL Exception occured: "+sqlException.getMessage());
throw sqlException;
}
}
return con;
}
public static void setDbWriterEnabled(boolean dbWriterEnabled) {
DBWriter.dbWriterEnabled = dbWriterEnabled;
}
/**
* @return the dbWriterEnabled
*/
public static boolean isDbWriterEnabled() {
String propertyValue = tunableProperties.getDynamicProperty(LOGGER_DBWRITER_DB_WRITE_ENABLED);
if(propertyValue != null) {
return new Boolean(propertyValue).booleanValue();
}
else
return dbWriterEnabled;
}
}