偶然间从一个blog上看到这个项目,于是就花时间看了看,真的值得一试.
优点比较明显,总结了几个自己适用的:
下载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); }}
首先是基于字节码的技术,这个很多框架,包括自己都能够实现。但是,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,远程管理。