BTrace在解决现场问题的时候非常有用。
1、概述
1.1下载
https://github.com/btraceio/btrace,最新版本是1.3.9
目前1.3.x系列最低支持JDK1.7,要想使用JDK1.6的话,可以下载http://download.csdn.net/detail/ccscu/9899450
1.2开始使用
使用命令:./btrace pid HelloWorld.java
1.3安全限制
默认不支持for循环等,可以使用-u来突破限制
1.4定义classpath
-cp
1.5输出结果到文件
推荐使用重定向而不是-o
1.6预编译脚本
./btractc HelloWorld.java
2、拦截方法定义
1、构造函数的名称是<init>
@OnMethod(clazz="java.util.Timer", method="<init>")
2、内部类的名称是在类名和内部类之间加上$
@OnMethod(clazz="org.apache.struts2.dispatcher.Dispatcher$Locator", method="getLocation")
3、拦截多个同名的函数,可以定义不同的参数列表区分
3、拦截时机
3.1Kind.ENTRY和Kind.RETURN
[email protected](Kind.RETURN)
默认值就是Kind.ENTRY,如果使用AnyType来定义,必须使用Kind.ENTRY,否则会进入一种特殊的静默模式;
如果想获得返回值或者运行时间,必须使用Kind.RETURN。
3.2Kind.THROW
@OnMethod(clazz = "org.apache.coyote.tomcat5.CoyoteResponse", method = "getWriter", location = @Location(Kind.THROW))
4、获取this、参数和返回值
4.1定义注入
@OnMethod(clazz = "java.util.HashMap", method = "put", location = @Location(Kind.RETURN))
public static void onPutMap(@Self Object obj, String key, String value, @Return AnyType result)
参数列表要么不定义,要定义就需要完整,否则BTrace无法处理同名函数;
也可以使用AnyType或者AnyType[]来表示,这个时候必须使用Kind.ENTR,否则会进入一种特殊的静默模式,只要有一个函数打印错了,整个BTrace就什么也打印不出来。
4.2获取对象的属性值
如果是JDK的类
field("java.lang.Thread", "name");
非JDK的类
private static Field response = field(classForName("com.neusoft.unieap.techcomp.ria.action.BaseEntry", contextClassLoader()), "response") ;
Object res = get(response, obj);
这里除了get方法之外,还有getBoolean、getInt等各种基础类型的方法。
5、其他常用API
5.1获取当前线程名称
BTraceUtils.Threads.name(BTraceUtils.currentThread())
5.2获取队形的Hash code
BTraceUtils.identityHashCode(params[1])
5.3获取对象的类名称
BTraceUtils.Reflective.name(BTraceUtils.classOf(obj))
其中BTraceUtils.classOf(obj)返回类,BTraceUtils.Reflective.name返回类名称
在写这篇文章的时候借鉴了以下文章:
1、http://calvin1978.blogcn.com/articles/btrace1.html
江南白衣的文笔一流,他的BTrace的文章架构非常好:我完全模仿了他的结构
2、http://www.bo56.com/btrace示例和资料整理/
学习了如何拿到成员变量的值
3、https://www.gitbook.com/book/json-liu/btrace/details
BTrace的中文使用手册,入门必备