mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-18 01:06:03 +10:00
[강운덕] [LUCYSUS-1744] modifier 등록 지점 구현.
git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@466 84d0f5b1-2673-498c-a247-62c4ff18d310
This commit is contained in:
@@ -7,7 +7,9 @@ import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.security.ProtectionDomain;
|
||||
|
||||
import com.profiler.modifier.DefaultModifierRegistry;
|
||||
import com.profiler.modifier.Modifier;
|
||||
import com.profiler.modifier.ModifierRegistry;
|
||||
import javassist.ClassPool;
|
||||
import javassist.NotFoundException;
|
||||
|
||||
@@ -42,19 +44,34 @@ public class TomcatProfiler implements ClassFileTransformer {
|
||||
private Instrumentation instrumentation;
|
||||
private ClassPool classPool;
|
||||
|
||||
|
||||
private final ModifierRegistry modifierRepository;
|
||||
private TomcatProfilerConfig tomcatProfilerConfig;
|
||||
|
||||
public static void premain(String agentArgs, Instrumentation inst) {
|
||||
new TomcatProfiler(agentArgs, inst);
|
||||
TomcatProfilerConfig tomcatProfilerConfig = TomcatProfilerConfig.readConfigFile();
|
||||
new TomcatProfiler(agentArgs, inst, tomcatProfilerConfig);
|
||||
}
|
||||
|
||||
public TomcatProfiler(String agentArgs, Instrumentation inst) {
|
||||
public TomcatProfiler(String agentArgs, Instrumentation inst, TomcatProfilerConfig tomcatProfilerConfig) {
|
||||
this.agentArgString = agentArgs;
|
||||
this.instrumentation = inst;
|
||||
this.instrumentation.addTransformer(this);
|
||||
this.classPool = createClassPool();
|
||||
this.modifierRepository = createModifierRegistry(tomcatProfilerConfig);
|
||||
this.tomcatProfilerConfig = tomcatProfilerConfig;
|
||||
|
||||
|
||||
}
|
||||
|
||||
private ModifierRegistry createModifierRegistry(TomcatProfilerConfig tomcatProfilerConfig) {
|
||||
DefaultModifierRegistry modifierRepository = new DefaultModifierRegistry();
|
||||
modifierRepository.addTomcatModifier();
|
||||
if(tomcatProfilerConfig.enableJdbcProfile()) {
|
||||
modifierRepository.addJdbcModifier();
|
||||
}
|
||||
return modifierRepository;
|
||||
}
|
||||
|
||||
private ClassPool createClassPool() {
|
||||
ClassPool classPool = new ClassPool(null);
|
||||
classPool.appendSystemPath();
|
||||
@@ -76,7 +93,13 @@ public class TomcatProfiler implements ClassFileTransformer {
|
||||
|
||||
@Override
|
||||
public byte[] transform(ClassLoader classLoader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classFileBuffer) throws IllegalClassFormatException {
|
||||
if (className.startsWith("org/apache/catalina")) {
|
||||
Modifier findModifier = this.modifierRepository.findModifier(className);
|
||||
if(findModifier != null) {
|
||||
String javassistClassName = className.replace('/', '.');
|
||||
return findModifier.modify(classPool, classLoader, javassistClassName, classFileBuffer);
|
||||
}
|
||||
|
||||
if (className.startsWith("org/apache/catalina")) {
|
||||
String javassistClassName = className.replace('/', '.');
|
||||
if (javassistClassName.equals("org.apache.catalina.core.StandardHostValve")) {
|
||||
// Add code to monitor Request and Response
|
||||
@@ -99,7 +122,7 @@ public class TomcatProfiler implements ClassFileTransformer {
|
||||
}
|
||||
}
|
||||
// #### If JDBC_PROFILE is true, SQL data will be collected
|
||||
if (TomcatProfilerConfig.JDBC_PROFILE) {
|
||||
if (tomcatProfilerConfig.enableJdbcProfile()) {
|
||||
if (className.startsWith("com/mysql/jdbc")) {
|
||||
// MySQL !!!!!!!!!!
|
||||
String javassistClassName = className.replace('/', '.');
|
||||
@@ -256,7 +279,7 @@ public class TomcatProfiler implements ClassFileTransformer {
|
||||
try {
|
||||
classPool.appendClassPath(filePath);
|
||||
// log("Loaded "+filePath+" library.");
|
||||
} catch (Exception e) {
|
||||
} catch (NotFoundException e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,110 +2,131 @@ package com.profiler.config;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.profiler.TomcatProfiler;
|
||||
import com.profiler.logging.LogLevel;
|
||||
import com.profiler.logging.Logger;
|
||||
|
||||
public class TomcatProfilerConfig {
|
||||
|
||||
private static final Logger logger = Logger.getLogger(TomcatProfilerConfig.class);
|
||||
private static final Logger logger = Logger.getLogger(TomcatProfilerConfig.class);
|
||||
|
||||
public static String SERVER_IP = "127.0.0.1";
|
||||
public static String SERVER_IP = "127.0.0.1";
|
||||
|
||||
public static int AGENT_TCP_LISTEN_PORT = 9990;
|
||||
public static int SERVER_TCP_LISTEN_PORT = 9991;
|
||||
public static int REQUEST_TRANSACTION_DATA_LISTEN_PORT = 9995;
|
||||
public static int REQUEST_DATA_LISTEN_PORT = 9996;
|
||||
public static int JVM_DATA_LISTEN_PORT = 9997;
|
||||
public static int AGENT_TCP_LISTEN_PORT = 9990;
|
||||
public static int SERVER_TCP_LISTEN_PORT = 9991;
|
||||
public static int REQUEST_TRANSACTION_DATA_LISTEN_PORT = 9995;
|
||||
public static int REQUEST_DATA_LISTEN_PORT = 9996;
|
||||
public static int JVM_DATA_LISTEN_PORT = 9997;
|
||||
|
||||
public static long JVM_STAT_GAP = 5000L;
|
||||
public static long SERVER_CONNECT_RETRY_GAP = 1000L;
|
||||
public static long JVM_STAT_GAP = 5000L;
|
||||
public static long SERVER_CONNECT_RETRY_GAP = 1000L;
|
||||
|
||||
public static LogLevel LOG_LEVEL = LogLevel.INFO;
|
||||
public static LogLevel LOG_LEVEL = LogLevel.INFO;
|
||||
|
||||
/**
|
||||
* If sql query count is over 10000 it consumes Memory. So sqlHashSet uses
|
||||
* CopyOnWriteArraySet. It is slow, but it is stable. Default set is false
|
||||
* and it uses HashSet.
|
||||
*/
|
||||
public static boolean QUERY_COUNT_OVER_10000 = false;
|
||||
public static boolean JDBC_PROFILE = true;
|
||||
/**
|
||||
* If sql query count is over 10000 it consumes Memory. So sqlHashSet uses
|
||||
* CopyOnWriteArraySet. It is slow, but it is stable. Default set is false
|
||||
* and it uses HashSet.
|
||||
*/
|
||||
public static boolean QUERY_COUNT_OVER_10000 = false;
|
||||
|
||||
static {
|
||||
readConfigFile();
|
||||
}
|
||||
private boolean JDBC_PROFILE = true;
|
||||
|
||||
public static void readConfigFile() {
|
||||
String hippoConfigFileName = System.getProperty("hippo.config");
|
||||
public static TomcatProfilerConfig readConfigFile() {
|
||||
TomcatProfilerConfig config = new TomcatProfilerConfig();
|
||||
|
||||
if (hippoConfigFileName != null) {
|
||||
Properties prop = new Properties();
|
||||
try {
|
||||
FileReader reader = new FileReader(hippoConfigFileName);
|
||||
prop.load(reader);
|
||||
reader.close();
|
||||
setPropertyValues(prop);
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
logger.error("%s file is not exists. Please check configuration.", hippoConfigFileName);
|
||||
} catch (Exception e) {
|
||||
logger.fatal(e.getMessage());
|
||||
}
|
||||
} else {
|
||||
logger.warn("hippo.config property is not set. Using default values");
|
||||
}
|
||||
}
|
||||
String hippoConfigFileName = System.getProperty("hippo.config");
|
||||
if (hippoConfigFileName == null) {
|
||||
logger.warn("hippo.config property is not set. Using default values");
|
||||
return config;
|
||||
}
|
||||
|
||||
private static void setPropertyValues(Properties prop) {
|
||||
// TODO : use Properties defaultvalue instead of using temp variable.
|
||||
try {
|
||||
Properties properties = readProperties(hippoConfigFileName);
|
||||
setPropertyValues(config, properties);
|
||||
return config;
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
logger.error("%s file is not exists. Please check configuration.", hippoConfigFileName);
|
||||
} catch (Exception e) {
|
||||
logger.fatal(e.getMessage());
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
Object temp = null;
|
||||
private static Properties readProperties(String propertyName) throws FileNotFoundException, IOException {
|
||||
FileReader reader = null;
|
||||
try {
|
||||
Properties prop = new Properties();
|
||||
reader = new FileReader(propertyName);
|
||||
prop.load(reader);
|
||||
return prop;
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((temp = prop.get("SERVER_IP")) != null) {
|
||||
SERVER_IP = temp.toString();
|
||||
logger.info("SERVER_IP=%s", SERVER_IP);
|
||||
}
|
||||
if ((temp = prop.get("AGENT_TCP_LISTEN_PORT")) != null) {
|
||||
AGENT_TCP_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("AGENT_TCP_LISTEN_PORT=%d", AGENT_TCP_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("SERVER_TCP_LISTEN_PORT")) != null) {
|
||||
SERVER_TCP_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("SERVER_TCP_LISTEN_PORT=%d", SERVER_TCP_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("REQUEST_TRANSACTION_DATA_LISTEN_PORT")) != null) {
|
||||
REQUEST_TRANSACTION_DATA_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("REQUEST_TRANSACTION_DATA_LISTEN_PORT=%d", REQUEST_TRANSACTION_DATA_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("REQUEST_DATA_LISTEN_PORT")) != null) {
|
||||
REQUEST_DATA_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("REQUEST_DATA_LISTEN_PORT=%d", REQUEST_DATA_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("JVM_DATA_LISTEN_PORT")) != null) {
|
||||
JVM_DATA_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("JVM_DATA_LISTEN_PORT=%d", JVM_DATA_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("JVM_STAT_GAP")) != null) {
|
||||
JVM_STAT_GAP = Long.parseLong(temp.toString());
|
||||
logger.info("JVM_STAT_GAP=%d", JVM_STAT_GAP);
|
||||
}
|
||||
if ((temp = prop.get("SERVER_CONNECT_RETRY_GAP")) != null) {
|
||||
SERVER_CONNECT_RETRY_GAP = Long.parseLong(temp.toString());
|
||||
logger.info("SERVER_CONNECT_RETRY_GAP=%d", SERVER_CONNECT_RETRY_GAP);
|
||||
}
|
||||
if ((temp = prop.get("QUERY_COUNT_OVER_10000")) != null) {
|
||||
QUERY_COUNT_OVER_10000 = Boolean.parseBoolean(temp.toString());
|
||||
logger.info("QUERY_COUNT_OVER_10000=%s", QUERY_COUNT_OVER_10000);
|
||||
}
|
||||
if ((temp = prop.get("JDBC_PROFILE")) != null) {
|
||||
JDBC_PROFILE = Boolean.parseBoolean(temp.toString());
|
||||
logger.info("JDBC_PROFILE=%s", JDBC_PROFILE);
|
||||
}
|
||||
if ((temp = prop.get("LOG_LEVEL")) != null) {
|
||||
LOG_LEVEL = LogLevel.valueOf(temp.toString());
|
||||
logger.info("LOG_LEVEL=%s", LOG_LEVEL);
|
||||
}
|
||||
public boolean enableJdbcProfile() {
|
||||
return JDBC_PROFILE;
|
||||
}
|
||||
|
||||
logger.info("configuration loaded successfully.");
|
||||
}
|
||||
private static void setPropertyValues(TomcatProfilerConfig config, Properties prop) {
|
||||
// TODO : use Properties defaultvalue instead of using temp variable.
|
||||
|
||||
Object temp = null;
|
||||
|
||||
if ((temp = prop.get("SERVER_IP")) != null) {
|
||||
config.SERVER_IP = temp.toString();
|
||||
logger.info("SERVER_IP=%s", SERVER_IP);
|
||||
}
|
||||
if ((temp = prop.get("AGENT_TCP_LISTEN_PORT")) != null) {
|
||||
config.AGENT_TCP_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("AGENT_TCP_LISTEN_PORT=%d", AGENT_TCP_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("SERVER_TCP_LISTEN_PORT")) != null) {
|
||||
config.SERVER_TCP_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("SERVER_TCP_LISTEN_PORT=%d", SERVER_TCP_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("REQUEST_TRANSACTION_DATA_LISTEN_PORT")) != null) {
|
||||
config.REQUEST_TRANSACTION_DATA_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("REQUEST_TRANSACTION_DATA_LISTEN_PORT=%d", REQUEST_TRANSACTION_DATA_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("REQUEST_DATA_LISTEN_PORT")) != null) {
|
||||
config.REQUEST_DATA_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("REQUEST_DATA_LISTEN_PORT=%d", REQUEST_DATA_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("JVM_DATA_LISTEN_PORT")) != null) {
|
||||
config.JVM_DATA_LISTEN_PORT = Integer.parseInt(temp.toString());
|
||||
logger.info("JVM_DATA_LISTEN_PORT=%d", JVM_DATA_LISTEN_PORT);
|
||||
}
|
||||
if ((temp = prop.get("JVM_STAT_GAP")) != null) {
|
||||
config.JVM_STAT_GAP = Long.parseLong(temp.toString());
|
||||
logger.info("JVM_STAT_GAP=%d", JVM_STAT_GAP);
|
||||
}
|
||||
if ((temp = prop.get("SERVER_CONNECT_RETRY_GAP")) != null) {
|
||||
config.SERVER_CONNECT_RETRY_GAP = Long.parseLong(temp.toString());
|
||||
logger.info("SERVER_CONNECT_RETRY_GAP=%d", SERVER_CONNECT_RETRY_GAP);
|
||||
}
|
||||
if ((temp = prop.get("QUERY_COUNT_OVER_10000")) != null) {
|
||||
config.QUERY_COUNT_OVER_10000 = Boolean.parseBoolean(temp.toString());
|
||||
logger.info("QUERY_COUNT_OVER_10000=%s", QUERY_COUNT_OVER_10000);
|
||||
}
|
||||
if ((temp = prop.get("JDBC_PROFILE")) != null) {
|
||||
config.JDBC_PROFILE = Boolean.parseBoolean(temp.toString());
|
||||
logger.info("JDBC_PROFILE=%s", config.JDBC_PROFILE);
|
||||
}
|
||||
if ((temp = prop.get("LOG_LEVEL")) != null) {
|
||||
config.LOG_LEVEL = LogLevel.valueOf(temp.toString());
|
||||
logger.info("LOG_LEVEL=%s", LOG_LEVEL);
|
||||
}
|
||||
|
||||
logger.info("configuration loaded successfully.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.profiler.modifier;
|
||||
|
||||
import com.profiler.modifier.tomcat.EntryPointStandardHostValveModifier;
|
||||
import com.profiler.modifier.tomcat.TomcatConnectorModifier;
|
||||
import com.profiler.modifier.tomcat.TomcatStandardServiceModifier;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class DefaultModifierRegistry implements ModifierRegistry {
|
||||
// TODO 혹시 동시성을 고려 해야 되는지 검토.
|
||||
private Map<String, Modifier> registry = new HashMap<String, Modifier>();
|
||||
|
||||
|
||||
private List<String> packageIncludeFilters = new ArrayList<String>();
|
||||
|
||||
@Override
|
||||
public Modifier findModifier(String className) {
|
||||
if(!findPackage(className)) {
|
||||
return null;
|
||||
}
|
||||
return registry.get(className);
|
||||
}
|
||||
|
||||
private boolean findPackage(String className) {
|
||||
for(String filter : packageIncludeFilters) {
|
||||
if(filter.equals(className)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void addTomcatModifier() {
|
||||
packageIncludeFilters.add("org/apache/catalina");
|
||||
|
||||
Map<String, Modifier> registry = this.registry;
|
||||
Modifier entryPointStandardHostValveModifier = new EntryPointStandardHostValveModifier();
|
||||
registry.put("org/apache/catalina/core/StandardHostValve", entryPointStandardHostValveModifier);
|
||||
|
||||
Modifier tomcatStandardServiceModifier = new TomcatStandardServiceModifier();
|
||||
registry.put("org/apache/catalina/core/StandardService", tomcatStandardServiceModifier);
|
||||
|
||||
Modifier tomcatConnectorModifier = new TomcatConnectorModifier();
|
||||
registry.put("org/apache/catalina/connector/Connector", tomcatConnectorModifier);
|
||||
}
|
||||
|
||||
public void addJdbcModifier() {
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.profiler.modifier;
|
||||
|
||||
public interface ModifierRegistry {
|
||||
|
||||
Modifier findModifier(String className);
|
||||
}
|
||||
Reference in New Issue
Block a user