不了解的 BTrace 的可以先看 BTrace 用户指南 。
被跟踪的程序
package net.coderbee.btrace;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author coderbee 2017年5月9日 下午9:50:18
*
*/
public class BtraceObservable {
private AtomicInteger counter = new AtomicInteger();
public String targetMethod(int i) {
try {
Thread.sleep(2000);
if (i % 10 == 0) {
throw new IllegalStateException("测试抛异常状态。");
}
} catch (Exception e) {
e.printStackTrace();
}
return Thread.currentThread().getName() + "--" + i + " returned.";
}
private int tcount() {
return counter.incrementAndGet();
}
/**
* @param args
*/
public static void main(String[] args) {
BtraceObservable observable = new BtraceObservable();
System.err.println(observable);
ExecutorService service = Executors.newFixedThreadPool(2);
service.submit(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 10000; i++) {
int count = observable.tcount();
String string = observable.targetMethod(count);
System.out.println(string);
}
}
});
service.shutdown();
}
}
跟踪脚本
package net.coderbee.btrace;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;
import com.sun.btrace.annotations.Return;
import com.sun.btrace.annotations.Self;
import com.sun.btrace.annotations.TargetInstance;
import com.sun.btrace.annotations.TargetMethodOrField;
@BTrace
public class BtraceScript {
/**
* 可以用正则表达式匹配多个类、多个方法,然后用注解 @ProbeClassName 获得被调用的类, @ProbeMethodName
* 获得被调用的方法。
*
* 注意正则表达式定义
*/
// /java\\.io\\..*Input.*/
@OnMethod(
clazz = "net.coderbee.btrace.BtraceObservable",
method = "/t.*/")
public static void func(@ProbeClassName String className,
@ProbeMethodName String methodName) {
BTraceUtils.println("ProbeClassName:" + className + ", ProbeMethodName:"
+ methodName);
}
/**
* 用 @Return 获取方法的返回值
*/
@OnMethod(
clazz = "net.coderbee.btrace.BtraceObservable",
method = "targetMethod",
location = @Location(Kind.RETURN) )
public static void retVal(@Return String retVal) {
BTraceUtils.println("target method return:" + retVal);
}
/**
* 获取调用对象、被调用对象、调用方法的信息
*/
@OnMethod(clazz = "net.coderbee.btrace.BtraceObservable",
method = "tcount",
location = @Location(value = Kind.CALL, clazz = "/.*/",
method = "/.*/") )
public static void call(@Self Object self, @TargetInstance Object target,
@TargetMethodOrField String method) {
BTraceUtils.println("on call, self:" + self + "\ntarget:" + target
+ ", method:" + method);
}
/**
* 跟踪异常类的初始化。如果 类有多个构造函数,可以重载对应的方法。
*
* @param self
* 新创建的异常
*/
@OnMethod(
clazz = "java.lang.Throwable",
method = "<init>")
public static void onthrow(@Self Throwable self) {
BTraceUtils.println(self);
}
}
欢迎关注我的微信公众号: coderbee笔记,可以更及时回复你的讨论。