BTrace通过在目标程序中植入跟踪代码(字节码跟踪)用于动态跟踪运行中的java程序,而其很安全(因为其做了很多限制)。它能够方便的获取代码中的属性、参数、返回等数据,还能监控JVM线程,loader等,功能很强大,实现成本低,侵入性低,几乎对应用无影响,可以堪称排查问题一利器。
其实现关键是:JavaCompiler API,JVMTI,Instrumentation,asm。
基本用法
btrace[-I<include-path>] [-p<port>][-cp<classpath>]<pid><btrace-script> [<args>]
- include-path -定头文件的路径;
- port指定agent的服务端监听端口号,默认为2020;
- classpath用来指定类加载路径;
- pid表示进程号,可通过jps命令获取;
- btrace-script即为BTrace脚本;btrace脚本如果以.java结尾,会先编译再提交执行。可使用btracec命令对脚本进行预编译。
- args是BTrace脚本可选参数,在脚本中可通过"$"和"$length"获取参数信息。
btracec[-I<include-path>][-cp<classpath>][-d<directory>]<one-or-more-BTrace-.java-files>
用于预编译BTrace脚本,用于在编译时期验证脚本正确性。
btracer<pre-compiled-btrace.class> <application-main-class><application-args>
btracer命令同时启动应用程序和BTrace脚本。
BtraceClient
BtraceClient主要工作:
通过java compileapi将脚本编译成class文件,利用VirturalMachine技术,动态的attach到jvm启动BtraceAgent,同时在本地启动一个socket,用于client与agent通讯,监听Event事件。
BtraceAgent
BtraceAgent 主要入口在com.sun.btrace.agent.Main中,从解析参数->启动agentThread->loadBtraceScript->startserver socket->handleNewClient.
com.sun.btrace.agent.RemoteClien 用来提交script.
BtraceAgent在接受到监控指令后,会遍历当前所有已经加载的class类,挨个进行匹配检查,并生成相应的监控字节码(监控方法)。
Btrace 限制
can not create new objects.
can not create new arrays.
can not throw exceptions.
can not catch exceptions.
can not make arbitrary instance or staticmethod calls - only the public static methods of com.sun.btrace.BTraceUtilsclass or methods declared in the same program may be called from a BTraceprogram.
(pre 1.2) can not have instance fields andmethods. Only static public void returning methods are allowed for a BTraceclass. And all fields have to be static.
can not assign to static or instance fieldsof target program's classes and objects. But, BTrace class can assign to it'sown static fields ("trace state" can be mutated).
can not have outer, inner, nested or localclasses.
can not have synchronized blocks orsynchronized methods.
can not have loops (for, while, do..while)
can not extend arbitrary class (super classhas to be java.lang.Object)
can not implement interfaces.
can not contains assert statements.
can not use class literals.
具体可以参见:com.sun.btrace.compiler.Verifier
Btrace注解
Method Annotation | Argument Annotation | Field Annotation | Class Annotation |
OnMethod | Self | Export | DTrace |
OnTimer | Return | Property | DTraceRef |
OnError | ProbeClassName | TLS | Btrace |
OnExit | ProbeMethodName |
|
|
OnEvent | TargetInstance |
|
|
OnLowMemory |
|
|
|
OnProbe |
|
|
|
instrument http://download.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html
JVM TI(java tool api) http://download.oracle.com/javase/6/docs/jdk/api/attach/spec/com/sun/tools/attach/VirtualMachine.html
Java Compiler Api http://download.oracle.com/javase/6/docs/api/javax/tools/package-summary.html