BTrace小结(+houseMD使用)

之前很早有同事分享过Btrace的原理,基于java Instruction 实现的,方便跟踪代码。对于线上应用,我们不能进行debug来获取运行的详细信息,通过BTrace可以搞定一些问题。Btrace使用到的技术主要有

•Java Compiler API;•Annotation Processing;•Java Agent;•ASM 4;•Attach API;•jvmstat;•JMX

术语主要有三个:

Probe Point 在何处执行trace语句, 这里的"何处"可以是具体的跟踪地点和执行事件, 在BTrace中通过各种注解来指定 
Trace Actions or Actions在何时执行trace语句 
Action Methods 定义在trace脚本中的trace语句, 具体来说就是脚本中的无返回值静态方法(1.2之后可以是非静态方法)

使用BTrace

(1)下载BTrace的工程代码

mkdir /home/admin/btrace

cd /home/admin/btrace

wget  http://kenai.com/downloads/btrace/releases/release-1.2.2/btrace-bin.tar.gz 

tar -xzvf  /home/admin/btrace/btrace-bin.tar.gz

export JAVA_HOME=/java

(2)编写自定义的BTrace脚本(java文件)

常用的几个注解

A、方法上的注解OnMethod

clazz: 类名称,可以是全称,也可以是正则表达式(也可以是正则表达式(表达式必须写在"//"中, 比如"/java\\.awt\\..+/").)

例如: clazz="+java.lang.ClassLoader"--》实现ClassLoader接口的类;

method:方法名称,

location:例如location=@Location(Kind.RETURN)是一个枚举值

例如:

 @OnMethod(

        clazz="/java\\.io\\..*Input.*/",

        method="/read.*/"

    )

B 、方法上的注解OnTimer 用来指定时长(ms)执行一次trace. 时长通过"value"属性指定。例如   @OnTimer(4000) 

C、 其他方法上的注解、

  • OnError 当trace代码抛异常时该注解的方法会被执行. 如果同一个trace脚本中其他方法抛异常, 该注解方法也会被执行.

  • OnExit 当trace方法调用内置exit(int)方法(用来结束整个trace程序)时, 该注解的方法会被执行. 参考自带例子ProbeExit.java.

  • OnEvent 用来截获"外部"btrace client触发的事件, 比如按Ctrl-C 中断btrace执行时将执行使用了该注解的方法, 该注解的value值为具体事件名称. 

  • OnLowMemory 当内存超过某个设定值将触发该注解的方法, 具体参考MemAlerter.java

D、参数上的注解:Self 用来指定被trace方法的this

E、参数上的注解:Return 用来指定被trace方法的返回值

F、参数上的注解:ProbeClassName 和ProbeMethodName  被trace的类名称和方法名称

G、参数:.TargetInstance (since 1.1) 用来指定被trace方法内部被调用到的实例

H、参数:TargetMethodOrField (since 1.1) 用来指定被trace方法内部被调用的方法名, 可参考例子AllCalls1.java 合 AllCalls2.java

I、属性上的注解:TLS 将一个脚本变量与一个ThreadLocal变量关联

常用的几种脚本

A、查看一个方法的入参和返回值

B、查看一个方法执行耗时

C、谁调用这个方法

D、代码中的特定行有没有被调用

下面转自毕玄的博客:http://rdc.taobao.com/team/jm/archives/509

 

(3)命令运行自定义脚本(获取反馈信息)

运行一个例子程序(-cp是设置环境变量,18528是java的进程ID,然后后面是编写的java的文件)

btrace -cp [btrace的jar所在的路径,默认为btrace/build下] [pid] [需要运行的java代码]

sudo -u admin sh  btrace -cp /home/admin/btrace/build 18528 /home/admin/btrace/samples/ThreadCounter.java 

代码备注:

获取一个类中方法的返回值、响应时间以及调用情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import  static  com.sun.btrace.BTraceUtils.*;
import  com.sun.btrace.annotations.*;
@BTrace
public  class  BtraceAll {
     @TLS
     private  static  long  beginTime;
     @OnMethod (
             clazz= "com.taobao.commonway.core.service.impl.TimeInfoManagerImpl" ,
             method= "getCityName"
     )
     public  static  void  traceMethodBegin(){
         beginTime = timeMillis();
     }
     @OnMethod (
             clazz= "com.taobao.commonway.core.service.impl.TimeInfoManagerImpl" ,
             method= "getCityName" ,
             location= @Location (Kind.RETURN)
     )
     public  static  void  traceMethdReturn(
             @Return  String result,
             @ProbeClassName  String clazzName,
             @ProbeMethodName  String methodName){
         println( "===========================================================================" );
         println(strcat(strcat(clazzName,  "." ), methodName));
         println(strcat( "Time taken : " , str(timeMillis() - beginTime)));
         println( "java thread method trace:---------------------------------------------------" );
         jstack();
         println( "----------------------------------------------------------------------------" );
         println(strcat( "Reuslt :" ,str(result)));
         println( "============================================================================" );
     }
}

参考:

http://rdc.taobao.com/team/jm/archives/509

 http://kenai.com/projects/btrace/ 

http://macrochen.iteye.com/blog/838920

=========================================================================================================

下面是houseMD的使用,感觉比btrace好用一点,但是灵活性不是很高,常见问题都能用一下。

安装

(1)sudo -u admin  curl -Lk https://raw.github.com/zhongl/HouseMD/master/bin/install

(2) sudo -u admin sh install.sh  | bash

(3) export JAVA_HOME=/opt/taobao/java

(4)sudo -u admin /home/admin/houseMD/housemd -h  23259 ( java pid)进入housemd的控制台

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#! /bin/bash
                           
CHECKSUM= "checksum"
                           
curl -Lk https: //api .github.com /repos/zhongl/HouseMD/downloads  grep  -E  "[0-9a-f]+\s+[^ \"]+"  -o |  head  -1 > $CHECKSUM
                           
JAR_NAME=` cat  $CHECKSUM |  grep  -E housemd.+ -o`
                           
curl -Lk https: //github .com /downloads/zhongl/HouseMD/ $JAR_NAME > $JAR_NAME
                           
SHASUM=` which  shasum ||  which  sha1sum`
                                                                                                                 
if  [ -z $SHASUM ];  then
     echo  "Warning, shasum or sha1sum could not find to validate the download jar."
else
     $SHASUM -c $CHECKSUM || {
         rm  -rf $JAR_NAME $CHECKSUM ;
         echo  "Download failed, please try again!" ;
         exit  1;
     }
fi
                           
mv  $JAR_NAME housemd.jar
rm  -rf $CHECKSUM
curl -Lk https: //raw .github.com /zhongl/HouseMD/master/bin/housemd  > housemd
chmod  u+x housemd

(1)查看类加载路径(loaded 类名称,如果查看加载层次,加参数-h)

1
2
3
housemd> loaded CollectionUtil
com.taobao.util.CollectionUtil -> /home/admin/commonway/. default /deploy/commonway.war/WEB-INF/lib/util- 1.0 .jar
com.alibaba.citrus.util.CollectionUtil -> /home/admin/commonway/. default /deploy/commonway.war/WEB-INF/lib/citrus-webx-all-in-one- 3.0 . 3 .jar

(2)查看一个类或者特定方法的运行情况

-t 时间  一定时间的运行情况

-s 打出栈信息

-d打印详细信息

打印接下来10秒内方法的调用情况(方法全名(含参数列表), 当前类的加载器对象, 总计调用次数, 平均调用耗时, 调用的自身对象

1
2
3
4
5
6
7
8
9
housemd> trace -t  10  TimeInfoManagerImpl.querySellerAvgSpeed
INFO : Probe  class  com.taobao.commonway.core.service.impl.TimeInfoManagerImpl
No traced method invoked
  
com/taobao/commonway/core/service/impl/TimeInfoManagerImpl.querySellerAvgSpeed( long , String)    sun.misc.Launcher$AppClassLoader @4aad3ba4             3             5ms    com.taobao.commonway.core.service.impl.TimeInfoManagerImpl @794352d2
  
INFO : Ended by timeout
INFO : Reset  class  com.taobao.commonway.core.service.impl.TimeInfoManagerImpl

打印调用的详细信息

1
2
3
4
5
6
7
8
9
10
11
housemd> trace -d TimeInfoManagerImpl.querySellerAvgSpeed
INFO : Probe  class  com.taobao.commonway.core.service.impl.TimeInfoManagerImpl
No traced method invoked
            
No traced method invoked
            
com/taobao/commonway/core/service/impl/TimeInfoManagerImpl.querySellerAvgSpeed( long , String)    sun.misc.Launcher$AppClassLoader @4aad3ba4             1             3ms    com.taobao.commonway.core.service.impl.TimeInfoManagerImpl @794352d2
            
INFO : You can get invocation detail from /tmp/trace/ 23259 @commonway079145 .pre.cm3.tbsite.net/detail
INFO : Ended by timeout
INFO : Reset  class  com.taobao.commonway.core.service.impl.TimeInfoManagerImpl

日志中的详细信息

日期, 时间戳, 调用耗时, 调用线程名, 调用方法的自身对象, 调用方法全名, 调用方法参数值列表, 返回值(或异常)

1
2
3
4
5
6
7
8
9
10
more /tmp/trace/ 23259 @commonway079145 .pre.cm3.tbsite.net/detail
          
2012 - 11 - 20  16 : 44 : 06  3ms [http- 0.0 . 0.0 - 7001 - 6 ] com.taobao.commonway.core.service.impl.TimeInfoManagerImpl @794352d2 com/taobao/commonw
ay/core/service/impl/TimeInfoManagerImpl.querySellerAvgSpeed [ 341952863  121.0 . 29.228 ] com.taobao.commonway.common.TimeResultDO @1a882
b79[
   consignTime= 20
   timeCost= 66
   industryCtime= 21
   industryStime= 44
]

(3)查看类中属性的值(inspect 类名称)( 属性全名, 属性值, 自身对象实例 , 此类的类加载器

1
2
3
4
5
6
7
8
9
10
housemd> inspect TimeResultDO.consignTime
INFO : Probe  class  com.taobao.commonway.common.TimeResultDO
TimeResultDO.consignTime  20  com.taobao.commonway.common.TimeResultDO @eec91ef [
   consignTime= 20
   timeCost= 66
   industryCtime= 21
   industryStime= 44
] org.jboss.mx.loading.UnifiedClassLoader3 @37debcf3 { url=file:/home/admin/commonway/. default /deploy/commonway.war/ ,addedOrder= 44 }
INFO : Ended by timeout
INFO : Reset  class  com.taobao.commonway.common.TimeResultDO

https://github.com/zhongl/HouseMD/wiki/UserGuideCN

https://github.com/downloads/zhongl/HouseMD/housemd_2.9.2-0.2.4.min.jar

猜你喜欢

转载自iamzhongyong.iteye.com/blog/1729743