再谈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信息,打印线程启动信息等等。
相关阅读:
《重构不完全指南!》
扫码关注,一起进步
个人博客: http://www.andyqian.com
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
oracle中rollup的使用(rollup和rank的结合使用)
1.rollup的作用 用来对每个分组的数据进行小计或者合计。 2.求每个学生的所有课程成绩的平均分 1)使用pl/sql查询SC表,这个表是安装oracle时默认安装的scott用户下的表。 2)查询每个学生的平均成绩 3.统计所有学生的平均成绩 那我们如何将每个学生的平均成绩和所有学生的平均成绩放在一个查询结果里呢?这就需要使用到rollup函数。 4.rollup函数的使用 1)使用rollup select t.sno, avg(t.score) from SC t group by rollup(t.sno); 2)改进rollup 上一个查询结果第5行的SNO字段是空的,需要我们填入默认值。这里可以使用nvl函数。 select nvl(t.sno,'所有学生'), avg(t.score) from SC t group by rollup(t.sno); 5.学生平均成绩排名,rank函数的使用 select t.sno, avg(t.score) "平均分", rank() over(order by avg(t.score) desc) "成绩排名" from S...
- 下一篇
一篇文章从了解到入门shell
请注明文章来源:http://blog.zjiecode.com/2019/04/15/shell/ 1、shell介绍 shell 俗称叫做壳,计算机的壳层,和内核是相对的,用于和用户交互,接收用户指令,调用相应的程序。 因此,把shell分为2大类 1.1、图形界面shell(Graphical User Interface shell 即 GUI shell) 也就是用户使用GUI和计算机核交互的shell,比如Windows下使用最广泛的Windows Explorer(Windows资源管理器),Linux下的X Window,以及各种更强大的CDE、GNOME、KDE、 XFCE。 他们都是GUI Shell。 1.2、命令行式shell(Command Line Interface shell ,即CLI shell) 也就是通过命令行和计算机交互的shell。 Windows NT 系统下有 cmd.exe(命令提示字符)和近年来微软大力推广的 Windows PowerShell。 Linux下有bash / sh / ksh / csh/zsh等 一般情况下,习惯把...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Linux系统CentOS6、CentOS7手动修改IP地址
- SpringBoot2全家桶,快速入门学习开发网站教程
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS6,CentOS7官方镜像安装Oracle11G
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS7,CentOS8安装Elasticsearch6.8.6
- CentOS8编译安装MySQL8.0.19