java agent 拦截方法耗时
引入依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<bytebuddy.version>1.12.18</bytebuddy.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>${bytebuddy.version}</version>
</dependency>
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy-agent</artifactId>
<version>${bytebuddy.version}</version>
</dependency>
</dependencies>
采用编译期方式
public class MethodTimeAgent {
private static final String ANNOTATION_REST_CONTROLLER = "org.springframework.web.bind.annotation.RestController";
public static void premain(String agentArgs, Instrumentation inst) {
AgentBuilder.Transformer transformer = (builder, typeDescription, classLoader, javaModule, protectionDomain) -> {
return builder
.method(ElementMatchers.any()) // 拦截任意方法
.intercept(MethodDelegation.to(MethodTimeInterceptor.class)); // 委托
};
new AgentBuilder
.Default()
.type(ElementMatchers.nameStartsWith("com.xx") //类全路径以com.xx开头
.and(ElementMatchers.isAnnotatedWith(ElementMatchers.named(ANNOTATION_REST_CONTROLLER)))) //
// 指定需要拦截的类
.transform(transformer)
.installOn(inst);
}
}
MethodTimeInterceptor 拦截逻辑
public class MethodTimeInterceptor {
@RuntimeType
public static Object intercept(@Origin Method method, @SuperCall Callable<?> callable) throws Exception {
long start = System.nanoTime();
try {
// 原有函数执行
return callable.call();
} finally {
System.out.println(method.getName() + " 方法耗时: " + (System.nanoTime() - start) + "ns");
}
}
}
打包
<build>
<finalName>mybatis-log</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer
implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<manifestEntries>
<!-- 修改为正确的Premain地址 -->
<Premain-Class>org.example.sample.log.SqlLogAgent</Premain-Class>
</manifestEntries>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
打包后,在项目上加上启动参数
-javaagent:D:\xxx\mybatis-log\target\mybatis-log.jar
示例结果:
userList() 方法耗时: 19283600ns