`
san_yun
  • 浏览: 2652447 次
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

btrace学习总结

 
阅读更多

当程序结果出现异常情况,但是没有日志报错的情况下,btrace成了最后的救命稻草。本文对btrace的使用进行总结。

首先推荐官方用户手册:https://kenai.com/projects/btrace/pages/UserGuide

 

btrace使用方法  

 命令格式: 

btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>] 

 示例: 

btrace -cp common.jar  1200 AllCalls1.java 

注: common.jar不是必须的,如果只是打印耗时不需要

参数含义: 

  • include-path指定头文件的路径,用于脚本预处理功能,可选; 
  • port指定BTrace agent的服务端监听端口号,用来监听clients,默认为2020,可选; 
  • classpath用来指定类加载路径,默认为当前路径,可选; 
  • pid表示进程号,可通过jps命令获取; 
  • btrace-script即为BTrace脚本;btrace脚本如果以.java结尾,会先编译再提交执行。可使用btracec命令对脚本进行预编译。 
  • args是BTrace脚本参数,在脚本中可通过"$"和"$length"获取参数信息,可选;

btrace案例

  1. 一次奇异的getRegionInfo异常定位
  2. perftools查看堆外内存并解决hbase内存溢出
  3. btrace记忆
  4. 使用Btrace查看某个线程池活跃线程大小

常见使用场景 

0.最常用的情况,查看某个方法耗时:

import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.Return;
import com.sun.btrace.annotations.Self;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;

@BTrace
public class IndexSearcher {

	 @TLS static long beginTime=0;  

	 
	@OnMethod(clazz="com.taobao.tlog.servlet.DataChartAction_Curve", method="execute")
	public static void test(){
    		 beginTime=timeMillis();
		
   	}		


	@OnMethod(clazz="com.taobao.tlog.servlet.DataChartAction_Curve", method="execute",location=@Location(Kind.RETURN))
	public static void test_end()throws Exception {
		println(strcat(strcat("Search .execute time is:",str(timeMillis()-beginTime)),"ms"));
		
	}
}

 如果没有打印可能出现的问题是:

1. interface是不会打印的,clazz请填写具体的实现类(已代码验证过)

 

 

1.获取方法参数值和返回值

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
   @OnMethod(
      clazz="com.learnworld.Counter",
      method="add",
      location=@Location(Kind.RETURN)
   )
   public static void traceExecute(int num,@Return int result){
     println("====== ");
     println(strcat("parameter num: ",str(num)));
     println(strcat("return value:",str(result)));
   }
}

  

import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.Return;
import com.sun.btrace.annotations.Self;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
import com.taobao.eagleeye.model.RpcBased;

@BTrace(unsafe=true) 
public class EgTest2 {

	@OnMethod(clazz="com.taobao.eagleeye.data.ip.IpAppMapper", method="getAppName",location=@Location(Kind.RETURN))
	public static void search(String ip,@Return String result){
		println(strcat(ip,result));
   	}		


}

 

2.定时获取Counter类的属性值totalCount。 

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
   private static Object totalCount = 0;
   
   @OnMethod(
      clazz="com.learnworld.Counter",
      method="add",
      location=@Location(Kind.RETURN)
   ) 
   public static void traceExecute(@Self com.learnworld.Counter counter){
     totalCount = get(field("com.learnworld.Counter","totalCount"), counter);
   } 
    
   @OnTimer(1000)
   public static void print(){
     println("====== ");
     println(strcat("totalCount: ",str(totalCount)));
   }
}

 

 3. 获取add方法执行时间。

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
   @TLS private static long startTime = 0;
   
   @OnMethod(
      clazz="com.learnworld.Counter",
      method="add"
   ) 
   public static void startExecute(){
     startTime = timeNanos();
   } 
    
   @OnMethod(
      clazz="com.learnworld.Counter",
      method="add",
      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)));
   } 
}

 

import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.Return;
import com.sun.btrace.annotations.Self;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
import org.apache.lucene.search.*;
import org.apache.lucene.index.*;

@BTrace
public class MultiTermQueryWrapperFilter {

	 @TLS static long beginTime=0;  

	@OnMethod(clazz="org.apache.lucene.search.MultiTermQueryWrapperFilter", method="getDocIdSet")
	public static void traceExecuteBegin(){
    		 beginTime=timeMillis();
   	}		


	@OnMethod(clazz="org.apache.lucene.search.MultiTermQueryWrapperFilter", method="getDocIdSet",location=@Location(Kind.RETURN))
	public static void mergeArray()throws Exception {
		println(strcat(strcat("MultiTermQueryWrapperFilter .execute time is:",str(timeMillis()-beginTime)),"ms"));
	}
}

 

 

4. 获取add()方法调用方法sleep()次数。 

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
   private static long count; 
     
   @OnMethod(
      clazz="/.*/",
      method="add",
      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)));
   }
}

 

3. 获取参数的成员变量

@BTrace
public class OracleTimeoutTracer {

    @OnMethod(clazz = "oracle.net.nt.ConnStrategy", method = "createSocketOptions", location = @Location(value = Kind.ENTRY))
    public static void strategy(@Self Object self, Properties paramProperties) {
        println(str(paramProperties));
    }

    @OnMethod(clazz = "oracle.net.nt.TcpNTAdapter", method = "connect", location = @Location(value = Kind.ENTRY))
    public static void adapter(@Self Object self) {
        Field socketTimeoutField = field("oracle.net.nt.TcpNTAdapter", "sockTimeout");
        Field hostField = field("oracle.net.nt.TcpNTAdapter", "host");
        Field portField = field("oracle.net.nt.TcpNTAdapter", "port");
        int scoketTimeout = (Integer) get(socketTimeoutField, self);
        int port = (Integer) get(portField, self);
        String host = (String) get(hostField, self);

        println(strcat(strcat(strcat(strcat(strcat("host : ", host), ", port : "), str(port)), " , socketTimeout : "),
                       str(scoketTimeout)));
    }
}

 

import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.Return;
import com.sun.btrace.annotations.Self;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
import com.taobao.eagleeye.model.RpcBased;

@BTrace(unsafe=true) 
public class EgTest1 {

	@OnMethod(clazz="com.taobao.eagleeye.digest.RealtimeDigester", method="generateStat")
	public static void search(RpcBased rpcBased){

		Object clientAppName = get(field("com.taobao.eagleeye.model.RpcBased","clientAppName"), rpcBased);
		Object serverAppName = get(field("com.taobao.eagleeye.model.RpcBased","serverAppName"), rpcBased);
		Object serviceId = get(field("com.taobao.eagleeye.model.RpcBased","serviceId"), rpcBased);
		Object host = 	get(field("com.taobao.eagleeye.model.RpcBased","host"), rpcBased);

		String a = strcat(str(clientAppName),",");
		String b = strcat(str(serverAppName),",");
		String c = strcat(str(serviceId),",");	
		String e = strcat(str(host),",");

		String n1 = strcat(a,b);
		String n2 = strcat(c,e);
		println(strcat(n1,n2));


   	}		


}

 

 

 问题总结

 

1. btrace报错:Port 2020 unavailable

admin@eagleeyetlog128031 bin]$ ./btrace -cp eagleeye-common.jar 122810 EgTest1.java 
Port 2020 unavailable.

原因是btrace会在remote JVM(pid:122810)agent开启一个远程socketserver,默认端口是2020,正好我这台服务器有多个JVM实例,当我在第一个JVM上执行之后,第一个就会报错。正确的做法是:./btrace -cp eagleeye-common.jar -p 2021 53523 EgTest1.java 。

 

2. btrace报错:method calls are not allowed - only calls to BTraceUtils are allowed

原因是btrace存在安全限制,不允许调用被agent对象的方法。晚上说可以通过设计Dcom.sun.btrace.unsafe=true破解btrace的安全限制,但我试过不行。

 

3. 私有方法的访问

private method可以被直接访问到的

import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.Return;
import com.sun.btrace.annotations.Self;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
import com.taobao.eagleeye.model.RpcBased;
import com.taobao.tlog.keyvalue.KVRecord;
import com.taobao.eagleeye.rt.DigestLogContext;

@BTrace(unsafe=true)
public class EgTest4 {

        @OnMethod(clazz="com.taobao.eagleeye.digest.RealtimeDigester", method="fastFilter")
        public static void search(DigestLogContext context){
                println("haha");
        }


}

这个方法是private,但会打印

分享到:
评论

相关推荐

    BTrace自我总结测试代码

    **BTrace 自我总结测试代码** BTrace 是一个强大的、安全的、动态的Java应用程序诊断工具,由Sun Microsystems(现已被Oracle收购)开发。它允许开发者在运行时对应用程序进行探查,而无需修改源代码或重启服务。...

    Btrace 学习1

    【标题】:“Btrace 学习1” 【描述】: BTrace 是一款强大的动态跟踪工具,它允许开发者在运行时对 Java 应用程序进行安全、低开销的诊断和性能分析。BTrace 基于 Sun/Oracle 的 Jitrino.JIT 和 Dynamic Code ...

    btrace release-1.2.5.1

    总结来说,"btrace release-1.2.5.1" 是一个包含了BTrace工具的完整发布包,用户可以通过这个包了解并使用BTrace进行Java应用的动态追踪。从提供的文件列表中,我们可以获取到版权信息、许可证、第三方库信息、安装...

    jvisualvm btrace插件离线安装

    在Java开发领域,性能优化是不可或缺的一环,而BTrace作为一个强大的动态跟踪工具,可以帮助开发者实时监控和分析应用程序的行为。本文将详细介绍如何在jVisualVM上进行BTrace插件的离线安装,以便在无法在线安装的...

    Btrace资源

    **Btrace资源详解** Btrace 是一个强大的Java应用程序动态...然而,为了充分利用这些工具,你需要学习Btrace的语法和使用方法,并理解如何编写有效的Btrace脚本。记得参考相关的文章或官方文档来获取更详细的指导。

    btrace1.3.9.zip

    总结,BTrace 1.3.9作为一款强大的Java诊断工具,结合了对JDK 1.8的良好支持和Maven的便利性,使得开发者能够更高效地定位和解决问题。通过熟练掌握BTrace,我们可以提升对Java应用程序的理解和控制,从而优化系统...

    btrace安装包

    7. **总结** BTrace作为一款强大的Java诊断工具,为开发者提供了一种在生产环境中实时监控和诊断应用的新途径。正确安装和使用BTrace,能够显著提高问题定位的效率,降低运维成本,是每个Java开发者和运维人员的...

    jdk1.8-Btrace.rar

    【标题】"jdk1.8-Btrace.rar"指的是一个针对Java开发的特殊工具包,它包含了一个名为Btrace的在线检测插件。这个插件专为Java开发者设计,旨在帮助他们在应用程序运行时进行问题的实时定位,而无需停止或重启服务。...

    bTrace跟踪线程堆栈

    总结来说,"bTrace跟踪线程堆栈" 是一种利用bTrace工具动态监控Java应用中线程行为的方法,有助于调试和优化代码,尤其是在处理并发问题时。通过学习这个主题,开发者可以更好地理解和诊断程序的运行状态,提升软件...

    Btrace 官方zip包

    **Btrace 深度解析:项目检测与性能监控** Btrace 是一款强大的Java应用程序诊断工具,它允许开发者在不修改或重启应用的情况下,实时监控和分析运行中的Java程序。这款工具的核心特性在于其无侵入性,对于繁忙的...

    BTrace监控远程服务器使用实例

    在这个实例中,我们将学习如何使用BTrace来监控远程Linux服务器上的Tomcat应用。 首先,你需要了解的是BTrace的工作原理。BTrace会动态地生成和注入字节码到目标Java类的方法中,以此来添加监控逻辑。这些监控脚本...

    btrace1.3.9

    【标题】"btrace1.3.9"指的是BTrace工具的一个特定版本,1.3.9,这是一款强大的Java应用程序动态跟踪工具。BTrace利用Java的JVMTI(Java Virtual Machine Tool Interface)和Serviceability Agent(SA)来提供安全、...

    btrace.jar

    学习编写有效的BTrace脚本是使用该工具的关键。 3. **权限需求**:在生产环境中使用btrace可能需要管理员权限,因为它涉及到修改运行时的字节码。 4. **兼容性**:btrace需要与Java版本兼容,确保使用的btrace版本能...

    btrace调试工具

    总结,BTrace作为一款强大的Java在线调试工具,通过字节码增强技术实现了对运行中的Java应用的实时监控,对于开发人员而言,是进行性能优化和问题排查的得力助手。合理运用BTrace,可以极大地提升线上问题解决的效率...

    btrace-release-1.3.11.3.zip

    3. **编写监控脚本**:学习 Btrace 脚本语言,根据需求编写监控脚本。 4. **应用监控脚本**:通过 Btrace 的命令行工具,将监控脚本应用到目标 JVM 上。 5. **查看结果**:收集的数据可以通过日志或其他输出方式查看...

    btrace源代码

    通过对BTrace源代码的深入研究,我们可以更好地理解其设计思路,学习如何利用BTrace进行生产环境的性能调试,甚至可以扩展其功能以满足更复杂的监控需求。BTrace的开源特性也鼓励社区成员参与进来,共同推动其发展,...

    btrace引导文件安装Btrace

    **总结** Btrace作为一个强大的Java应用监控工具,通过动态字节码注入技术,让我们无需修改代码就能实现运行时监控。结合VisualVM插件,我们可以更直观地管理和分析监控数据,这对于调试、性能优化以及问题排查具有...

    btrace扩展功能工具

    1.btrace扩展是在btrace已由功能上进行的扩展,原有功能和使用方式依然没变。目前版本扩展了两个功能:接口时间监控和接口时间调用树监控。扩展之后的btrace功能使用时都不需要写btrace脚本。 2.使用接口时间监控...

    btrace支持jdk1.6上运行的版本

    - **samples**:包含了一些示例脚本,帮助用户理解和学习如何编写 BTrace 脚本。 - **docs**:存放了 BTrace 的文档,包括用户指南和API参考。 - **bin**:包含了 BTrace 的可执行文件和相关的脚本,用于运行和管理 ...

Global site tag (gtag.js) - Google Analytics