java btrace_再谈Java 生产神器 BTrace

本文首发于个人公众号《andyqian》,期待你的关注~

前言

在上一篇文章《Java 生产神器 BTrace》中我们认识了BTrace,并了解到 BTrace 脚本如何编写,如何执行,不熟悉的朋友,也可以对着文章照葫芦画瓢。但对于我们技术人来说,仅有这些是不够的,我们必须弄清楚每一个参数的意义,用法,才能百变不离其宗。另外,在这基础之上,还有一些更高阶的用法也是需要我们掌握的。

用法

在 BTrace 的用户指南中,将 BTrace 的常用用法分为类注解,方法注解,方法参数注解,它们各司其职,构造成了BTrace。下面分别介绍其使用方法:

类注解

@BTrace 注解的作用域为类,我们可以理解像Java类中的 class 关键字一样的作用。作用域与之类似的还有:DTrace,DTraceRef,这两个注解涉及到另外一种脚本语言,且不常用,不在本文中展开。

方法注解@com.sun.btrace.annotations.OnMethod

在方法注解中,最常见的莫过于@OnMethod,顾名思义,该注解作用于trace方法上。在该注解中,有三个非常重要的属性:clazz 表示我们需要监听类的全限定名称,也支持匹配子类。例如:下述示例 3所述,也可以通过正则匹配多个类中的多个方法,如示例 4 中所示。

method 表示我们需要监听的方法,同样的也支持正则匹配。

location 表示 trace 脚本在方法中执行的位置。

其可选值为com.sun.btrace.annotations.Kind 枚举中的值,常用的有以下值:CALL 当追踪方法被调用时执行。

CATCH 当追踪方法捕获异常时执行。

ENTRY 当进入追踪方法时执行(默认值)。

ERROR 当追踪方法发生错误时执行。

LINE 当执行到指定的代码上时执行,当值为-1时,方法中的所有代码行。

RETURN 当追踪方法返回时执行,一般搭档 @Duration 注解进行方法耗时的记录。

THROW 当追踪方法抛出异常时执行。

2. @com.sun.btrace.annotations.OnTimer

该注解作用于方法上,一般用于周期性执行任务。该注解中包括两个属性,其中 常用的 value 属性表示时间间隔,单位为毫秒。有一个典型的案例,可以通过 OnTimer 注解来统计某个方法在一定时间段的请求次数。例如在1分钟内,某个方法的调用次数。代码如下:

待监听的方法添加如下代码:

BTraceUtils.Atomic.getAndIncrement(callCount);

OnTimer 代码如下:

static AtomicLong callCount = BTraceUtils.Atomic.newAtomicLong(1);

@OnTimer(value=1000*60)

public static void print() {

BTraceUtils.println("count: "+ BTraceUtils.Atomic.get(callCount));

BTraceUtils.println();

}

3. @com.sun.btrace.annotations.OnError

该注解作用于 BTrace 脚本,当BTrace类本身发生错误时会触发该方法的执行。

4. @com.sun.btrace.annotations.OnExit

当BTrace脚本中显示调用BTraceUtils.exit();方法时则会调用该注解引用的方法,调用该方法后,BTrace 脚本则会退出监听状态。示例代码如下:

@OnExit

public static void printOnExit(int code) {

BTraceUtils.println("====exit========"+code);

BTraceUtils.println();

}

5. @com.sun.btrace.annotations.OnEvent

该注解应用于事件,当我们在使用 BTrace 客户端 Ctrl+C 时,会显示如下选项,我们选择 2 则会发送一个默认的SIGINT事件。当然了,我们也可以指定事件名称。例子如下:

EBUG: received com.sun.btrace.comm.OkayCommand@4148db48

Please enter your option:

1. exit

2. send an event

3. send a named event

4. flush console output

2

DEBUG: sending event command

DEBUG: received com.sun.btrace.comm.MessageCommand@282003e1

====recevied event action========

默认事件,监听代码如下:

@OnEvent

public static void printOnEvent(){

BTraceUtils.println("====recevied event action========");

BTraceUtils.println();

}

指定事件名称的事件的示例代码,(通过Ctrl+C 选择选项3 并输入相同的事件名称即可触发):

@OnEvent("evenName")

public static void printOnEventName(){

BTraceUtils.println("====recevied event action event Name========");

BTraceUtils.println();

}

方法参数注解@ProbeClassName 表示监听类的全限定名称,与 @OnMethod 注解中的 clazz 中的值是一致的。

@ProbeMethodName 表示监听方法的名词,与 @OnMethod 注解中的 method 属性中的值是一致的。

@Duration 表示方法的持续时间,一般用于方法耗时,在性能分析以及慢执行方面用的比较多,单位为纳秒。

@Self 表示当前对象,与Java中的this关键字的作用是一致的。

@Return 表示方法的返回对象。

AnyType 这个非常有用,表示任意类有一个比较典型的案例:当监听方法的参数为对象时怎么办?使用AnyType轻松搞定,如示例 5 所示:

@OnLowMemory 该注解用于内存监控,其有两个比较重要的参数: pool 表示需要监听的内存区域,具体名称与GC算法有关,threshold 表示阀值,超过阀值时则会触发。如示例6所示:

示例

1. 判断是否执行过指定行:

@OnMethod(clazz="com.jq.wechat.facade.srv.impl.AuthRestServiceImpl",method = "getUserInfo",location=@Location(value=Kind.LINE,line = 48))

public static void online(@ProbeClassName String pcn @ProbeMethodName String pmn, int line) {

BTraceUtils.println(pcn + "." + pmn + ":" + line);

BTraceUtils.println();

}

当然,方法中的参数是可选的,也可以省略掉。其中 line 的值 就是 当前BTrace脚本监控的绝对行数。

2. 打印系统属性以及运行:

@BTrace

public class JInfo {

static {

println("System Properties:");

printProperties();

println("VM Flags:");

printVmArguments();

println("OS Enviroment:");

printEnv();

println();

}

}

3. 监听所有实现 Runnalbe 接口类中的run方法:

@BTrace

public class SubtypeTracer {

@OnMethod(

clazz="+java.lang.Runnable",

method="run"

)

public static void onRun(@ProbeClassName String pcn, @ProbeMethodName String pmn) {

print(pcn);

print('.');

println(pmn);

}

}

4. 表示匹配 java.io中所有包括类名中包含Input关键字的类中包含read关键字的方法:

@BTrace public class MultiClass {

@OnMethod(

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

method="/read.*/"

)

public static void onread(@ProbeClassName String pcn) {

println("read on " + pcn);

}

}

5. 当参数为对象类型,打印参数以及返回参数:

@OnMethod(clazz="com.jq.wechat.facade.srv.impl.AuthRestServiceImpl",method="getUserInfo",location=@Location(value=Kind.RETURN))

public static void printUserInfo(AnyType params,@Return AnyType type){

BTraceUtils.print("=====");

BTraceUtils.println("====params=====");

BTraceUtils.printFields(params);

BTraceUtils.println("====return result=====");

BTraceUtils.printFields(type);

BTraceUtils.println();

}

当参数为参数列表时,可以参考在文章《Java 生产神器 BTrace》的用法,这里就不再详细介绍。

6. 打印内存参数

@BTrace

public class MemAlerter {

@OnLowMemory(

pool = "Tenured Gen",

threshold=6000000

)

public static void onLowMem(MemoryUsage mu) {

println(mu);

}

最后

在上述中,给出了 BTrace 脚本的使用方法,并详细介绍了常用参数的意义,在文章最后给出了一些例子。当然了,你也可以在BTrace的用户指南中找到更多的例子。例如:打印jstack信息,打印线程启动信息等等。

相关阅读:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值