`
zl198751
  • 浏览: 273605 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

BTrace使用

 
阅读更多

该篇文章为译稿,原稿在:http://kenai.com/projects/btrace/pages/UserGuide#btrace_anno

包括本文提到的sample代码也在原稿中有连接。

Btrace的API在:http://btrace.kenai.com/javadoc/1.2/index.html

 

BTrace(https://btrace.dev.java.net/ ) 是一个非常不错的 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命令: 

引用
btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]

 

  • -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 [-I <include-path>] [-cp <classpath>] [-d <directory>] <one-or-more-BTrace-.java-files>


参数和上面大同小异, btracec 是一个类似javac的程序, 使用该程序编译, 将根据BTrace的限制条件进行严格检查 

在目标程序中启动BTrace Agent 
这个主要针对需要在目标程序启动的时候就需要trace其行为的场景, 此时BTrace agent将与目标程序一起启动(前提是必须对BTrace脚本进行预编译) 
命令行: 

引用
java -javaagent:btrace-agent.jar=script=<pre-compiled-btrace-script1>[,<pre-compiled-btrace-script1>]* <MainClass> <AppArguments>

方法上的注解  

  • @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脚本文件.

脚本举例如下 
1.监控方法参数(数组)  

  1. import   static  com.sun.btrace.BTraceUtils.print;    
  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.       * @author jerry  
  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.监控使用时间  

  1. import   static  com.sun.btrace.BTraceUtils.name;    
  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. * @author jerry  
  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\\.jerry\\../" , 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\\.jerry\\../" , 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. }   

3.监控内存

  1. import   static  com.sun.btrace.BTraceUtils.*;    
  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. * @author jerry  
  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使用方法详解

    主要介绍了Java软件生产监控工具Btrace使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    如何检测线上代码的运行情况---BTrace使用分享

    NULL 博文链接:https://dengminhui.iteye.com/blog/996192

    BTrace监控远程服务器使用实例

    自己做的BTrace监控,Linux服务器上的tomcat工程,压缩包包含BTrace开发所需的jar包 BTrace简单示例代码 jvisualvm.exe如果远程服务器监控JVM虚拟机信息

    btrace扩展功能工具

    1.btrace扩展是在btrace已由功能上进行的扩展,原有功能和使用方式依然没变。目前版本扩展了两个功能:接口时间监控和接口时间调用树监控。扩展之后的btrace功能使用时都不需要写btrace脚本。 2.使用接口时间监控...

    btrace支持jdk1.7 linux下使用

    btrace支持jdk1.7 linux下使用 非常好用哦 呵呵呵呵

    BTrace安装包 btrace-bin-1.3.11.3.zip + btrace-src-1.3.11.3.zip

    btrace-bin直接解压缩配置环境变量后即可运行使用。 java监控调试工具虚拟机监控程序,利用BTrace可以在线监控java程序状态。 BTrace是一种安全,动态的Java跟踪工具。BTrace通过动态(字节码)检测正在运行的Java...

    btrace安装包

    btrace安装包,linux和windows通用,1.3.9版本。可以直接解压缩配置环境变量后运行使用

    btrace api 1.2.chm

    btrace api 1.2 文档,从网上扒下来自己做的,其他地方貌似都没有chm,提供给大家使用 btrace是一个跟踪、监控java程序的小工具,能够在不改变源代码的情况下监控很多东西,比如:方法运行时间、输入输出参数、抛出...

    btrace_extend-master

    btrace_extend-master,解压后上传至服务器即可以使用btrace命令

    Btrace非侵入式调试Java程序神奇win版

    Btrace非侵入式调试Java程序神奇win版本,可以在线调试java应用不需要重新编译

    btrace_ali

    btrace(阿里封装过的,使用更简单)

    btrace.jar

    btrace提供了线上检测java程序的功能,使得可以不重启程序的情况下,在线上对程序进行跟踪。不过在日常的调试维护中,还是建议尽量使用日志来帮忙跟踪调试,btrace只作为辅助性工具

    Btrace-bin-1.3.10,适用于jdk1.7(+)

    java线上问题定位神器,Btrace-bin-1.3.10,适用于jdk1.7(+),解压即可使用,一般人我不告诉他。

    java程序运行跟踪利器Btrace分享

    你还在为各种意想不到的状况烦恼吗?不知如何去及时了解jvm的运行情况吗?java线程、内存使用情况等都可以通过Btrace进行跟踪分析,了解系统运行情况,方便易用!

    一个用于演示btrace功能的demo程序

    这是一个用于演示btrace功能的demo程序, 其中TestJar4是源码,使用maven作为项目管理工具 TestJar4-0.0.1-SNAPSHOT.jar为maven构建之后的jar包 AllMethod.java是trace script

    btrace:BTrace-用于Java平台的安全,动态跟踪工具

    BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace,适用于OpenSolaris应用程序和OS)。 BTrace动态地检测目标应用程序的类以注入跟踪代码(“字节码跟踪”)。 学分 基于 由提供支持 由提供支持 使用优化 ...

    btrace定位生产故障的方法示例

    主要介绍了btrace定位生产故障的方法示例,文中通过示例代码介绍的很详细,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。

    btrace:另一个btrace分支!

    BTrace 版本 2.0 快速总结 ...使用BTrace 安装 将二进制分发文件(* .tar.gz或* .zip)分解到您选择的目录中 您可以将系统环境变量BTRACE_HOME设置为指向包含展开分布的目录。 为了方便起见,可以使用$ B

    webBTraceUtil_for_JDK11

    个人开发的BTrace小工具。不需要再配置BTRACEHOME环境变量,可多人互不影响同时测试。使用方式,请参见:https://blog.csdn.net/jl19861101/article/details/88368830

    webBTraceUtil_for_JDK1.8

    个人开发的BTrace小工具。不需要再配置BTRACEHOME环境变量,可多人互不影响同时测试。使用方式,请参见:https://blog.csdn.net/jl19861101/article/details/88368830

Global site tag (gtag.js) - Google Analytics