BTrace 是一个非常不错的java诊断工具, 最近试着用了一下, 文档比较少, 主要是看例子吧.
BTrace 中的B表示bytecode, 表明它是在字节码层面上对代码进行trace
用来在运行中的java类中注入trace代码, 并对运行中的目标程序进行热交换(hotswap)
btrace还提供了VisualVM Plugin 以及Netbeans Plugin
术语
Probe Point
在何处执行trace语句, 这里的"何处"可以是具体的跟踪地点和执行事件, 在BTrace中通过各种注解来指定
Trace Actions or Actions
在何时执行trace语句
Action Methods
定义在trace脚本中的trace语句, 具体来说就是脚本中的无返回值静态方法(1.2之后可以是非静态方法)
BTrace限制
为了保证trace语句只读, BTrace对trace脚本有一些限制(比如不能改变被trace代码中的状态)
· BTrace class不能新建类, 新建数组, 抛异常, 捕获异常,
· 不能调用实例方法以及静态方法(com.sun.btrace.BTraceUtils除外)
· 不能将目标程序和对象赋值给BTrace的实例和静态field
· 不能定义外部, 内部, 匿名, 本地类
· 不能有同步块和方法
· 不能有循环
· 不能实现接口, 不能扩展类
· 不能使用assert语句, 不能使用class字面值
BTrace步骤
1.取得目标java进程id(pid)
2.编写BTrace脚本
3.执行命令行: btrace <pid> <自己定制的脚本> <输出文件>
eg:btrace 3045PrintExecuteTime.java > time.log
完整的BTrace命令:
- -I 没有这个表明跳过预编译
- include-path: 指定用来编译脚本的头文件路径(关于预编译可参考例子ThreadBean.java)
- port : btrace agent端口, 默认是2020
- classpath : 编译所需类路径, 一般是指btrace-client.jar等类所在路径
- pid : java进程id
- btrace-script: btrace脚本, 如果是java文件, 则是未编译, class文件, 则是已编译过的
- args: 传递给btrace脚本的参数, 在脚本中可以通过$(), $length()来获取这些参数(定义在BTraceUtils中)
预编译BTrace脚本命令
参数和上面大同小异, btracec 是一个类似javac的程序, 使用该程序编译, 将根据BTrace的限制条件进行严格检查
在目标程序中启动BTrace Agent
这个主要针对需要在目标程序启动的时候就需要trace其行为的场景, 此时BTrace agent将与目标程序一起启动(前提是必须对BTrace脚本进行预编译)
命令行:
方法上的注解
- @com.sun.btrace.annotations.OnMethod 用来指定trace的目标类和方法以及具体位置, 被注解的方法在匹配的方法执行到指定的位置会被调用. "clazz"属性用来指定目标类名, 可以指定全限定类名, 比如"java.awt.Component", 也可以是正则表达式(表达式必须写在"//"中, 比如"/java\\.awt\\..+/"). "method"属性用来指定被trace的方法. 表达式可以参考自带的例子(NewComponent.java 和 Classload.java, 关于方法的注解可以参考MultiClass.java). 有时候被trace的类和方法可能也使用了注解. 用法参考自带例子WebServiceTracker.java. 针对注解也是可以使用正则表达式, 比如像这个"@/com\\.acme\\..+/ ", 也可以通过指定超类来匹配多个类, 比如"+java.lang.Runnable"可以匹配所有实现了java.lang.Runnable接口的类. 具体参考自带例子SubtypeTracer.java.
- @com.sun.btrace.annotations.OnTimer 用来指定时长(ms)执行一次trace. 时长通过"value"属性指定. 具体参考自带例子 Histogram.java
- @com.sun.btrace.annotations.OnError 当trace代码抛异常时该注解的方法会被执行. 如果同一个trace脚本中其他方法抛异常, 该注解方法也会被执行.
- @com.sun.btrace.annotations.OnExit 当trace方法调用内置exit(int)方法(用来结束整个trace程序)时, 该注解的方法会被执行. 参考自带例子ProbeExit.java.
- @com.sun.btrace.annotations.OnEvent 用来截获"外部"btrace client触发的事件, 比如按Ctrl-C 中断btrace执行时将执行使用了该注解的方法, 该注解的value值为具体事件名称. 具体参考例子HistoOnEvent.java
- @com.sun.btrace.annotations.OnLowMemory 当内存超过某个设定值将触发该注解的方法, 具体参考MemAlerter.java
- @com.sun.btrace.annotations.OnProbe //我也没搞明白:(
参数上的注解
- @com.sun.btrace.annotations.Self 用来指定被trace方法的this, 可参考例子AWTEventTracer.java 和 AllCalls1.java
- @com.sun.btrace.annotations.Return 用来指定被trace方法的返回值, 可参考例子Classload.java
- @com.sun.btrace.annotations.ProbeClassName (since 1.1) 用来指定被trace的类名, 可参考例子AllMethods.java
- @com.sun.btrace.annotations.ProbeMethodName (since 1.1) 用来指定被trace的方法名, 可参考例子WebServiceTracker.java o (since 1.2)可以通过注解的fqn boolean属性来表明是否要获取全限定方法名
- @com.sun.btrace.annotations.TargetInstance (since 1.1) 用来指定被trace方法内部被调用到的实例, 可参考例子AllCalls2.java
- @com.sun.btrace.annotations.TargetMethodOrField (since 1.1) 用来指定被trace方法内部被调用的方法名, 可参考例子AllCalls1.java 合 AllCalls2.java o (since 1.2) 可通过注解的fqn boolean属性来表明是否要获取全限定方法名
未被注解的方法参数
未使用注解的方法参数一般都是用来做方法签名匹配用的, 他们一般和被trace方法中参数出现的顺序一致. 不过他们也可以与注解方法交错使用, 如果一个参数类型声明为*AnyType[]*, 则表明它按顺序"通吃"方法所有参数. 未注解方法需要与*Location*结合使用:
- Kind.ENTRY, Kind.RETURN- 被trace方法参数
- Kind.THROW - 抛异常
- Kind.ARRAY_SET, Kind.ARRAY_GET - 数组索引
- Kind.CATCH - 捕获异常
- Kind.FIELD_SET - 属性值
- Kind.LINE - 行号
- Kind.NEW - 类名
- Kind.ERROR - 抛异常
属性上的注解
- @com.sun.btrace.annotations.Export 该注解的静态属性主要用来与jvmstat计数器做关联. 使用该注解之后, btrace程序就可以向jvmstat客户端(可以用来统计jvm堆中的内存使用量)暴露trace程序的执行次数, 具体可参考例子ThreadCounter.java
- @com.sun.btrace.annotations.Property 使用了该注解的trace脚本将作为MBean的一个属性, 一旦使用该注解, trace脚本就会创建一个MBean并向MBean服务器注册, 这样JMX客户端比如VisualVM, jconsole就可以看到这些BTrace MBean. 如果这些被注解的属性与被trace程序的属性关联, 那么就可以通过VisualVM 和jconsole来查看这些属性了. 具体可参考例子ThreadCounterBean.java 和 HistogramBean.java.
- @com.sun.btrace.annotations.TLS 用来将一个脚本变量与一个ThreadLocal变量关联. 因为ThreadLocal变量是跟线程相关的, 一般用来检查在同一个线程调用中是否执行到了被trace的方法. 具体可参考例子OnThrow.java 和 WebServiceTracker.java
类上的注解
- @com.sun.btrace.annotations.DTrace 用来指定btrace脚本与内置在其脚本中的D语言脚本关联, 具体参考例子DTraceInline.java.
- @com.sun.btrace.annotations.DTraceRef 用来指定btrace脚本与另一个D语言脚本文件关联. 具体参考例子DTraceRefDemo.java.
- @com.sun.btrace.annotations.BTrace 用来指定该java类为一个btrace脚本文件.
监控方法参数(数组)
2 import static com.sun.btrace.BTraceUtils.printArray;
3 import static com.sun.btrace.BTraceUtils.println;
4 import static com.sun.btrace.BTraceUtils.probeClass;
5 import static com.sun.btrace.BTraceUtils.probeMethod;
6
7 import com.sun.btrace.annotations.BTrace;
8 import com.sun.btrace.annotations.OnMethod;
9
10 @BTrace
11 public class PrintArgArray {
12
13 /**
14 * 此方法打印出Test类中的mergeArray(Long[] arrayOne, Long[] arrayTwo)方法传入的参数
15 * 参数名字一定要和监控对象的方法参数名字一致
16 *
17 * @param arrayOne 监控参数一
18 * @param arrayTwo 监控参数二
19 *
20 */
21 @OnMethod(clazz = "com.jerry.test.Test", method = "mergeArray")
22 // 此处写明要监控的包、类、方法等 可以使用正则匹配
23 public static void anyRead(Long[] arrayOne, Long[] arrayTwo) {
24 // 打印监控的类名
25 print(probeClass());
26 print(" [");
27 // 打印监控的方法名
28 print(probeMethod());
29 println("]");
30
31 if (arrayOne != null) {
32 printArray(arrayOne);
33 } else {
34 println("the arguments is null!");
35 }
36
37 if (arrayTwo != null) {
38 printArray(arrayTwo);
39 } else {
40 println("the arguments is null!");
41 }
42 }
43
44 }
监控使用时间
2 import static com.sun.btrace.BTraceUtils.print;
3 import static com.sun.btrace.BTraceUtils.println;
4 import static com.sun.btrace.BTraceUtils.probeClass;
5 import static com.sun.btrace.BTraceUtils.probeMethod;
6 import static com.sun.btrace.BTraceUtils.str;
7 import static com.sun.btrace.BTraceUtils.strcat;
8 import static com.sun.btrace.BTraceUtils.timeMillis;
9
10 import com.sun.btrace.annotations.BTrace;
11 import com.sun.btrace.annotations.Kind;
12 import com.sun.btrace.annotations.Location;
13 import com.sun.btrace.annotations.OnMethod;
14 import com.sun.btrace.annotations.TLS;
15
16 /**
17 * 监控方法耗时
18 *
19 *
20 */
21 @BTrace
22 public class PrintTimes {
23
24 /**
25 * 开始时间
26 */
27 @TLS
28 private static long startTime = 0;
29
30 /**
31 * 方法开始时调用
32 */
33 @OnMethod(clazz = "/com\\copul\\../", method = "/.+/")
34 public static void startMethod() {
35 startTime = timeMillis();
36 }
37
38 /**
39 * 方法结束时调用<br>
40 * Kind.RETURN这个注解很重要
41 */
42 @SuppressWarnings("deprecation")
43 @OnMethod(clazz = "/com\\.copul\\../", method = "/.+/", location = @Location(Kind.RETURN))
44 public static void endMethod() {
45
46 print(strcat(strcat(name(probeClass()), "."), probeMethod()));
47 print(" [");
48 print(strcat("Time taken : ", str(timeMillis() - startTime)));
49 println("]");
50 }
51 }
监控内存
2 import java.lang.management.MemoryUsage;
3
4 import com.sun.btrace.annotations.BTrace;
5 import com.sun.btrace.annotations.OnLowMemory;
6
7 /**
8 * 监控内存使用
9 *
10 *
11 */
12 @BTrace
13 public class PrintMemory {
14
15 /*
16 * 指定内存区域低于一定的界限的时候才内存使用打印数据<br> 也可以指定时间间隔打印内存使用
17 */
18 @OnLowMemory(pool = "Tenured Gen", threshold = 6000000)
19 public static void printMem(MemoryUsage mu) {
20 print("MemoryUsage : ");
21 println(mu);
22 print("FreeMem : ");
23 println(freeMemory());
24 print("Heap:");
25 println(heapUsage());
26 print("Non-Heap:");
27 println(nonHeapUsage());
28 }
29 }
相关推荐
java btrace线上代码调试工具,可以用来在不关闭线上系统的情况下动态植入调试代码
《深入理解BTrace 1.3.9:Java应用诊断利器》 BTrace,全称为“Bytecode Tracing”,是一款强大的动态代码插桩工具,它允许开发者在运行时对Java应用程序进行性能分析和诊断。BTrace 1.3.9是其一个重要版本,特别...
net-java-btrace-visualvm.nbm java visualvm btrace 插件
1. **编写脚本**:Btrace使用一种基于Groovy的脚本语言,你可以通过学习官方提供的samples来快速上手。这些脚本通常包含探查点(probe),在特定的代码行或方法执行时被触发。 2. **查找Java进程**:使用`jps`命令...
Java软件生产监控工具Btrace使用方法详解 Btrace是Sun公司推出的Java动态、安全追踪(监控)工具,可以在不需要重启的情况下监控系统运行情况,方便地获取程序运行时的数据信息,如方法参数、返回值、全局变量和...
- **自定义脚本**:BTrace使用一种基于Java的脚本语言,允许开发者编写简单的脚本来定义想要追踪的行为,例如记录特定方法的执行时间、参数和返回值。 - **安全无侵入**:BTrace遵循最小权限原则,仅对指定的方法...
**BTrace监控远程服务器使用实例** BTrace 是一个强大的、安全的、动态的Java...通过熟练掌握BTrace的使用,可以有效地提升故障排查效率,优化Java应用的性能。记住,合理配置安全策略和权限,确保远程监控的安全性。
标题中的"BTrace"是一个专为Java平台设计的安全、动态的跟踪工具,它的主要功能是对正在运行的Java应用程序进行实时监控和诊断。...在实际开发中,结合BTrace的使用,可以帮助我们构建更加健壮、高效的Java系统。
通常,这样的包会包含Btrace的二进制文件、文档、示例脚本以及可能的配置文件,方便用户在Java 1.8环境下安装和使用Btrace。用户需要先解压这个文件,然后根据文档指导进行配置和启动,以利用Btrace的功能。 在实际...
在Java开发领域,性能优化是不可或缺的一环,而BTrace作为一个强大的动态...正确安装和使用BTrace,可以极大地提升Java应用程序的性能调优效率。通过熟练掌握这一工具,开发者能够更深入地理解和优化他们的Java应用。
3. **运行Btrace**:使用`btrace`命令启动Btrace,并指定要监控的Java进程ID以及脚本文件。 4. **查看结果**:Btrace 将在控制台输出监控数据,也可以选择将结果输出到文件或通过网络发送到其他工具进行进一步分析...
本文将介绍两款强大的Java在线问题排查工具——Btrace和Greys,它们能够帮助开发者在不重启服务的情况下,实时地跟踪和分析代码执行情况。 1. Btrace 是一个开源的Java诊断工具,它利用了Java的Instrumentation API...
BTrace脚本由一系列探查点和相关操作组成,使用Java语法编写。开发者可以定义探查点触发时执行的代码,比如记录日志、计算性能指标等。`samples`目录中的脚本提供了很好的学习起点。 5. **BTrace的优势**: - **...
1. 使用Btrace需要对Java和Java虚拟机有一定的了解。 2. 虽然Btrace可以无侵入地跟踪应用程序,但过度使用可能会对性能产生影响,因此应在生产环境谨慎使用。 3. Btrace与特定的JDK版本兼容,本资源包特别提到支持...
Btrace非侵入式调试Java程序神奇win版本,可以在线调试java应用不需要重新编译
2. **脚本编写**:BTrace使用一种简单的脚本语言,基于Groovy,开发者可以编写脚本来定义想要追踪的行为。例如,可以追踪方法调用、记录日志、计算性能指标等。 3. **安全机制**:BTrace有内置的安全策略,以防止不...
通过使用BTrace,开发者可以在运行时对Java应用添加探查点,收集数据,而无需修改源代码或重新编译。这极大地提高了问题排查的效率和便捷性。 2. **安装过程** - **Linux安装**:首先,将下载的压缩包解压到任意...
标题 "bTrace跟踪线程堆栈" 涉及到的是在Java开发中对线程堆栈进行监控和分析的技术,主要使用了开源工具bTrace。bTrace是一款强大的、无侵入式的Java运行时代码注入工具,允许开发者在运行中的Java应用上动态添加...
4. **兼容性**:btrace需要与Java版本兼容,确保使用的btrace版本能与目标应用程序的Java版本匹配。 5. **调试与优化**:btrace提供了丰富的调试选项,如输出跟踪信息、控制台打印等,方便我们调试和优化监控脚本。 ...