Created
April 2, 2015 14:03
-
-
Save felixbarny/e0c64819c59368a28200 to your computer and use it in GitHub Desktop.
ByteBuddyProfiler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.stagemonitor.instrument; | |
import java.lang.instrument.Instrumentation; | |
import java.lang.reflect.Method; | |
import java.util.concurrent.Callable; | |
import net.bytebuddy.agent.builder.AgentBuilder; | |
import net.bytebuddy.dynamic.DynamicType; | |
import net.bytebuddy.instrumentation.MethodDelegation; | |
import net.bytebuddy.instrumentation.method.bytecode.bind.annotation.Origin; | |
import net.bytebuddy.instrumentation.method.bytecode.bind.annotation.RuntimeType; | |
import net.bytebuddy.instrumentation.method.bytecode.bind.annotation.SuperCall; | |
import net.bytebuddy.instrumentation.type.TypeDescription; | |
import net.bytebuddy.matcher.ElementMatcher; | |
import net.bytebuddy.matcher.ElementMatchers; | |
import org.stagemonitor.requestmonitor.profiler.Profiler; | |
public class ByteBuddyProfiler { | |
public static void premain(String agentArgs, Instrumentation inst) { | |
new AgentBuilder.Default() | |
.rebase(new ElementMatcher<TypeDescription>() { | |
@Override | |
public boolean matches(TypeDescription target) { | |
return target.getCanonicalName().startsWith("org.stagemonitor.benchmark.profiler.ClassByteBuddyProfiled"); | |
} | |
}) | |
.transform(new ProfilingTransformer()) | |
.installOn(inst); | |
} | |
private static class ProfilingTransformer implements AgentBuilder.Transformer { | |
@Override | |
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription) { | |
return builder | |
.method(ElementMatchers.any()) | |
.intercept(MethodDelegation.to(ProfilingInterceptor.class)); | |
} | |
} | |
public static class ProfilingInterceptor { | |
@RuntimeType | |
public static Object profile(@Origin String signature, @SuperCall Callable<?> zuper) throws Exception { | |
Profiler.start(signature); | |
try { | |
return zuper.call(); | |
} finally { | |
Profiler.stop(); | |
} | |
} | |
/* | |
Overhead is 4x higher | |
@RuntimeType | |
public static Object profile(@Origin(cacheMethod = true) Method method, @Origin Class clazz, @SuperCall Callable<?> zuper) throws Exception { | |
String signature = getSignature(method, clazz); | |
Profiler.start(signature); | |
try { | |
return zuper.call(); | |
} finally { | |
Profiler.stop(); | |
} | |
}*/ | |
} | |
/** | |
* ReturnType full.qualified.ClassName(ParamType, ParamType2) | |
*/ | |
private static String getSignature(Method method, Class clazz) { | |
StringBuilder signature = new StringBuilder() | |
.append(method.getReturnType().getSimpleName()).append(" ") | |
.append(clazz.getCanonicalName()) | |
.append('.').append(method.getName()) | |
.append("("); | |
Class<?>[] parameterTypes = method.getParameterTypes(); | |
for (int i = 0; i < parameterTypes.length; i++) { | |
Class<?> paramClass = parameterTypes[i]; | |
signature.append(paramClass.getSimpleName()); | |
if (i < parameterTypes.length - 1) { | |
signature.append(' '); | |
} | |
} | |
signature.append(")"); | |
return signature.toString(); | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment