今天学习了Byteman的一些基础用法,尝试使用Byteman脚本来统计Java应用中方法的耗时。
测试环境:
Java的版本信息:1.8.0_112-ea
Byteman的版本信息:byteman-download-3.0.6
主要步骤:
测试1. 验证Byteman与JDK版本是否兼容,能够正常工作。
BYTEMAN_HOME="/home/cindy/tools/byteman-download-3.0.6"
BYTEMAN_OPT="-javaagent:${BYTEMAN_HOME}/lib/byteman.jar=script:${BYTEMAN_HOME}/trace_main.btm
在java应用的启动命令行中加上上述参数,进行注入。
$ cat trace_main.btm
RULE checkByteman
CLASS MyAppLauncher
METHOD main
AT ENTRY
IF TRUE
DO traceln("*****IN MAIN*****"+System.currentTimeMillis())
ENDRULE
验证log中是否有该行输出。如果有,即byteman能够正常工作。
测试2:获得函数的RT。
调整应用启动命令行,可动态注入规则,方便在不用重启应用的情况下,进行规则的调整。
BYTEMAN_HOME="/home/cindy/tools/byteman-download-3.0.6"
BYTEMAN_OPT="-javaagent:${BYTEMAN_HOME}/lib/byteman.jar=listener:true,boot:${BYTEMAN_HOME}/lib/byteman.jar -Dorg.jboss.byteman.transform.all"
Byteman脚本内容:
$ cat trace_write_rt.btm
RULE trace write.entrytime
CLASS MyWriter
METHOD writeSync
AT ENTRY
IF TRUE
DO createTimer($1)
ENDRULE
RULE trace corgi.write.endtime
CLASS MyWriter
METHOD writeSync
AT EXIT
IF TRUE
DO traceln("-----writeSync RT:-----"+getElapsedTimeFromTimer($1));
deleteTimer($1);
ENDRULE
动态加载规则:
$ sh bin/bmsubmit.sh -l trace_write_rt.btm
应用的log中就会打印出每次调用writeSync方法的RT,时间精度为毫秒。
注意在使用Timer时应该注意的几个问题:
1)为什么要加$1参数?
2)为什么要加deleteTimer($1)?
关于Timer用法的一些澄清,Byteman的作者对timer的详细说明,可以解答上面的问题。
https://issues.jboss.org/browse/BYTEMAN-72