您的位置:首页 > 编程语言 > Java开发

利用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 class

can 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 static
methods of
 com.sun.btrace.BTraceUtils
class 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 void
returning 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: