利用btrace在线监控java程序状态
2016-03-10 16:05
615 查看
btrace介绍
下载地址: https://kenai.com/projects/btrace/downloads/directory/releases/选择版本进行下载,这里下载的是 release-1.2.4 / btrace-bin.zip
这两天在调试程序时,发现一个比较好用的工具-btrace,能够线上监控程序状态,获取运行时数据信息,如方法返回值,参数,调用次数,全局变量,调用堆栈等。
btrace命令行使用
位于bin目录下面主要有6个脚本,3个windows的,另外3个是linux的,分别是btrace、btracec、btracer。具体功能如下:1、btrace
功能: 用于运行BTrace跟踪程序。命令格式:
btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]
示例:
btrace -cp build/ 1200 AllCalls1.java
参数含义:
include-path指定头文件的路径,用于脚本预处理功能,可选;
port指定BTrace agent的服务端监听端口号,用来监听clients,默认为2020,可选;
classpath用来指定类加载路径,默认为当前路径,可选;
pid表示进程号,可通过jps命令获取;
btrace-script即为BTrace脚本;btrace脚本如果以.java结尾,会先编译再提交执行。可使用btracec命令对脚本进行预编译。
args是BTrace脚本可选参数,在脚本中可通过"$"和"$length"获取参数信息。
2. btracec
功能: 用于预编译BTrace脚本,用于在编译时期验证脚本正确性。btracec [-I <include-path>] [-cp <classpath>] [-d <directory>] <one-or-more-BTrace-.java-files>
参数意义同btrace命令一致,directory表示编译结果输出目录。
3. btracer
功能: btracer命令同时启动应用程序和BTrace脚本,即在应用程序启动过程中使用BTrace脚本。而btrace命令针对已运行程序执行BTrace脚本。命令格式:
btracer <pre-compiled-btrace.class> <application-main-class> <application-args>
参数说明:
pre-compiled-btrace.class表示经过btracec编译后的BTrace脚本。
application-main-class表示应用程序代码;
application-args表示应用程序参数。
该命令的等价写法为:
java -javaagent:btrace-agent.jar=script=<pre-compiled-btrace-script1>[,<pre-compiled-btrace-script1>]* <MainClass> <AppArguments>
btrace脚本限制
In particular, a BTrace classcan not create new objects.
can not create new arrays.
can not throw exceptions.
can not catch exceptions.
can not make arbitrary instance or static method calls - only the
public staticmethods of
com.sun.btrace.BTraceUtilsclass may be called from a BTrace program.
can not assign to static or instance fields of target program's classes and objects. But, BTrace class can assign to it's own static fields ("trace state" can be mutated).
can not have instance fields and methods. Only
static public voidreturning methods are allowed for a BTrace class. And all fields have to be static.
can not have outer, inner, nested or local classes.
can not have synchronized blocks or synchronized methods.
can not have loops (
for, while, do..while)
can not extend arbitrary class (super class has to be java.lang.Object)
can not implement interfaces.
can not contains assert statements.
can not use class literals.
jvisualvm 插件
BTrace提供了jvisualvm插件,强烈推荐在jvisualvm中编写和测试BTrace脚本,启动、关闭、发送事件、增加classpath都非常方便。
btrace实例
package baby.btrace; public class CaseObject{ private static int sleepTotalTime=0; private int sleepTotalTime2=0; public boolean execute(int sleepTime) throws Exception{ System.out.println("sleep: "+sleepTime); sleepTotalTime+=sleepTime; sleepTotalTime2=sleepTotalTime+1; sleep(sleepTime); if(sleepTime%2==0) return true; else return false; } public void sleep(int sleepTime) throws Exception { Thread.sleep(sleepTime); } }
package baby.btrace; import java.util.Random; public class CaseObjectMain { int times = 10; public static void main(String[] args) { CaseObjectMain main= new CaseObjectMain(); try { main.begin(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void begin() throws Exception{ CaseObject object=new CaseObject(); while(true){ times++; boolean result=doWork(object); Thread.sleep(1000); } } public boolean doWork(CaseObject object) throws Exception{ Random random=new Random(); boolean temp= object.execute(random.nextInt(1000)); return temp; } }
1、获取返回值,参数等信息
/* BTrace Script Template */ import com.sun.btrace.annotations.*; import static com.sun.btrace.BTraceUtils.*; @BTrace public class TracingScript { /* put your code here */ /*指明要查看的方法,类*/ @OnMethod( clazz="baby.btrace.CaseObject", method="execute", location=@Location(Kind.RETURN) ) /*主要两个参数是对象自己的引用 和 返回值,其它参数都是方法调用时传入的参数*/ public static void traceExecute(@Self baby.btrace.CaseObject object,int sleepTime, @Return boolean result){ println("调用堆栈!!"); println(strcat("返回结果是:",str(result))); jstack(); println(strcat("时间是:",str(sleepTime))); } }
2、获取对象属性值
/* BTrace Script Template */ import com.sun.btrace.annotations.*; import static com.sun.btrace.BTraceUtils.*; @BTrace public class TracingScript { /* put your code here */ /*指明要查看的方法,类*/ @OnMethod( clazz="baby.btrace.CaseObject", method="execute", location=@Location(Kind.RETURN) ) /*主要两个参数是对象自己的引用 和 返回值,其它参数都是方法调用时传入的参数*/ public static void traceExecute(@Self baby.btrace.CaseObject object,int sleepTime, @Return boolean result){ println("调用堆栈!!"); println(strcat("返回结果是:",str(result))); jstack(); println(strcat("时间是:",str(sleepTime))); } }
3、获取方法执行时长
import com.sun.btrace.annotations.*; import static com.sun.btrace.BTraceUtils.*; @BTrace public class TracingScript3 { @TLS private static long startTime = 0; @OnMethod( clazz="baby.btrace.CaseObject", method="execute" ) public static void startExecute(){ startTime = timeNanos(); } @OnMethod( clazz="baby.btrace.CaseObject", method="execute", location=@Location(Kind.RETURN) ) public static void endExecute(@Duration long duration){ long time = timeNanos() - startTime; println(strcat("execute time(nanos): ", str(time))); println(strcat("duration(nanos): ", str(duration))); } }
4、正则匹配和获取方法执行次数
import com.sun.btrace.annotations.*; import static com.sun.btrace.BTraceUtils.*; @BTrace public class TracingScript4 { private static long count; @OnMethod( clazz="/.*/", method="execute", location=@Location(value=Kind.CALL, clazz="/.*/", method="sleep") ) public static void traceExecute(@ProbeClassName String pcm, @ProbeMethodName String pmn, @TargetInstance Object instance, @TargetMethodOrField String method){ println("====== "); println(strcat("ProbeClassName: ",pcm)); println(strcat("ProbeMethodName: ",pmn)); println(strcat("TargetInstance: ",str(classOf(instance)))); println(strcat("TargetMethodOrField : ",str(method))); count++; } @OnEvent public static void getCount(){ println(strcat("count: ", str(count))); } }
5、正则和事件交互
import com.sun.btrace.annotations.*; import static com.sun.btrace.BTraceUtils.*; @BTrace public class TracingScript5 { private static long count; @OnMethod( clazz="/.*/", method="execute", location=@Location(value=Kind.CALL, clazz="/.*/", method="sleep") ) public static void traceExecute(@ProbeClassName String pcm, @ProbeMethodName String pmn, @TargetInstance Object instance, @TargetMethodOrField String method){ println("====== "); println(strcat("ProbeClassName: ",pcm)); println(strcat("ProbeMethodName: ",pmn)); println(strcat("TargetInstance: ",str(classOf(instance)))); println(strcat("TargetMethodOrField : ",str(method))); count++; } @OnEvent public static void getCount(){ println(strcat("count: ", str(count))); } @OnEvent("A") public static void getCountA(){ println("==AAAA==== "); println(strcat("count: ", str(count))); } @OnEvent("B") public static void getCountB(){ println("==BBB==== "); println(strcat("count: ", str(count))); } }
链接:
/article/3877317.html
/content/2744804.html
相关文章推荐
- 在 Eclipse 下利用 gradle 构建系统
- Spring 4.x实现Restful web service
- java spark WordCount
- 动态代理 jdk as cglib asm
- Javac编译器源代码分析
- java实现动态切换上网IP (ADSL拨号上网)
- JAVA 中BIO,NIO,AIO的理解
- Java BIO、NIO、AIO
- Java数据类型和MySql数据类型对应表
- java jvm 参数 -Xms -Xmx -Xmn -Xss 调优总结
- Java中的数据类型
- 利用java开源包进行短信的收发
- Java NIO框架Mina、Netty、Grizzly介绍与对比
- Java常用工具包 Jodd
- Spring Security二
- Spring Security
- NStruts
- java.io.IOException: Negative seek offset
- java threadLocal 测试
- JAVA 变量的概述