package com.dianping.data;
import java.util.Random;
/**
* @author star.li
* @date 16/4/14.
*/
public class Case1{
public static void main(String[] args) throws Exception{
Random random=new Random();
CaseObject object=new CaseObject();
boolean result=true;
while(result){
result=object.execute(random.nextInt(1000));
Thread.sleep(1000);
}
}
}
package com.dianping.data;
/**
* @author star.li
* @date 16/4/14.
*/
public class CaseObject {
private static int sleepTotalTime=0;
public boolean execute(int sleepTime) throws Exception{
System.out.println("sleep: "+sleepTime);
sleepTotalTime+=sleepTime;
Thread.sleep(sleepTime);
return true;
}
}
4.有沒有人調用CaseObject中的特定某行代碼?
1.監控函數的參數、返回值、靜態類成員變量
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
import com.dianping.data.*;
@BTrace public class TraceMethodArgsAndReturn {
@OnMethod(
clazz="com.dianping.data.CaseObject",
method="execute",
location=@Location(Kind.RETURN)
)
public static void traceExecute(@Self CaseObject instance,int sleepTime,@Return boolean result){
println("call CaseObject.execute");
println(strcat("sleepTime is:",str(sleepTime)));
println(strcat("sleepTotalTime is:",str(get(field("com.dianping.data.CaseObject","sleepTotalTime"),instance))));
println(strcat("return value is:",str(result)));
}
}
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodExecuteTime{
@TLS static long beginTime;
@OnMethod(
clazz="com.dianping.data.CaseObject",
method="execute"
)
public static void traceExecuteBegin(){
beginTime=timeMillis();
}
@OnMethod(
clazz="com.dianping.data.CaseObject",
method="execute",
location=@Location(Kind.RETURN)
)
public static void traceExecute(){
println(strcat(strcat("CaseObject.execute time is:",str(timeMillis()-beginTime)),"ms"));
}
}
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodCallee{
@OnMethod(
clazz="com.dianping.data.CaseObject",
method="execute"
)
public static void traceExecute(){
println("who call CaseObject.execute :");
jstack();
}
}
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodLine{
@OnMethod(
clazz="com.dianping.data.CaseObject",
location=@Location(value=Kind.LINE,line=11)
)
public static void traceExecute(@ProbeClassName String pcn,@ProbeMethodName String pmn,int line){
println(strcat(strcat(strcat(strcat(strcat("call ",pcn),"."),pmn),"at line:"),str(line)));
}
}
本文的例子參考bluedavy(畢玄/林昊)的文章:BTrace使用簡介:http://bluedavy.me/?p=185 其他幾篇可以看看的文章:
需要注意的一點是,btrace監控退出後,修改過的class不會被恢復,你的所有的監控代碼依然一直在運行。每次執行你的監控代碼之前會先進行一個判斷,判斷當前是否處於監控中。你的客戶端發起了exit指令後,該方法判斷false,直接return。所以btrace使用退出後會讓你的代碼多走了一個方法調用+一個對象屬性判斷.
使用JVisualVM的BTrace插件
1.安裝BTrace插件
打開VisualVM的工具—插件,在可用插件列表中選擇BTrace Workbench進行安裝

2.選擇java應用,右鍵選擇Trace application...即可打卡BTrace界面

3.在打開的BTrace界面中編寫監控腳本代碼,並執行(可根據需要調整classpath)
