一、背景
在生产环境中可能经常遇到各种问题,定位问题需要获取程序运行时的数据信息,如方法参数、返回值、全局变量、堆栈信息等。为了获取这些数据信息,我们可以通过改写代码,增加日志信息的打印,再发布到生产环境。通过这种方式,一方面将增大定位问题的成本和周期,对于紧急问题无法做到及时响应;另一方面重新部署后环境可能已被破坏,很难重新问题的场景。
二、BTrace功能
BTrace天生就为解决这类问题而来,它可以动态地跟踪java运行程序。通过hotswap技术,动态将跟踪字节码注入到运行类中,对运行代码侵入较小,对性能上的影响可以忽略不计。
BTrace在使用上有很多限制条件,如不能创建对象、数组、抛出和捕获异常、循环等,具体限制条件参考用户文档中的BTrace Restrictions。用户文档地址: http://kenai.com/projects/btrace/pages/UserGuide。
根据官方声明,不当地使用btrace可能导致jvm崩溃,如BTrace使用错误的.class文件,Hotspot JVM自身存在的hotswap bug等。可以先在本地验证BTrace脚本的正确性,再传到生产环境中定位问题。
三、安装步骤
1. 下载安装压缩包,最新版本的是1.2.1,下载地址: http://kenai.com/projects/btrace/downloads/directory/releases。
2. 解压缩,命令脚本放在bin目录中。
3. 设置脚本环境变量。
4. 增加脚本可执行权限。
四、使用方法
BTrace主要包含btracec和btrace两个命令编译和启动BTrace脚本:
1. btrace
功能: 用于运行BTrace跟踪程序。
命令格式:
btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]
示例:
btrace -cp build/ 1200 AllCalls1.java
参数含义:
include-path指定头文件的路径,用于脚本预处理功能,可选;
port指定BTrace agent的服务端监听端口号,用来监听clients,默认为2020,可选;
classpath用来指定类加载路径,默认为当前路径,可选;
pid表示进程号,可通过jps命令获取;
btrace-script即为BTrace脚本;btrace脚本如果以.java结尾,会先编译再提交执行。可使用btracec命令对脚本进行预编译。
args是BTrace脚本可选参数,在脚本中可通过"$"和"$length"获取参数信息。
2. btracec
功能: 用于预编译BTrace脚本,用于在编译时期验证脚本正确性。
btracec [-I <include-path>] [-cp <classpath>] [-d <directory>] <one-or-more-BTrace-.java-files>
参数意义同btrace命令一致,directory表示编译结果输出目录。
3. btracer
功能: btracer命令同时启动应用程序和BTrace脚本,即在应用程序启动过程中使用BTrace脚本。而btrace命令针对已运行程序执行BTrace脚本。
命令格式:
btracer <pre-compiled-btrace.class> <application-main-class> <application-args>
参数说明:
pre-compiled-btrace.class表示经过btracec编译后的BTrace脚本。
application-main-class表示应用程序代码;
application-args表示应用程序参数。
该命令的等价写法为:
java -javaagent:btrace-agent.jar=script=<pre-compiled-btrace-script1>[,<pre-compiled-btrace-script1>]* <MainClass> <AppArguments>
4. jvisualvm插件
BTrace提供了jvisualvm插件,强烈推荐在jvisualvm中编写和测试BTrace脚本,启动、关闭、发送事件、增加classpath都非常方便。
五、BTrace实战
1. 示例代码
示例代码定义了Counter计数器,有一个add()方法,每次增加随机值,总数保存在totalCount属性中。
package com.learnworld;
import java.util.Random;
public class BTraceTest {
public static void main(String[] args) throws Exception {
Random random = new Random();
// 计数器
Counter counter = new Counter();
while (true) {
// 每次增加随机值
counter.add(random.nextInt(10));
Thread.sleep(1000);
}
}
}
package com.learnworld;
public class Counter {
// 总数
private static int totalCount = 0;
public int add(int num) throws Exception {
totalCount += num;
sleep();
return totalCount;
}
public void sleep() throws Exception {
Thread.sleep(1000);
}
}
2. 常见使用场景
下面通过几个常见使用场景演示如何使用BTrace脚本。
1) 获取add()方法参数值和返回值。
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TracingScript {
@OnMethod(
clazz="com.learnworld.Counter",
method="add",
location=@Location(Kind.RETURN)
)
public static void traceExecute(int num,@Return int result){
println("====== ");
println(strcat("parameter num: ",str(num)));
println(strcat("return value:",str(result)));
}
}
2) 定时获取Counter类的属性值totalCount。
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TracingScript {
private static Object totalCount = 0;
@OnMethod(
clazz="com.learnworld.Counter",
method="add",
location=@Location(Kind.RETURN)
)
public static void traceExecute(@Self com.learnworld.Counter counter){
totalCount = get(field("com.learnworld.Counter","totalCount"), counter);
}
@OnTimer(1000)
public static void print(){
println("====== ");
println(strcat("totalCount: ",str(totalCount)));
}
}
3) 获取add方法执行时间。
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TracingScript {
@TLS private static long startTime = 0;
@OnMethod(
clazz="com.learnworld.Counter",
method="add"
)
public static void startExecute(){
startTime = timeNanos();
}
@OnMethod(
clazz="com.learnworld.Counter",
method="add",
location=@Location(Kind.RETURN)
)
public static void endExecute(@Duration long duration){
long time = timeNanos() - startTime;
println(strcat("execute time(nanos): ", str(time)));
println(strcat("duration(nanos): ", str(duration)));
}
}
4) 获取add()方法调用方法sleep()次数。
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TracingScript {
private static long count;
@OnMethod(
clazz="/.*/",
method="add",
location=@Location(value=Kind.CALL, clazz="/.*/", method="sleep")
)
public static void traceExecute(@ProbeClassName String pcm, @ProbeMethodName String pmn,
@TargetInstance Object instance, @TargetMethodOrField String method){
println("====== ");
println(strcat("ProbeClassName: ",pcm));
println(strcat("ProbeMethodName: ",pmn));
println(strcat("TargetInstance: ",str(classOf(instance))));
println(strcat("TargetMethodOrField : ",str(method)));
count++;
}
@OnEvent
public static void getCount(){
println(strcat("count: ", str(count)));
}
}
六、参考文档
1. userGuide: http://kenai.com/projects/btrace/pages/UserGuide
2. JAVA doc: http://btrace.kenai.com/javadoc/1.2/index.html
3. BTrace用户手册<译>,http://macrochen.iteye.com/blog/838920
4. btrace使用简介,http://rdc.taobao.com/team/jm/archives/509
5. btrace记忆,http://agapple.iteye.com/blog/962119
6. btrace一些你不知道的事(源码入手),http://agapple.iteye.com/blog/1005918
- 大小: 103 KB
分享到:
相关推荐
**BTrace 自我总结测试代码** BTrace 是一个强大的、安全的、动态的Java应用程序诊断工具,由Sun Microsystems(现已被Oracle收购)开发。它允许开发者在运行时对应用程序进行探查,而无需修改源代码或重启服务。...
总结来说,"btrace release-1.2.5.1" 是一个包含了BTrace工具的完整发布包,用户可以通过这个包了解并使用BTrace进行Java应用的动态追踪。从提供的文件列表中,我们可以获取到版权信息、许可证、第三方库信息、安装...
通过使用BTrace,开发者可以在运行时对Java应用添加探查点,收集数据,而无需修改源代码或重新编译。这极大地提高了问题排查的效率和便捷性。 2. **安装过程** - **Linux安装**:首先,将下载的压缩包解压到任意...
总结,BTrace 1.3.9作为一款强大的Java诊断工具,结合了对JDK 1.8的良好支持和Maven的便利性,使得开发者能够更高效地定位和解决问题。通过熟练掌握BTrace,我们可以提升对Java应用程序的理解和控制,从而优化系统...
总结,BTrace作为一款强大的Java在线调试工具,通过字节码增强技术实现了对运行中的Java应用的实时监控,对于开发人员而言,是进行性能优化和问题排查的得力助手。合理运用BTrace,可以极大地提升线上问题解决的效率...
总结来说,"bTrace跟踪线程堆栈" 是一种利用bTrace工具动态监控Java应用中线程行为的方法,有助于调试和优化代码,尤其是在处理并发问题时。通过学习这个主题,开发者可以更好地理解和诊断程序的运行状态,提升软件...
总结来说,btrace.jar是一个强大的Java在线检测工具,能够帮助开发者在不重启应用的情况下进行问题诊断。然而,由于其可能会带来一定的性能开销,因此通常应作为日志调试的补充手段,而非首选。正确理解和使用btrace...
"btrace引导文件安装Btrace"的标题表明我们将使用一个引导文件来安装Btrace。通常,这个引导文件可能包含必要的配置信息和脚本,以简化Btrace的部署过程。首先,你需要下载Btrace的安装包,这可以从官方仓库或其他...
总结来说,BTrace是一个强大的在线代码监控工具,它让我们无需停机或修改源代码就能深入理解线上应用的运行行为。通过编写简单的BTrace脚本,我们可以轻松地追踪代码执行的细节,如方法调用频率、耗时等,这对于性能...
总结起来,BTrace是一个强大且灵活的Java应用诊断工具,通过编写简单的Groovy脚本,就能实现在运行时对Java应用程序的深度监控。在开发和运维过程中,熟练掌握BTrace可以帮助我们快速定位问题,优化系统性能。在进行...
Java软件生产监控工具Btrace使用方法详解 Btrace是Sun公司推出的Java动态、安全追踪(监控)工具,可以在不需要重启的情况下监控系统运行情况,方便地获取程序运行时的数据信息,如方法参数、返回值、全局变量和...
总结来说,Btrace和Greys是Java开发者在生产环境中排查问题的有力助手,它们能够帮助我们实时查看代码执行情况,定位性能问题,且无需改动源代码或重启服务。通过熟练掌握这类工具,可以极大地提高问题解决的效率,...
对于工具使用,可能需要更深入地学习BTrace的文档,或者在社区中寻求帮助,看看其他用户是否遇到过类似问题。 压缩包中的文件名(如hs_err_pid*.log)通常是Java HotSpot虚拟机的错误日志。这些日志包含了JVM在运行...
在这个例子中,我们定义了一个名为`HelloWorld`的TraceClass,并使用`@BTrace`注解将其标记为BTrace类。然后定义了一个名为`onNewFile`的动作方法,该方法将在每次创建新的`File`对象时被调用,并打印出创建的文件...
使用时需要注意,BTrace注入的字节码不会自动还原,因此在生产环境中使用时,应确保跟踪操作是只读且有限的。BTrace对追踪脚本有一些限制,例如禁止创建对象、数组,禁止抛出或捕获异常,禁止使用循环、同步块等。...
BTrace 的核心是使用 BTrace 脚本来定义要收集的信息。在上述例子中,我们看到一个名为 `DBProxyTrace` 的 BTrace 脚本,该脚本关注于 `xxx.xxx.QueryHandler` 类的 `query` 方法。当该方法返回且执行时间超过 10 ...
快速总结 BTrace是用于Java平台的安全,动态跟踪工具。 BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace,适用于OpenSolaris应用程序和OS)。 BTrace动态地检测目标应用程序的类以注入跟踪代码(“字节码...
BTrace 版本 2.0 快速总结 ...使用BTrace 安装 将二进制分发文件(* .tar.gz或* .zip)分解到您选择的目录中 您可以将系统环境变量BTRACE_HOME设置为指向包含展开分布的目录。 为了方便起见,可以使用$ B
总结起来,Java 动态追踪技术,如 BTrace,是一种强大的工具,它允许开发者在运行时无侵入地监控和诊断应用程序。借助 Instrumentation API,BTrace 能够安全地修改类字节码,添加追踪代码,从而为优化性能、调试和...