BTrace简介与使用说明

       大家在开发过程中总会预告各种个样的BUG,不是什么时候都可以去debug,也不是什么时候都可以去在代码中增加需要的日志,这个时候该如何解决呢?这个时候就是BTrace的大展身手的时候时候了,下面通过对于BTrace的介绍,同时会有一些示例代码希望可以给大家带来一定的了解

  简介

    Btrace (Byte Trace)是sun推出的一款java 动态、安全追踪工具,可以不停机的情况下监控线上情况,并且做到最少的侵入,占用最少的系统资源。BTrace应用较为广泛的原因应该是其安全性和无侵入性,其中热交互技术,使得我们无需启动Agent的情况下动态跟踪分析,其安全性不会导致对目标Java进程的任何破坏性影响,使得BTrace成为我们线上产品问题定位的利器。无侵入性无需我们对原有代码做任何修改,降低上线风险和测试成本,并且无需重启启动目标Java进程进行Agent加载即可动态分析和跟踪目标程序,可以说BTrace可以满足大部分的应用场景。

   安装

    下载BTrace

     BTrace已经迁移到GitHub, 最新到版本是v1.3.11  下载 https://github.com/btraceio/btrace/releases/download/v1.3.11/btrace-bin-1.3.11.zip 后解压到指定目录

       配置BTRACE_HOME

1

vi .bash_profile

1

2

3

4

5

6

JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home

BTRACE_HOME=/Users/david/Downloads/btrace-bin-1.3.11

PATH=$PATH:$BTRACE_HOME/bin:$JAVA_HOME/bin:$HOME/bin

export JAVA_HOME

export BTRACE_HOME

export PATH

 配置完成后执行  source .bash_profile

  在终端中输入btrace 可以看到如下内容

1

2

3

4

5

6

7

8

9

10

11

12

13

14

$ btrace

Usage: btrace <options> <pid> <btrace source or .class file> <btrace arguments>

where possible options include:

  --version             Show the version

  -v                    Run in verbose mode

  -o <file>             The path to store the probe output (will disable showing the output in console)

-u                    Run in trusted mode

  -d <path>             Dump the instrumented classes to the specified path

  -pd <path>            The search path for the probe XML descriptors

  -classpath <path>     Specify where to find user class files and annotation processors

  -cp <path>            Specify where to find user class files and annotation processors

  -I <path>             Specify where to find include files

  -p <port>             Specify port to which the btrace agent listens for clients

  -statsd <host[:port]> Specify the statsd server, if any

  

BTrace使用

  1. jps命令查出需要监控的jvm pid
  2. 编写BTrace跟踪程序 
  3. 执行:btrace <pid> BTrace跟踪程序

注意事项

     Btrace脚本就是一个普通的用@Btrace注解的Java类,其中包含一个或多个public static void修饰的方法,注意拦截方法必须是用public static  void 进行修饰的,如果不是静态方法则会抛出 instance methods are not allowed 这样的异常信息 如果不是public 则会提示btrace methods should be public ;如果有返回则提示信息为:btrace probe methods must return void

       为了保证对目标程序不造成影响,Btrace脚本对其可以执行的动作做了很多限制,如下:

  1. 不能创建对象
  2. 不能抛出或者捕获异常
  3. 不能用synchronized关键字
  4. 不能对目标程序中的instace或者static变量
  5. 不能调用目标程序的instance或者static方法
  6. 脚本的field、method都必须是static的
  7. 脚本不能包括outer,inner,nested class
  8. 脚本中不能有循环,不能继承任何类,任何接口与assert语句

BTrace注解

   对于BTrace的学习离不开对BTrace注解的理解,BTrace注解可以分为类注解 @BTrace 方法注解如@OnMethod 参数注解如:@ProbeClassName 为了后面更好理解demo我们首先从参数注解开始介绍

 @ProbeClassName

       用于标记处理方法的参数,仅用户@OnMethod, 该参数的值就是被跟踪的类名称

 @ProbeMethodName

       用于表姐处理方法的参数,仅用户 @OnMethod,该参数值是被跟踪方法名称

 @Self

     当前截取方法的封闭实例参数

@Return

    当前截取方法的的返回值, 只对 location=@Location(Kind.RETURN) 生效

@Duration

    当前截取方法的执行时间

@TargetInstance

 当前截取方法内部调用的实例

@TargetMethodOrField

   当前截取方法内部被调用的方法名

方法注解重点介绍OnMethod这个也是我们在排查问题时重点使用的.

@OnMethod

     作用

       用于指定跟踪方法到目标类,目标方法和目标位置

    格式

     @OnMethod(clazz=<cname_spec>[, method=<mname_spec>]? [, type=<signature>]? [, location=<location_spec>]?)

    参数说明

         clazz  用于限定目标类

        cname_spec = <class_name> | +<class_name> | /regex/  class_name 是完全限定类名 +class_name 完全限定类名称前加上“+”表示这个类的所有子类或实现,/regex/就是用户识别类名称的标准正则表达式

      method 用户限定目标方法, mname_spec表示简单的方法名称,不包含签名和返回类型;

      type:用户限定目标方法的签名和返回类型 <return_type> ((arg_type(,arg_type)*)?  return_type就是方法的返回类型,如void, java.lang.String; arg_type就是参数类型

     location 用于限定目标方法的位置, 通过@Location注解进行指定

       @Location 属性有:

  1. value 默认值为Kind.ENTRY 即参数的入口位置
  2. where 限定探测位置 默认值为 Where.BEFORE 也可以设置为Where.AFTER
  3. clazz
  4. method
  5. field
  6. type
  7. line

     其中 @Kind注解的值有

  • Kind.ENTRY-被trace方法参数
  • Kind.RETURN-被trace方法返回值
  • Kind.THROW -抛异常
  • Kind.ARRAY_SET, Kind.ARRAY_GET -数组索引
  • Kind.CATCH -捕获异常
  • Kind.FIELD_SET -属性值
  • Kind.LINE -行号
  • Kind.NEW -类名
  • Kind.ERROR -抛异常

    获取截取方法 类,方法,实例,返回值以及耗时信息,限定的类为Map接口的实现类,方法为put 位置为return 之前

1

2

3

4

5

6

7

8

9

10

11

12

13

14

@BTrace

public class TracingScript {

    @OnMethod(clazz="+java.util.Map",method="put",location=@Location(Kind.RETURN))

  public static void testB(@ProbeClassName String pcm,@ProbeMethodName String pmn,@Self Object self,@Duration long duration,@Return  Object result){

      

     println(strcat(strcat(strcat(strcat(pcm,"#"),pmn)," called in"),str(self)));

      

      println(strcat(strcat("result is ",str(result)),strcat(" duration is ",str(duration))));

        

   

     

      }

       

}

  输出的结果是:

 

1

2

3

4

5

6

7

8

java.util.HashMap#put called in{name=javax.management.ObjectName$Property@338bf6b2, type=javax.management.ObjectName$Property@6f24f3ca}

result is null duration is 2488

java.util.HashMap#put called in{javax.management.ObjectName=java.lang.Object@74685cec}

result is null duration is 5692

java.util.HashMap#put called in{type=javax.management.ObjectName$Property@582e822b}

result is null duration is 2957

java.util.HashMap#put called in{name=javax.management.ObjectName$Property@10dc9047, type=javax.management.ObjectName$Property@582e822b}

result is null duration is 2683

  获取截取方法内部调用实例以及方法

1

2

3

4

5

@OnMethod(clazz="+java.util.Map",method="get",location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/"))

     public static void testA(@ProbeClassName String pcm, @TargetInstance Object target, @TargetMethodOrField String field){

      

         println(strcat("target is",strcat(strcat(str(target),"#"),field)));   

     }

  输出的结果是:

1

2

target isjava.io.ObjectStreamClass$WeakClassKey@3952cb51#hashCode

target isjava.io.ObjectStreamClass$WeakClassKey@3952cb51#equals

  

 

@OnTimer

   用于指定跟踪操作定时执行。value用于指定时间间隔

 

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

33

34

import com.sun.btrace.annotations.*;

 

import static com.sun.btrace.BTraceUtils.*;

 

import java.util.Map;

import java.util.concurrent.atomic.AtomicInteger;

 

 

@BTrace

public class TracingScript {

    private static Map<String, AtomicInteger> histo = Collections.newHashMap();

 

    @OnMethod(clazz = "+java.util.Map", method = "put", location = @Location(value = Kind.RETURN, clazz = "/.*/", method = "/.*/"))

    public static void testB(@ProbeClassName String pcm, @ProbeMethodName String pmn, @Self Object self, @Duration long duration, @Return Object result) {

 

        String cn = Reflective.name(classOf(self));

        AtomicInteger ai = Collections.get(histo, cn);

        if (ai == null) {

            ai = Atomic.newAtomicInteger(1);

            Collections.put(histo, cn, ai);

        else {

            Atomic.incrementAndGet(ai);

        }

 

 

    }

 

    @OnTimer(1000)

    public static void print() {

        if (Collections.size(histo) != 0) {

            printNumberMap("Component Histogram", histo);

        }

    }

}

  输出的结果是:

1

2

* Component Histogram *

java.util.HashMap = 130

  

@OnError

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

 @OnEvent

  通过btrace client事件进行触发,在jvisualvm 通过发送事件 就可以触发如下代码

1

2

3

4

5

6

@OnEvent

    public static void printEvent(){

        if(Collections.size(histo)!=0){

                printNumberMap("Component Histogram", histo);

            }  

     }

  

1

2

* Component Histogram *

java.util.HashMap = 131

  

 在jvisualvm中使用BTrace

   首先选择 工具->插件 安装BTrace插件

 

选择需要跟踪的工程,   

来源:https://www.cnblogs.com/wei-zw/p/9502274.html

http://yyk.familydoctor.com.cn/content_21206_974517.html

http://yyk.familydoctor.com.cn/content_21206_973473.html

http://yyk.familydoctor.com.cn/content_21206_973488.html

http://yyk.familydoctor.com.cn/content_21206_973511.html

发布了0 篇原创文章 · 获赞 168 · 访问量 52万+
展开阅读全文

tomcat启动报错,大神们帮忙分析分析

12-31

严重: Error configuring application listener of class org.springframework.web.context.request.RequestContextListener java.lang.ClassNotFoundException: org.springframework.web.context.request.RequestContextListener at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1892) at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1735) at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:495) at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:477) at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:113) at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:5034) at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5634) at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:145) at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:899) at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:875) at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:652) at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1260) at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:2002) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.run(FutureTask.java:262) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览