偶然间从一个blog上看到这个项目,于是就花时间看了看,真的值得一试.
优点比较明显,总结了几个自己适用的:
1.直接使用,无需重启需要监听的进程。
下载btrace,解压,写监控类, 然后获取需要监控程序的pid进程号,运行bin/btrace <pid> HelloWorld.java ,就这么简单一气呵成。 即时启用,即时关闭。
e.g(每次进程start()都会打印一条消息)
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
// @BTrace annotation tells that this is a BTrace program
@BTrace
class HelloWorld {
@OnMethod(
clazz="java.lang.Thread",
method="start"
)
void func() {
sharedMethod("msg start Thread");
}
void sharedMethod(String msg) {
println(msg);
}}
2.对现有程序的性能干扰不大!!
首先是基于字节码的技术,这个很多框架,包括自己都能够实现。但是,Btrace的精髓还在于,使用c++的模式实现了一些更高效的Util方法,比如: 计时的timeMillis, 字符串函数 strcat,
println(strcat("VerifyInterceptor Timetaken(msec) ", str(timeMillis() - startTime)))
另外,在btrace的监控代码里面,严格限制了任何干扰监控对象程序的java代码。比如创建新对象、抛异常,捕获异常,甚至是使用System.currentTimeMillis()这样的java计时函数都是不可以的。
3.切面灵活
厌倦了检测整个函数的执行时间么?(必须的,因为函数会有嵌套调用关系,有时候只期望能检测函数的某一段代码执行时间)
那么下面这个例子就比较爽了: 检测VerifyInterceptor.intercept()函数开始,到代码的262行(也就是intercept函数中的某一处),执行时间。
// import BTrace annotations
import com.sun.btrace.annotations.*;
// import logging methods
import static com.sun.btrace.BTraceUtils.*;
@BTrace public class Tracker {
@TLS private static long startTime;
@OnMethod(
clazz="com.xxr.VerifyInterceptor",
method="intercept"
)
public static void onbefore() {
startTime = timeMillis();
}
@OnMethod(
clazz="com.xxr.VerifyInterceptor",
method="intercept",
//location=@Location(Kind.RETURN)
location=@Location(value=Kind.LINE, line=262)
)
public static void onreturn() {
println(strcat("VerifyInterceptor Timetaken(msec) ", str(timeMillis() - startTime)));
//println("==========================");
}
}
btrace还可以做很多事情,比如监控Annotation,做定时器的检测,输出jstack,jmap.mem,乃至socket,以及将自己暴露成一个JMX bean,远程管理。