由于认识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
参考文档:
BTrace使用总结(江南白衣)