由于认识JAVA代码热更新在先,所以Btrace这一神器似乎失去了一些光芒,但他的优势是无任何侵入性,可以做一些代码热更新没法做的事情,做到两者互补。
比如
1 可以直接运行java文件,少了一步编译,更可以在线上直接修改代码
2.可以独立的打印到单独的文件中
3.想进第三方jar包里的方法里方法内的数据track,
4.输入和返回数据track
5.内存不够时的track
6.异常未有捕获时的track
Kind.Error, Kind.Throw和 Kind.Catch
Throw:异常抛出,Catch:异常被捕获,Error:异常没被捕获而被抛出函数之外,主要用于对某些异常情况的跟踪。
缺点:
1.BTrace植入过的代码,会一直在,直到应用重启为止。所以即使BTrace退出了,业务函数每次执行时都会多出一次BTrace是否Attach状态的判断。
2.必须到相关java进程所在的机器上去执行,不能远程执行
1.如何解除安全限制:
只能调用BTraceUtils 里的一系列方法和脚本里定义的static方法,不允许其他调用任何类的任何方法。 比如不允许创建对象,比如不允许For 循环等等
但我们其实很需要调用第三方包,自己写的类,所以如何突破限制呢?
命令行加 -u,BTrace类的头加上@BTrace(trusted=true)
2.如何引用第三方包:
-cp .:game-common.jar:game-data-1.0.0-RELEASE.jar
每个jar包都要显式的列出来,这个有点笨,不能直接指向一个目录?有什么更好的办法请告之。
3.打印到单独的文件,并可以一直tracer
./btrace -cp .:game-common.jar:game-data-1.0.0-RELEASE.jar -u -v 15659 HelloWorld.java > btrace.log 2>&1 &
package com.sun.btrace.samples; import static com.sun.btrace.BTraceUtils.println; import com.imi.common.id.ServerObject; import com.imi.common.util.StringUtil; import com.sun.btrace.BTraceUtils; import com.sun.btrace.annotations.BTrace; import com.sun.btrace.annotations.Duration; import com.sun.btrace.annotations.Kind; import com.sun.btrace.annotations.Location; import com.sun.btrace.annotations.OnMethod; import com.sun.btrace.annotations.Return; import com.sun.btrace.annotations.Self; @BTrace(trusted=true) public class HelloWorld { @OnMethod(clazz = "com.imi.gate.action.UserAction", method = "login", location = @Location(value = Kind.RETURN)) public static void onUserAction_login(@Return Void value, @Duration long duration) { println("interval:" + duration / 1000000); } @OnMethod(clazz = "com.imi.common.id.ServerObject", method = "newId", location = @Location(value = Kind.ENTRY)) public static void onnewId(@Self ServerObject value) { { println(StringUtil.format("id={}", value.getId())); if(value.getId()>0){ BTraceUtils.jstack(); } } } }
BTrace是神器,每一个需要每天解决线上问题,但完全不用BTrace的Java工程师,都是可疑的 -- 凯尔文. 萧
下载地址:
http://github.com/btraceio/btrace
参考文档: