mirror of
https://github.com/wahyd4/pinpoint.git
synced 2026-08-16 16:28:48 +10:00
git-svn-id: http://svn.bds.nhncorp.com/pe/hippo-tomcat-profiler/trunk@1113 84d0f5b1-2673-498c-a247-62c4ff18d310
127 lines
4.2 KiB
Java
127 lines
4.2 KiB
Java
package com.profiler;
|
|
|
|
import java.lang.instrument.ClassFileTransformer;
|
|
import java.lang.instrument.IllegalClassFormatException;
|
|
import java.lang.instrument.Instrumentation;
|
|
import java.security.ProtectionDomain;
|
|
import java.util.logging.Level;
|
|
import java.util.logging.Logger;
|
|
|
|
import com.profiler.config.ProfilerConfig;
|
|
import com.profiler.interceptor.bci.ByteCodeInstrumentor;
|
|
import com.profiler.interceptor.bci.JavaAssistByteCodeInstrumentor;
|
|
import com.profiler.modifier.DefaultModifierRegistry;
|
|
import com.profiler.modifier.Modifier;
|
|
import com.profiler.modifier.ModifierRegistry;
|
|
|
|
public class TomcatProfiler implements ClassFileTransformer {
|
|
|
|
private static final Logger logger = Logger.getLogger(TomcatProfiler.class.getName());
|
|
|
|
private String agentArgString = "";
|
|
|
|
private Instrumentation instrumentation;
|
|
private final ByteCodeInstrumentor byteCodeInstrumentor;
|
|
|
|
private final ModifierRegistry modifierRepository;
|
|
|
|
private final ProfilerConfig profilerConfig;
|
|
private final Agent agent;
|
|
|
|
public static void premain(String agentArgs, Instrumentation instrumentation) {
|
|
try {
|
|
ProfilerConfig profilerConfig = new ProfilerConfig();
|
|
profilerConfig.readConfigFile();
|
|
if (!profilerConfig.isProfileEnable()) {
|
|
logger.warning("Profiler Agent not started. PROFILE_ENABLE=" + profilerConfig.isProfileEnable());
|
|
return;
|
|
}
|
|
Agent agent = new Agent(profilerConfig);
|
|
new TomcatProfiler(agentArgs, instrumentation, agent, profilerConfig);
|
|
} catch (Exception e) {
|
|
logger.log(Level.SEVERE, "Profiler Agent start fail. Cause:" + e.getMessage(), e);
|
|
}
|
|
}
|
|
|
|
public TomcatProfiler(String agentArgs, Instrumentation instrumentation, Agent agent, ProfilerConfig profilerConfig) {
|
|
this.agentArgString = agentArgs;
|
|
this.profilerConfig = profilerConfig;
|
|
this.agent = agent;
|
|
|
|
this.instrumentation = instrumentation;
|
|
this.instrumentation.addTransformer(this);
|
|
|
|
String[] paths = getTomcatlibPath();
|
|
this.byteCodeInstrumentor = new JavaAssistByteCodeInstrumentor(paths);
|
|
|
|
this.modifierRepository = createModifierRegistry();
|
|
}
|
|
|
|
private String[] getTomcatlibPath() {
|
|
String catalinaHome = System.getProperty("catalina.home");
|
|
|
|
if (catalinaHome == null) {
|
|
logger.info("CATALINA_HOME is null");
|
|
return null;
|
|
}
|
|
|
|
if (logger.isLoggable(Level.INFO)) {
|
|
logger.info("CATALINA_HOME=" + catalinaHome);
|
|
}
|
|
|
|
// TODO This is draft. How can we support both Tomcat and BLOC without this configuration?
|
|
String type = System.getProperty("hippo.servertype", "tomcat");
|
|
|
|
if (type.equals("bloc")) {
|
|
return new String[] { catalinaHome + "/server/lib/catalina.jar", catalinaHome + "/common/lib/servlet-api.jar" };
|
|
} else {
|
|
return new String[] { catalinaHome + "/lib/servlet-api.jar", catalinaHome + "/lib/catalina.jar" };
|
|
}
|
|
}
|
|
|
|
private ModifierRegistry createModifierRegistry() {
|
|
DefaultModifierRegistry modifierRepository = new DefaultModifierRegistry(byteCodeInstrumentor, agent, profilerConfig);
|
|
|
|
modifierRepository.addDummyModifier();
|
|
|
|
modifierRepository.addTomcatModifier();
|
|
|
|
// jdbc
|
|
modifierRepository.addJdbcModifier();
|
|
|
|
// rpc
|
|
modifierRepository.addConnectorModifier();
|
|
|
|
// bloc
|
|
modifierRepository.addBLOCModifier();
|
|
|
|
return modifierRepository;
|
|
}
|
|
|
|
@Override
|
|
public byte[] transform(ClassLoader classLoader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classFileBuffer) throws IllegalClassFormatException {
|
|
// fast java class skip
|
|
if (className.startsWith("java")) {
|
|
if (className.startsWith("/", 4) || className.startsWith("x/", 4)) {
|
|
return classFileBuffer;
|
|
}
|
|
}
|
|
Modifier findModifier = this.modifierRepository.findModifier(className);
|
|
if (findModifier == null) {
|
|
findModifier = this.modifierRepository.findModifier("*");
|
|
// return null;
|
|
}
|
|
if (logger.isLoggable(Level.FINE)) {
|
|
logger.fine("[transform] cl" + classLoader + " className:" + className + " Modifier:" + findModifier.getClass().getName());
|
|
}
|
|
String javassistClassName = className.replace('/', '.');
|
|
|
|
try {
|
|
return findModifier.modify(classLoader, javassistClassName, protectionDomain, classFileBuffer);
|
|
} catch (Exception e) {
|
|
logger.log(Level.SEVERE, "Modifier:" + findModifier.getTargetClass() + " modify fail. Cause:" + e.getMessage(), e);
|
|
return null;
|
|
}
|
|
}
|
|
}
|