BTrace实例

测试业务类

测试接口

package cn.freemethod.business;

public interface SumInter {
    long sum(int num);
}

测试实现类

package cn.freemethod.business;

import javax.annotation.Resource;

@Resource
public class GSumInterImpl implements SumInter{
    @Override
    public long sum(int num) {
        if(num % 2 == 0)
            return (1 + num) * (num / 2);
        else
            return (1 + num) * (num - 1)/2 + (num + 1) /2;
    }
}
package cn.freemethod.business;

import javax.annotation.Resource;

public class SumInterImpl implements SumInter{
    @Override
    public long sum(int num) {
        int sum = 0;
        for(int i =0 ;i<num;i++){
            sum += i;
        }
        return sum;
    }

    @Resource
    public int doSomething(String arg1,Integer arg2){
        return arg1.hashCode() + arg2;
    }
}

启动类

package cn.freemethod.business;

import java.util.Scanner;

public class SumStart {

    public static void main(String[] args) {
        GSumInterImpl gSumInter = new GSumInterImpl();
        SumInterImpl sumInter = new SumInterImpl();
        final Scanner scanner = new Scanner(System.in);
        scanner.nextLine();
        gSumInter.sum(10000);
        sumInter.sum(10000);
        sumInter.doSomething("hello",10);
        scanner.nextLine();

    }
}

这里使用scanner.nextLine();是为了等脚本启动好了手动控制执行。

BTrace脚本

package cn.freemethod.btracet;

import com.sun.btrace.AnyType;
import com.sun.btrace.annotations.*;

import static com.sun.btrace.BTraceUtils.Sys.Env.printEnv;
import static com.sun.btrace.BTraceUtils.Sys.Env.printProperties;
import static com.sun.btrace.BTraceUtils.Sys.Memory.heapUsage;
import static com.sun.btrace.BTraceUtils.Sys.Memory.nonHeapUsage;
import static com.sun.btrace.BTraceUtils.Sys.VM.printVmArguments;
import static com.sun.btrace.BTraceUtils.println;

@BTrace
public class OnMethodTrace {

    static{
        println("--printVmArguments()--");
        printVmArguments();
        println("--printProperties()--");
        printProperties();
        println("--printEnv()--");
        printEnv();
        println("--heapUsage()--");
        println(heapUsage());
        println("--nonHeapUsage()--");
        println(nonHeapUsage());
//        exit();

    }

//    @OnMethod(clazz="/java\\.util\\..*/",method="/.*/")
    @OnMethod(clazz="+java.util.Map",method="/.*/")
    public static void utilMethod(@ProbeClassName String probeClass, @ProbeMethodName String probeMethod) {
        println("utilMethod:" + probeClass + "."  + probeMethod);
    }

    @OnMethod(clazz = "+cn.freemethod.business.SumInter", method = "sum", location = @Location(Kind.RETURN))
    public static void onSum(@ProbeClassName String probeClass, @ProbeMethodName String probeMethod,@Return long sum, @Duration long duration){
        println("onSum:"+ probeClass + "."  + probeMethod + "_" + sum + "_"  + duration);
    }

    @OnMethod(clazz = "cn.freemethod.business.SumInterImpl", method = "@javax.annotation.Resource", location = @Location(value = Kind.RETURN))
    public static void onAnnotationResourceMethod(@Self Object self, String arg1, Integer arg2, @Return AnyType result){
        println("onAnnotationResourceMethod:" + arg1 + "_"  + arg2 + "_" + result);
    }

    @OnMethod(clazz = "@javax.annotation.Resource", location = @Location(value = Kind.LINE, line = 10))
    public static void onLine(int line) {
        println("onLine reached line:10 " + line);
    }
}

执行方式是在BTrace下载下载BTrace,解压在bin目录下执行:

btrace pid OnMethodTrace.java

脚本要拷贝到BTrace的bin目录下,否则就使用绝对路径。pid可以通过jps命令获取到。

更详细的内容可以参考BTrace使用

我们可以看到OnMethodTrace脚本中的static块部分,这一部分主要是打印jvm相关信息的,其实在实际中可能很少用,因为这些都可以jstat,jmap等工具获取到。

所有我们还是来看一下其他的:

//    @OnMethod(clazz="/java\\.util\\..*/",method="/.*/")
    @OnMethod(clazz="+java.util.Map",method="/.*/")

@OnMethod注解是用来拦截指定方法的,clazz属性是指定类,可以使用全限定名或者正则表达式,也可以使用接口(前面添加"+")。method可以是名字也可以是正则表达式。匹配的时候尽量让拦截的方法范围小一些,避免出现性能问题。

@ProbeClassName是注入被拦截方法所在的类的名字 @ProbeMethodName是注入被拦截方法的名字 @Return 是注入拦截时间 @Duration 是注入方法执行时间(单位是纳秒,要除以1000000才是毫秒,location必须是Kind.RETURN) @Self是注入调用被拦截方法的实例(this)

还可以注入被拦截方法的参数,我们看下面这个:

public static void onAnnotationResourceMethod(@Self Object self, String arg1, Integer arg2, @Return AnyType result)

注意:定义一定要按顺序,必须是@Self,参数1,参数2...,@Return

参数也可以使用AnyType[] args来定义,返回值也可以使用AnyType。

@OnMethod(clazz = "@javax.annotation.Resource", location = @Location(value = Kind.LINE, line = 10))

line是指定执行到指定行的时候执行,line=-1的时候是每行都会执行,加参数int line 注入当前行数

输出的内容比较多,大概就像是下面的样子: 实例输出

参考

BTrace下载 BTrace使用

猜你喜欢

转载自my.oschina.net/u/2474629/blog/1797078