Files
pinpoint/src/main/java/com/profiler/ClassFileTransformerDispatcher.java
T

93 lines
3.1 KiB
Java

package com.profiler;
import com.profiler.config.ProfilerConfig;
import com.profiler.modifier.DefaultModifierRegistry;
import com.profiler.modifier.Modifier;
import com.profiler.modifier.ModifierRegistry;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
*/
public class ClassFileTransformerDispatcher implements ClassFileTransformer {
private Logger logger = Logger.getLogger(this.getClass().getName());
private boolean isFine = logger.isLoggable(Level.FINE);
private ModifierRegistry modifierRegistry;
private Agent agent;
private ProfilerConfig profilerConfig;
public ClassFileTransformerDispatcher(Agent agent) {
if(agent == null) {
throw new NullPointerException("agent must not be null");
}
this.agent = agent;
this.profilerConfig = agent.getProfilerConfig();
this.modifierRegistry = createModifierRegistry();
}
@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.modifierRegistry.findModifier(className);
if (findModifier == null) {
// TODO : 디버그 용도로 추가함
// TODO : modifier가 중복 적용되면 어떻게 되지???
if (this.profilerConfig.isProfilableClass(className)) {
// 테스트 장비에서 callstack view가 잘 보이는지 확인하려고 추가함.
findModifier = this.modifierRegistry.findModifier("*");
} else {
return null;
}
}
if (isFine) {
logger.fine("[transform] cl" + classLoader + " className:" + className + " Modifier:" + findModifier.getClass().getName());
}
String javassistClassName = className.replace('/', '.');
try {
return findModifier.modify(classLoader, javassistClassName, protectionDomain, classFileBuffer);
} catch (Throwable e) {
logger.log(Level.SEVERE, "Modifier:" + findModifier.getTargetClass() + " modify fail. Cause:" + e.getMessage(), e);
return null;
}
}
private ModifierRegistry createModifierRegistry() {
DefaultModifierRegistry modifierRepository = new DefaultModifierRegistry(agent);
modifierRepository.addMethodModifier();
modifierRepository.addTomcatModifier();
// jdbc
modifierRepository.addJdbcModifier();
// rpc
modifierRepository.addConnectorModifier();
// bloc
modifierRepository.addBLOCModifier();
return modifierRepository;
}
}