教程英文版来源:https://github.com/btraceio/btrace/blob/master/docs/usersguide.html
BTrace用户指南
BTrace是一种安全,动态的Java跟踪工具。BTrace通过动态(字节码)检测正在运行的Java程序的类来工作。BTrace将跟踪操作插入到正在运行的Java程序的类中,并对跟踪的程序类进行热交换。
BTrace术语
- 探针点
- 执行一组跟踪语句的“location”或“event”。探针点是我们想要执行一些跟踪语句的感兴趣的“位置”或“事件”。 跟踪操作或操作
- 探测器“触发”时执行的跟踪语句。 行动方法
- 探测器触发时执行的BTrace跟踪语句是在类的静态方法中定义的。这种方法称为“动作”方法。
BTrace程序结构
BTrace程序是一个普通的Java类,它有一个或多个public static void
用BTrace注释注释的方法。注释用于指定跟踪的程序“位置”(也称为“探测点”)。跟踪操作在静态方法体内指定。这些静态方法称为“动作”方法。
BTrace限制
为了保证跟踪操作是“只读”(即跟踪操作不会改变跟踪的程序状态)和有界(即跟踪操作在有限时间内终止),BTrace程序只允许执行一组有限的行动。特别是BTrace类
- 不能创建新的对象。
- 不能创造新的阵列。
- 不能抛出异常。
- 不能捕捉异常。
- 不能让任意实例或静态方法调用-只有
public static
方法的com.sun.btrace.BTraceUtils
类可以从BTrace程序调用。 - 不能分配到目标程序的类和对象的静态或实例字段。但是,BTrace类可以分配给它自己的静态字段(“跟踪状态”可以变异)。
- 不能有实例字段和方法。
static public void
BTrace类只允许返回方法。所有领域都必须是静态的。 - 不可以具有外,内,嵌套的或局部类。
- 不可以具有同步块或同步方法。
- 不能有环(
for, while, do..while
) - 不可以延伸任意类(超类必须java.lang.Object中)
- 不可以实现接口。
- 不可以包含断言语句。
- 不可以使用类文字。
一个简单的BTrace程序
// import all BTrace annotationsimport com.sun.btrace.annotations.*;// import statics from BTraceUtils classimport static com.sun.btrace.BTraceUtils.*;// @BTrace annotation tells that this is a BTrace program@BTracepublic class HelloWorld { // @OnMethod annotation tells where to probe. // In this example, we are interested in entry // into the Thread.start() method. @OnMethod( clazz="java.lang.Thread", method="start" ) public static void func() { // println is defined in BTraceUtils // you can only call the static methods of BTraceUtils println("about to start a thread!"); }}
上面的BTrace程序可以针对正在运行的Java进程运行。这个程序将打印“即将开始一个线程!” 每当目标程序即将通过Thread.start()
方法启动一个线程时,在BTrace客户端。还有其他有趣的探索点可能。例如,我们可以在从方法返回时插入跟踪操作,从方法返回异常,在方法中获取或设置字段,创建对象/数组,行号,抛出异常。有关详细信息,请参阅 @OnMethod和其他注释。
运行BTrace的步骤
- 查找要跟踪的目标Java进程的进程ID。您可以使用工具查找pid。
- 编写BTrace程序 - 您可能想要开始修改其中一个 示例。
- 通过以下命令行运行btrace工具:
btrace
BTrace命令行
BTrace使用命令行工具btrace运行,如下所示:
btrace [-I] [-p ] [-cp ] [ ]
哪里
include-path
是一组搜索头文件的包含目录。BTrace包含一个简单的预处理,支持#define,#include和条件编译。它是不是像一个完整的C / C ++预处理程序-但有用的子集。请参阅示例“ThreadBean.java”。如果未指定-I,则BTrace将跳过预处理器调用步骤。port
是BTrace代理侦听的端口。这是可选参数。classpath
是一组目录,jar文件,其中BTrace在编译期间搜索类。默认为“。”。pid
是跟踪的Java程序的进程IDbtrace-script
是跟踪计划。如果它是“.java”,则在提交之前编译它。或者,假设它是预编译的[即,它必须是.class]并提交。
可选的
port
是BTrace代理程序侦听客户端的服务器套接字端口。默认是2020。path
是用于编译BTrace程序的类路径。默认为“。”。args
是传递给BTrace程序的命令行参数。BTrace程序可以使用内置函数“$”和“$ length”访问它们。
预编译BTrace脚本
可以使用btracec脚本预编译BTrace程序。btracec是一个类似javac的程序,它接受一个BTrace程序并生成一个.class文件。
btracec [-I] [-cp ] [-d ]
哪里
include-path
是一组搜索头文件的包含目录。BTrace包含一个简单的预处理,支持#define,#include和条件编译。它是不是像一个完整的C / C ++预处理程序-但有用的子集。请参阅示例“ThreadBean.java”。如果未指定-I,则BTrace将跳过预处理器调用步骤。classpath
是用于编译BTrace程序的类路径。默认为“。”directory
是存储编译的.class文件的输出目录。默认为“。”。
此脚本使用BTrace编译器类 - 而不是常规javac,因此将在编译时验证您的BTrace程序[以便您可以在运行时避免BTrace验证错误]。
使用BTrace代理启动应用程序
到目前为止,我们已经了解了如何跟踪正在运行的Java程序。也可以在其中启动使用BTrace代理的应用程序。如果您想从“开始”开始跟踪应用程序,您可能希望使用BTrace代理启动应用程序并指定跟踪脚本[即,BTrace代理是按需加载以及预先加载可加载代理程序]您可以使用以下命令启动应用程序并指定BTrace脚本文件。但是,您需要预编译BTrace脚本以实现此类用法。
java -javaagent:btrace-agent.jar=script=
以这种方式启动应用程序时,跟踪输出将转到当前目录中名为<btrace-class-file-name> .btrace的文件。此外,您可以通过指定noServer=true
BTrace代理的参数来避免为其他远程BTrace客户端启动服务器。
有一个方便的脚本叫做btracer来执行上述操作:
btracer
BTrace注释
方法注释
- @ com.sun.btrace.annotations.OnMethod 注释可用于指定方法中的目标类,目标方法和“位置”。当匹配方法到达指定位置时,将调用由此批注注释的操作方法。在OnMethod注释中,跟踪类名由“clazz”属性指定,跟踪方法由“method”属性指定。“clazz中”可以是一个完全合格的类名(像
java.awt.Component
或两个前进内指定正则表达式斜线。参考样品 NewComponent.java和Classload.java。正则表达式可以匹配的零个或更多的类在这种情况下所有匹配类仪表化的。例如/java\\.awt\\..+/
匹配java.awt包中的所有类。此外,方法名称也可以是正则表达式 - 匹配零个或多个方法。请参阅示例MultiClass.java。还有另一种方法可以抽象地指定跟踪类和方法。可以通过注释指定跟踪的类和方法。例如,如果将“clazz”属性指定为@javax.jws.WebService
BTrace,则将检测由WebService批注注释的所有类。类似地,方法级别注释可用于抽象地指定方法。请参阅示例 WebServiceTracker.java。也可以将正则表达式与注释结合起来 - 比如说@/com\\.acme\\..+/
匹配由任何与给定正则表达式匹配的注释注释的任何类。通过指定超类型可以匹配多个类。即,匹配给定超类型的子类型的所有类。+java.lang.Runnable
匹配实现java.lang.Runnable接口的所有类。请参阅示例SubtypeTracer.java。 - @ com.sun.btrace.annotations.OnTimer 注释可用于指定必须每N毫秒定期运行一次的跟踪操作。时间段被指定为此注释的长“值”属性。请参阅 Histogram.java示例
- @ com.sun.btrace.annotations.OnError 注释可用于指定在跟踪某些其他探测操作时抛出任何异常时运行的操作。当同一BTrace类中的任何其他BTrace操作方法抛出任何异常时,将调用由此批注注释的BTrace方法。
- @ com.sun.btrace.annotations.OnExit 注释可用于指定当BTrace代码调用“exit(int)”内置函数以完成跟踪“会话”时运行的操作。请参阅示例 ProbeExit.java。
- @ com.sun.btrace.annotations.OnEvent 注释用于将跟踪方法与BTrace客户端发送的“外部”事件相关联。当BTrace客户端发送“事件”时,将调用由此注释注释的BTrace方法。客户端可以根据某种形式的用户请求发送事件(如按Ctrl-C或GUI菜单)。字符串值可以用作事件的名称。这样,只要外部事件“触发”,就可以执行某些跟踪动作。截至目前,只要使用按Ctrl-C(SIGINT),命令行BTrace客户端就会发送“事件”。在SIGINT上,显示控制台菜单以发送事件或退出客户端[这是SIGINT的默认设置]。请参阅示例 HistoOnEvent.java
- @ com.sun.btrace.annotations.OnLowMemory 注释可用于跟踪内存阈值超出事件。请参阅示例 MemAlerter.java
- @ com.sun.btrace.annotations.OnProbe 注释可用于指定以避免在BTrace脚本中使用实现内部类。@OnProbe探针规范由BTrace VM代理映射到一个或多个@OnMethod规范。目前,此映射是使用XML探测描述符文件[由BTrace代理访问]完成的。请参阅示例 SocketTracker1.java 和关联的探测描述符文件 java.net.socket.xml。运行此示例时,需要将此xml文件复制到目标JVM运行的目录中(或修复btracer.bat中的probeDescPath选项以指向.xml文件所在的位置)。
参数注释
- @ com.sun.btrace.annotations.Self 注释可用于标记一个参数以保存* this *(或* self *)值。请参阅示例 AWTEventTracer.java或 AllCalls1.java
- @ com.sun.btrace.annotations.Return 注释可用于标记保存返回值的参数。请参阅示例 Classload.java
- @ com.sun.btrace.annotations.CalledInstance 注释可用于标记保存被调用实例值的参数。请参阅示例 AllCalls2.java
- @ com.sun.btrace.annotations.CalledMethod 可用于标记包含被调用方法名称的参数。请参阅示例 AllCalls1.java或 AllCalls2.java
字段注释
@com.sun.btrace.annotations.Export
注释可以与BTrace字段(静态字段)一起使用,以指定该字段必须映射到jvmstat计数器。使用此功能,BTrace程序可以将跟踪计数器公开给外部jvmstat客户端(例如jstat)。请参阅示例 ThreadCounter.java@com.sun.btrace.annotations.Property
注释可用于将特定(静态)字段标记为MBean特性。如果BTrace类具有至少一个具有@Property属性的静态字段,则创建MBean并向平台MBean服务器注册。诸如VisualVM,jconsole之类的JMX客户端可用于查看此类BTrace MBean。将BTrace附加到目标程序后,可以将VisualVM或jconsole附加到同一程序并查看新创建的BTrace MBean。使用VisualVM和jconsole,您可以使用MBeans选项卡查看BTrace域并查看其属性。请参阅示例ThreadCounterBean和 HistogramBean.java。@com.sun.btrace.annotations.TLS
注释可以与BTrace字段(静态字段)一起使用,以指定该字段是线程本地字段。每个Java线程都获得该字段的单独“副本”。BTrace程序可以使用这些线程本地字段来识别我们是否从同一线程到达多个探测操作。请参阅示例 OnThrow.java和 WebServiceTracker.java
类注释
@com.sun.btrace.annotations.DTrace
注释可用于将简单的单线程D-script(在BTrace Java类中内联)与BTrace程序相关联。请参阅示例DTraceInline.java。@com.sun.btrace.annotations.DTraceRef
注释可用于将D-script(存储在单独的文件中)与BTrace程序相关联。请参阅示例DTraceRefDemo.java。@com.sun.btrace.annotations.BTrace
必须使用注释将给定的Java类指定为BTrace程序。此注释由BTrace编译器以及BTrace代理强制执行。
DTrace集成
Solaris DTrace是一个用于Solaris程序的动态,安全的跟踪系统 - 内核和用户登陆程序。由于brace与DTrace和BTrace有明显的相似之处,因此可以预期整合b / w BTrace和DTrace。BTrace与DTrace集成的方式有两种。
- BTrace程序可以通过调用来引发DTrace探测
dtraceProbe
- 请参阅上面提到的BTraceUtils javadoc。要使此功能起作用,您需要在Solaris 10或更高版本上运行。对于其他平台(Solaris 9或更低版本或任何其他操作系统),dtraceProbe()
将是无操作。 - BTrace程序可以将D-script与它相关联 - 通过@DTrace注释(如果D-script是一个简单的单行),或者如果D-script较长并且因此存储在BTrace程序之外,则通过@DTraceRef。请参阅下面的BTrace样品部分中的DTrace集成样品。此功能使用。要使此DTrace功能起作用(oe,能够运行相关的D-script),您需要在Solaris 11 build 35或更高版本上运行。您可能想要检查您的计算机上是否有/usr/share/lib/java/dtrace.jar。@DTrace和@DTraceRef注释在其他平台(Solaris 10或更低版本或任何其他OS)上被忽略。
BTrace样品
BTrace样品
关于样品的一行:
- AWTEventTracer.java - 通过检测EventQueue.dispatchEvent()方法演示AWT事件的跟踪。可以通过instanceof检查过滤事件。此示例仅过滤和打印焦点事件。
- AllLines.java - 演示基于行号的BTrace探测器。可以探测任何类(或类)和行号。当达到指定类的指定行号时,将触发BTrace探测并执行相应的操作。
- ArgArray.java - 在java.io包中的每个类的每个readXXX方法中打印所有输入参数。在探针规范中演示参数数组访问和多个类/方法匹配。
- Classload.java -
defineClass
由任何用户定义的类加载器在每个成功的类加载(返回)上打印堆栈跟踪。 - CommandArg.java - 演示BTrace命令行参数访问。
- Deadlock.java - 演示@OnTimer探针和
deadlock()
内置函数。 - DTraceInline.java - 演示@DTrace注释,将简单的单行D-script与BTrace程序相关联。
- DTraceRefDemo.java - 演示@DTraceRef注释以将D-script文件与BTrace程序相关联。此示例将classload.d与其自身相关联。
- FileTracker.java - 通过探测
File{Input/Output}Stream
构造函数入口点打印文件以进行读/写。 - FinalizeTracker.java - 演示我们可以打印对象的所有字段以及访问(私有)字段(只读)。这在调试/故障排除方案中很有用。此示例打印有关java.io.FileInputStream类的close()/ finalize()方法的信息。
- Histogram.java - 演示使用BTrace地图收集直方图(
javax.swing.JComponent
由app创建的对象 - 按子类名称和计数的直方图)。 - HistogramBean.java - 演示JMX集成。此示例使用
@Property
注释公开Map作为MBean属性。 - HistoOnEvent.java - 演示基于客户端事件获取跟踪输出。在BTrace客户端启动脚本后,按Ctrl-C获取发送事件或退出的菜单。在发送事件时,将打印直方图。这样,客户端可以在需要时“拉”跟踪输出,而不是BTrace代理总是或基于计时器推送跟踪输出。
- JdbcQueries.java - 演示BTrace聚合工具。此工具类似于工具。
- JInfo.java -演示
printVmArguments()
,printProperties()
并printEnv()
内置函数。 - JMap.java - 演示
dumpHeap()
内置函数以转储(hprof二进制格式)目标应用程序的堆转储。 - JStack.java - 演示
jstackAll()
内置函数以打印所有线程的堆栈跟踪。 - LogTracer.java - 演示捕获到实例方法(Logger.log)和打印私有字段值(LogRecord对象)
field()
和objectValue()
内置函数。 - MemAlerter.java - 演示@OnLowMememory注释对低内存事件的跟踪。
- Memory.java - 通过计时器探测器每4秒打印一次内存统计信息。演示内存统计内置函数。
- MultiClass.java - 演示使用正则表达式
clazz
和注释method
字段将跟踪代码插入到多个类的多个方法中@OnMethod
。 - NewComponent.java - 跟踪每个
java.awt.Component
创建并递增计数器并根据计时器打印计数器。 - OnThrow.java - 每次创建任何异常实例时都会打印异常堆栈跟踪。在大多数情况下,创建后会立即抛出异常。所以,我们得到了投掷点的堆栈跟踪。
- ProbeExit.java - 演示
@OnExit
探针和exit(int)
内置函数。 - Sizeof.java - 演示“sizeof”内置函数,可用于获取(近似)给定Java对象的大小。使用此内置功能可以获得按尺寸方式的直方图等。
- SocketTracker.java - 打印每个服务器socker创建/绑定和客户端套接字接受。
- SocketTracker1.java - 类似于SocketTracker.java示例,但此示例使用@OnProbe探针以避免在BTrace程序中使用Sun特定的套接字通道实现类。而是BTO代理将@OnProbe探针映射到@OnMethod探针。
- SysProp.java - 演示可以探测System类(如java.lang.System)并在action方法中调用BTrace内置函数。
- SubtypeTracer.java - 演示可以匹配给定超类型的所有子类型。
- ThreadCounter.java - 演示如何使用BTrace程序中的jvmstat计数器。
- ThreadCounterBean.java - 演示将BTrace程序公开为具有一个属性的JMX bean(使用@Property注释)。
- ThreadBean.java - 演示了BTrace [和JMX integratio]的预处理器的使用。
- ThreadStart.java - 演示从BTrace程序中提升DTrace探测器。另请参见 jthread.d - 关联的D-script。只要跟踪的程序进入java.lang.Thread.start()方法,此示例就会引发DTrace USDT探测。BTrace程序将JavaThread的名称传递给DTrace。
- Timers.java -
@OnTimer
在BTrace程序中演示多个计时器探测器()。 - URLTracker.java - 每次
URL.openConnection
成功返回时打印URL 。该程序也使用jurls.d D-script(显示通过DTrace打开的URL的直方图)。 - WebServiceTracker.java - 通过指定类和方法级别注释而不是类和方法名称来演示跟踪类和方法。