前阵子看了公司网站的一个cache 命中率统计的btrace监控脚本,感觉这个玩意功能挺强大,对应用监控有很大实践意义。也顺便把btrace简单学习了一下,未涉及原理方面的内容,只是使用层面的东西,简单笔记总结一下。
Linux下:
在http://kenai.com/projects/btrace下载btrace-bin.tar.gz,并解压,设置环境变量:
export BTRACE_HOME=/home/yblin/workspace/btrace/btrace-bin export PATH=$BTRACE_HOME/bin:$PATH
敲入btrace命令看到提示,说明安装正常。
是一个安全动态的监控工具。通过动态的修改运行时的java字节码,可以在运行时代码中插入监控行为。
探测点 (probe point):用于表示需要被探测监控的位置或者事件。
探测行为 (action):探测点触发时进行的探测行为。如计时等等。
探测方法 (method):当探测点触发的时候,需要触发的探测行为所定义在的那个方法。
Btrace代码结构(1.2之后static可以去掉 )
//annotation defined here public static void trace(){ //actions defined here }
注:以上是一个探测方法,方法的注解annotation用来指示探测点,即要探测的位置;方法体的内容,是探测点触发之后的探测行为。
以下是一个例子:
待测试代码:
package btrace.test; public class MyBtraceTest { public void execute() { int i = (int) (Math.random() * 1000); System.out.println(i); try { Thread.sleep(Math.abs(i)); } catch (InterruptedException e) { e.printStackTrace(); } } public void loopExcute() { while (true) { execute(); } } public static void main(String[] args) { MyBtraceTest m = new MyBtraceTest(); m.loopExcute(); } }
要测试待测代码里excute方法的执行时间,并每次打出方法栈,监控代码如下:
package btrace.test; import static com.sun.btrace.BTraceUtils.jstack; import static com.sun.btrace.BTraceUtils.println; import static com.sun.btrace.BTraceUtils.str; import static com.sun.btrace.BTraceUtils.strcat; import static com.sun.btrace.BTraceUtils.timeMillis; 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.TLS; @BTrace public class TraceMethodTime { @TLS static long beginTime; @OnMethod(clazz = "btrace.test.MyBtraceTest", method = "execute") public static void traceExecuteBegin() {// 在方法btrace.test.MyBtraceTest.execute()执行之前进行监控。 println("method start!"); beginTime = timeMillis(); // 监控行为是记录一个开始时间。 } // OnMethod代表运行一个方法的时候进行监控,location @Location(Kind.RETURN)代表在方法返回的时候触发监控行为。 @OnMethod(clazz = "btrace.test.MyBtraceTest", method = "execute", location = @Location(Kind.RETURN)) public static void traceExcute() { // 监控行为是根据开始时间计算出方法运行时间。 println(strcat(strcat("btrace.test.MyBtraceTest.execute time is:", str(timeMillis() - beginTime)), "ms")); println("method end!"); jstack();//打印方法栈 } }
先运行 MyBtraceTest,通过jps拿到进程id,再通过
btrace 11059 btrace/test/TraceMethodTime.java
命令进行监控。可以得到结果:
Btrace的注解方式有很多,意义各不同,同时也有很多现成例子,能帮助实现各种监控场景。
参考官网:http://kenai.com/projects/btrace/pages/UserGuide