转载

BTrace 问题辅助排查工具使用手册

BTrace是神器,可以通过自己编写的脚本,获取应用的一切调用信息。而不需要重启应用!

Btrace 项目信息(你行你上~)

项目地址(源码): http://github.com/btraceio/btrace

打开姿势,操作步骤:

1. 打开 jvisualVm 工具;

2. 加载 BTrace 工具, 先把 插件中心地址更改掉: https://visualvm.github.io/uc/8u131/updates.xml.gz ;

3. 连接到想要 trace 的服务器, 如本地 tomcat;

4. 右击tomcat进程,> Trace application...

5. 写debug程序,样例如下:(在IDE中编写)

6. 直接使用 brace监控: btrace <pid> BtraceScript.java

BTrace 问题辅助排查工具使用手册

来个例子:(拦截 spring 的 doService 方法)

/* BTrace Script Template */

import com.sun.btrace.AnyType;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.Duration;
import com.sun.btrace.annotations.Kind;
import com.sun.btrace.annotations.Location;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;

import static com.sun.btrace.BTraceUtils.currentThread;
import static com.sun.btrace.BTraceUtils.probeLine;
import static com.sun.btrace.BTraceUtils.threadId;

@BTrace
public class TracingScript {
    /* put your code here */
    @OnMethod(
            clazz = "/com.mobanker.microsite.service.borrow.+/",
            method = "/filterTemplatesByUserAmount.*/",
            location = @Location(Kind.RETURN)
    )
    public static void traceExecute(AnyType[] args, @ProbeClassName String name, @ProbeMethodName String method, @Duration long time) {
        long durationTime = time/1000000;
        if(durationTime > 0){
            String output = name + "." + method + "#" + probeLine() + " cost: " + durationTime + "ms, ThreadId:" + threadId(currentThread());
            BTraceUtils.println(output);
            // 打印整体参数
            BTraceUtils.printArray(args);
            // 调用应用的各字段进行反射调用
            BTraceUtils.printFields(args[1]);
            BTraceUtils.printFields(args[2]);
            BTraceUtils.println("over...");
            // 结束符
            BTraceUtils.println("");
        }
    }
}

在IDE中编写时,需要导入 pom.xml 如下:

        <!-- https://mvnrepository.com/artifact/com.sun.tools.btrace/btrace-agent -->
        <dependency>
            <groupId>com.sun.tools.btrace</groupId>
            <artifactId>btrace-agent</artifactId>
            <version>1.1.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.sun.tools.btrace/btrace-boot -->
        <dependency>
            <groupId>com.sun.tools.btrace</groupId>
            <artifactId>btrace-boot</artifactId>
            <version>1.1.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.sun.tools.btrace/btrace-client -->
        <dependency>
            <groupId>com.sun.tools.btrace</groupId>
            <artifactId>btrace-client</artifactId>
            <version>1.1.3</version>
        </dependency>

2. 拦截方法定义,也说是 @OnMethod 注解的作用

Btrace使用@OnMethod注解定义需要分析的方法入口,在@OnMethod注解中,需要指定class、method以及location等,class表明需要监控的类,method表明需要监控的方法!

@OnMethod(
            clazz = "/com.mobanker.microsite.service.borrow.+/",
            method = "/filterTemplatesByUserAmount.*/",
            location = @Location(Kind.RETURN)
    )

1. 正则表达式定位(全匹配是正则的一种特例)

可以用表达式,批量定义需要监控的类与方法。正则表达式需要写在两个 "/" 中间。

通过在拦截函数的定义里注入@ProbeClassName String probeClass, @ProbeMethodName String probeMethod 参数,告诉脚本实际匹配到的类和方法名。

2. 按接口,父类,Annotation定位

比如我想匹配所有的Filter类,在接口或基类的名称前面,加个+ 就行

@OnMethod(clazz="+com.vip.demo.Filter", method="doFilter")

也可以按类或方法上的annotaiton匹配,也就是注解匹配,前面加上@就行

@OnMethod(clazz="@javax.jws.WebService", method="@javax.jws.WebMethod")

3. 构造方法匹配  <init>

@OnMethod(clazz="java.net.ServerSocket", method="<init>")

4. 静态内部类的写法,在类与内部类之间加上"$"

@OnMethod(clazz="com.vip.MyServer$MyInnerClass", method="hello")

3. 拦截时机, 即@Location注解的作用

// Location 的定义
/**
 * This annotation specifies a particular "location" within a
 * traced/probed java method for BTrace probe specifications.
 *
 * @author A. Sundararajan
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Location {
    /**
     * Kind of the location.
     *
     * @see Kind
     */
    Kind value() default Kind.ENTRY;

    /**
     * Specifies where do want to probe with
     * respect to the location of interest.
     *
     * @see Where
     */
    Where where() default Where.BEFORE;

    /**
     * Specifies the fully qualified class name for
     * certain kind of probe locations.
     *
     * <p>
     * <h3>Since 1.3.11</h3>
     * The specification can contain references to user arguments.
     * These references are using Ant style substitution patterns.
     * If a reference is not resolvable the whole probe point will be effectively disabled.
     * <br>
     * <pre>
     * {@code @OnMethod(clazz = "MyClass", method = "myMethod", location = @Location(clazz = "${package}.OtherClass"))}
     * </pre>
     * </p>
     */
    String clazz() default "";

    /**
     * Specifies the method name for
     * certain kind of probe locations.
     *
     * <p>
     * <h3>Since 1.3.11</h3>
     * The specification can contain references to user arguments.
     * These references are using Ant style substitution patterns.
     * If a reference is not resolvable the whole probe point will be effectively disabled.
     * <br>
     * <pre>
     * {@code @OnMethod(clazz = "MyClass", method = "myMethod", location = @Location(clazz = "OtherClass", method = "${method}"))}
     * </pre>
     * </p>
     */
    String method() default "";

    /**
     * Specifies the field name for Kind.FIELD_SET
     * and Kind.FIELD_GET probes.
     *
     * @see Kind#FIELD_GET
     * @see Kind#FIELD_SET
     *
     * <p>
     * <h3>Since 1.3.11</h3>
     * The specification can contain references to user arguments.
     * These references are using Ant style substitution patterns.
     * If a reference is not resolvable the whole probe point will be effectively disabled.
     * <br>
     * <pre>
     * {@code @OnMethod(clazz = "MyClass", method = "myMethod", location = @Location(clazz = "OtherClass", field = "${field}"))}
     * </pre>
     * </p>
     */
    String field() default "";

    /**
     * Specifies field or method type for
     * certain kind of probe locations. The type
     * is specified like in Java source - except
     * the method or field name and parameter names
     * are not included.
     *
     * <p>
     * <h3>Since 1.3.11</h3>
     * The specification can contain references to user arguments.
     * These references are using Ant style substitution patterns.
     * If a reference is not resolvable the whole probe point will be effectively disabled.
     * <br>
     * <pre>
     * {@code @OnMethod(clazz = "MyClass", method = "myMethod", location = @Location(clazz = "OtherClass", type = "${ret} ()"))}
     * </pre>
     * </p>
     */
    String type() default "";

    /**
     * Specifies the line number for Kind.LINE probes.
     *
     * @see Kind#LINE
     */
    int line() default 0;
}

// Kind 的定义
public enum Kind {
    /**
     * <h2>Array element load</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@code type[]} - the array instance</li>
     *   <li>{@link int int} - array index</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain Return} - the return value of the method call (only for {@linkplain Where#AFTER})</li>
     * </ul>
     */
    ARRAY_GET,

    /**
     * <h2>Array element store</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@code type[]} - the array instance</li>
     *   <li>{@link int int} - array index</li>
     *   <li>{@link java.lang.Object Object} - new value</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     * </ul>
     */
    ARRAY_SET,

    /**
     * <h2>Method call</h2>
     * <p>
     * The order and number of unannotated parameters (if provided) must
     * fully match the called method signature. Instead of specific parameter
     * types one can use {@linkplain AnyType} to match any type.
     * <p>
     * If the only unannotated parameter is of type {@link AnyType AnyType[]}
     * it will contain the called method parameters in the order defined by
     * its signature.
     *
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain TargetInstance} - the target instance of the method call
     *       or null if the method is static</li>
     *   <li>{@linkplain TargetMethodOrField} - the name of the method which is called</li>
     *   <li>{@linkplain Return} - the return value of the method call (only for {@linkplain Where#AFTER})</li>
     *   <li>{@linkplain Duration} - the method call duration in nanoseconds (only for {@linkplain Where#AFTER}</li>
     * </ul>
     */
    CALL,

    /**
     * <h2>Exception catch</h2>
     *
     * <p>
     * The order and number of unannotated parameters (if provided) must
     * fully match the probed method signature. Instead of specific parameter
     * types one can use {@linkplain AnyType} to match any type.
     * <p>
     * If the only unannotated parameter is of type {@link AnyType AnyType[]}
     * it will contain the probed method parameters in the order defined by
     * its signature.
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain TargetInstance} - the caught {@linkplain Throwable} (@since 1.3.11)</li>
     * </ul>
     */
    CATCH,

    /**
     * <h2>Checkcast</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@link java.lang.String String} - type to cast to</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain TargetInstance} - the casted instance ({@linkplain AnyType})</li>
     * </ul>
     */
    CHECKCAST,

    /**
     * <h2>Method entry</h2>
     * <p>
     * The order and number of unannotated parameters (if provided) must
     * fully match the probed method signature. Instead of specific parameter
     * types one can use {@linkplain AnyType} to match any type.
     * <p>
     * If the only unannotated parameter is of type {@link AnyType AnyType[]}
     * it will contain the probed method parameters in the order defined by
     * its signature.
     *
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     * </ul>
     */
    ENTRY,

    /**
     * <h2>"return" because of no-catch</h2>
     *
     * <p>
     * The order and number of unannotated parameters (if provided) must
     * fully match the probed method signature. Instead of specific parameter
     * types one can use {@linkplain AnyType} to match any type.
     * <p>
     * If the only unannotated parameter is of type {@link AnyType AnyType[]}
     * it will contain the probed method parameters in the order defined by
     * its signature.
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain Duration} - the method call duration in nanoseconds (only for {@linkplain Where#AFTER}</li>
     *   <li>{@linkplain TargetInstance} - the {@linkplain Throwable} instance (@since 1.3.11)</li>
     * </ul>
     */
    ERROR,

    /**
     * <h2>Getting a field value</h2>
     *
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain TargetInstance} - the field owner instance or null 
     *       if the field is static</li>
     *   <li>{@linkplain TargetMethodOrField} - the name of the method which is called</li>
     *   <li>{@linkplain Return} - the return value of the method call (only for {@linkplain Where#AFTER})</li>
     * </ul>
     */
    FIELD_GET,

    /**
     * <h2>Setting a field value</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@link java.lang.Object Object} - new field value</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that field is static</li>
     *   <li>{@linkplain TargetInstance} - the field owner instance or null 
     *       if the field is static</li>
     *   <li>{@linkplain TargetMethodOrField} - the name of the method which is called</li>
     * </ul>
     */
    FIELD_SET,

    /**
     * <h2>instanceof check</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@link java.lang.String String} - type to check against</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain TargetInstance} - the checked instance ({@linkplain AnyType})</li>
     * </ul>
     */
    INSTANCEOF,

    /**
     * <h2>Source line number</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@link int int} - line number</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     * </ul>
     */
    LINE,

    /**
     * <h2>New object created</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@link java.lang.String String} - object type name</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain Return} - the return value of the method call (only for {@linkplain Where#AFTER})</li>
     * </ul>
     */
    NEW,

    /**
     * <h2>New array created</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@link java.lang.String String} - array type name</li>
     *   <li>{@link int int} - number of dimensions</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain Return} - the return value of the method call (only for {@linkplain Where#AFTER})</li>
     * </ul>
     */
    NEWARRAY,

    /**
     * <h2>Return from method</h2>
     * <p>
     * The order and number of unannotated probe handler parameters (if provided)
     * must fully match the probed method signature. Instead of specific parameter
     * types one can use {@linkplain AnyType} to match any type.
     * <p>
     * If the only unannotated parameter is of type {@link AnyType AnyType[]}
     * it will contain the probed method parameters in the order defined by
     * its signature.
     *
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain Return} - the return value of the method call (only for {@linkplain Where#AFTER})</li>
     *   <li>{@linkplain Duration} - the method call duration in nanoseconds (only for {@linkplain Where#AFTER}</li>
     * </ul>
     */
    RETURN,

    /**
     * <h2>Entry into a synchronized block</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@link java.lang.Object Object} - lock object</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     * </ul>
     */
    SYNC_ENTRY,

    /**
     * <h2>Exit from a synchronized block</h2>
     *
     * <h3>Unannotated probe handler parameters:</h3>
     * <ol>
     *   <li>{@link java.lang.Object Object} - lock object</li>
     * </ol>
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     * </ul>
     */
    SYNC_EXIT,

    /**
     * <h2>Throwing an exception</h2>
     *
     * <p>
     * The order and number of unannotated parameters (if provided) must
     * fully match the probed method signature. Instead of specific parameter
     * types one can use {@linkplain AnyType} to match any type.
     * <p>
     * If the only unannotated parameter is of type {@link AnyType AnyType[]}
     * it will contain the probed method parameters in the order defined by
     * its signature.
     * <h3>Allowed probe handler parameter annotations:</h3>
     * <ul>
     *   <li>{@linkplain ProbeClassName} - the name of the enclosing class</li>
     *   <li>{@linkplain ProbeMethodName} - the name of the enclosing method</li>
     *   <li>{@linkplain Self} - the instance enclosing the declaring method or null
     *       if that method is static</li>
     *   <li>{@linkplain TargetInstance} - the thrown exception (@since 1.3.11)</li>
     * </ul>
     */
    THROW
};

Location 主要属性有 value 和 where, 而 value 则是几个常用的定义点!

定义Btrace对方法的拦截位置,通过@Location注解指定,默认为Kind.ENTRY。可以为同一个函数的不同的Location,分别定义多个拦截函数。

1. Kind.Entry与Kind.Return

Kind.ENTRY:在进入方法时,调用Btrace脚本

Kind.RETURN:方法执行完时,调用Btrace脚本,只有把拦截位置定义为Kind.RETURN,才能获取方法的返回结果@Return和执行时间@Duration

duration的单位是纳秒,要除以 1,000,000 才是毫秒。

2. Kind.Error, Kind.Throw和 Kind.Catch

异常抛出(Throw),异常被捕获(Catch),异常没被捕获被抛出函数之外(Error),主要用于对某些异常情况的跟踪。

在拦截函数的参数定义里注入一个Throwable的参数,代表异常。

3. Kind.Call与Kind.Line

Kind.CALL:分析方法中调用其它方法的执行情况,比如在execute方法中,想获取add方法的执行耗时,必须把where设置成Where.AFTER.

Kind.LINE:通过设置line,可以监控代码是否执行到指定的位置.

下例定义监控bind()函数里调用的所有其他函数:

    @OnMethod(clazz = "java.net.ServerSocket", method = "bind", location = @Location(value = Kind.CALL, clazz = "/.*/", method = "/.*/", where = Where.AFTER))
    public static void onBind(@Self Object self, @TargetInstance Object instance, @TargetMethodOrField String method, @Duration long duration)

所调用的类及方法名所注入到@TargetInstance与 @TargetMethodOrField中。

下例监控代码是否到达了Socket类的第363行。

    @OnMethod(clazz = "java.net.ServerSocket", location = @Location(value = Kind.LINE, line = 363))

4. 如何使用Btrace定位问题

1. 打印this,参数 与 返回值

  @OnMethod(clazz = "java.io.File", method = "createTempFile", location = @Location(value = Kind.RETURN))
  public static void o(@Self Object self, String prefix, String suffix, @Return AnyType result)

如果想打印它们,首先按顺序定义用@Self 注释的this, 完整的参数列表,以及用@Return 注释的返回值。

需要打印哪个就定义哪个,不需要的就不要定义。但定义一定要按顺序,比如参数列表不能跑到返回值的后面。

Self:

如果是静态函数, self为空。

前面提到,如果上述使用了非JDK的类,命令行里要指定classpath。不过,如前所述,因为BTrace里不允许调用类的方法,所以定义具体类很多时候也没意 思,所以self定义为Object就够了。

参数数列表要么不要定义,要定义就要定义完整,否则BTrace无法处理不同参数的同名函数。

用AnyType来定义任意类型的参数,类似于 Object 。

2. 方法执行时,查看对象的实例属性值

再次强调,为了保证性能不受影响,Btrace不允许调用任何实例方法。

比如不能调用getter方法(怕在getter里有复杂的计算),只会通过直接反射来读取属性名。

又比如,除了JDK类,其他类toString时只会打印其类名+System.IdentityHashCode。

println, printArray,都按上面的规律进行,所以只能打打基本类型。

如果想打印一个Object的属性,用printFields()来反射。

如果只想反射某个属性,参照下面打印Port属性的写法。从性能考虑,应把field用静态变量缓存起来。

注意JDK类与非JDK类的区别:

import java.lang.reflect.Field;
//JDK的类这样写就行
private static Field fdFiled = field("java.io,FileInputStream", "fd");
//非JDK的类,要给出ClassLoader,否则ClassNotFound
private static Field portField = field(classForName("com.vip.demo.MyObject", contextClassLoader()), "port");
public static void onChannelRead(@Self Object self) {
    println("port:" + getInt(portField, self));
}

3.TLS,拦截函数间的通信机制

如果要多个拦截函数之间要通信,可以使用@TLS定义 ThreadLocal的变量来共享

@TLS
private static int port = -1;
@OnMethod(clazz = "java.net.ServerSocket", method = "<init>")
public static void onServerSocket(int p){
    port = p;
}
@OnMethod(clazz = "java.net.ServerSocket", method = "bind")
public static void onBind(){
  println("server socket at " + port);
}

4. 谁调用了这个函数(原理:拦截到方法后,把堆栈打出来)

@OnMethod(clazz = "java.lang.System", method = "gc")
public static void onSystemGC() {
    println("entered System.gc()");
    jstack();
}

5. 统计方法的调用次数,且每隔1分钟打印调用次数

@Export static AtomicLong counter = new AtomicLong();
@OnMethod(class="com.**.MyObject",method="add")
public static void run(){
    counter.getAndIncrement();
}
@OnTimer(1000*60)
public static void run(){
    BTraceUtils.println("count: " + connter.get());
    counter.set(0);
}

5. linux 上使用 btrace!

1. 下载压btrace缩包: wget https://github.com/btraceio/btrace/releases/download/v1.3.11.3/btrace-bin-1.3.11.3.zip ;

2. 解压: unzip btrace-bin-1.3.11.3.zip -d btrace-bin-1.3.11.3;

3. cd btrace-bin-1.3.11.3, ./btrace <pid> TracingScript.java, 就可以看效果了;

4. 修改脚本以解决问题;

5. 通过反射机制,可以很方法的得到当前实例的属性值;

        //print one field
        Field oneFiled = BTraceUtils.field("com.xx.test", "name");
        BTraceUtils.println("print one field: " + BTraceUtils.get(oneFiled, args[0]));

6. BTraceUtils.printFields(args[1]); 调用封装好的打印复杂对象;

            // 调用应用的各字段进行反射调用
            BTraceUtils.printFields(args[1]);

BTrace 问题辅助排查工具使用手册

BTrace 问题辅助排查工具使用手册

快速定位你的线上问题!

原文  http://www.cnblogs.com/yougewe/p/10180483.html
正文到此结束
Loading...