`
agapple
  • 浏览: 1597837 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

btrace记忆

阅读更多

上周五接近6个小时都在开会,悲剧阿。 美好的一天又这样被浪费了。

 

还好开会的时候自带了笔记本,闲来无聊又重新把btrace的内容重新梳理了一遍。

 

ps : 以前虽然看过btrace的使用,但根本是一种阅读者的态度,并没有反编译btrace源码进行查看。 还有就是实际也没写过几个btrace脚本,很多使用就显得很生疏。所以需要多加强下,只能多看过个2,3遍。

 

更详细,更精彩的一些btrace内容,请查看:  btrace一些你不知道的事(源码入手)

 

 

 

几个常用url : 

1. javadoc文档: http://btrace.kenai.com/javadoc/1.2/index.html

2. UserGuide :  http://kenai.com/projects/btrace/pages/UserGuide

3. DeveloperGuide : http://kenai.com/projects/btrace/pages/DeveloperGuide

4. jvisualvm plugins :  http://visualvm.java.net/pluginscenters.html  , http://visualvm.java.net/plugins.html

 

 

 


几个使用注意点:

1.  Kind.CALL 和 Kind.ENTRY的使用理解

  • Kind.ENTRY意指进入匹配probe点,跟你@Location设置的clazz和method没有任何关系。
  • Kind.CALL意指从某个匹配probe的方法中调用了匹配A class method的点,一定要和clazz,method配合使用。clazz和method的默认值为"",所以不能被匹配。
说白了一个就是跟踪A和B的调用关系,另一个只是关注调用了B的方法。

2.  @ProbeClassName 和 @ProbeMethodName的理解
因为btrace的probe点,clazz和method都支持正则匹配,clazz还支持super class or inteface匹配。所以对应匹配该probe的点会不同。
  • @ProbeClassName :  就是具体匹配对应的clazz规则的class name。如果没配置正则,则就是Probe clazz自己。
  • @ProbeMethodName :  就是具体匹配对应的method规则的method name。如果没配置正则,则就是Probe method自己。

3.  @TargetInstance 和 @TargetMethodOrField的理解

这个可以结合Kind.CALL进行说明,如果是probe A class的方法中调用了匹配B class。 @TargetInstance 返回的就是B class的实例,@Self返回的就是A class

  • @TargetInstance : 就是probe点内部间接调用class的对象引用
  • @TargetMethodOrField : 就是probe点内部间接调用class的方法或者对象属性。
说明: @TargetInstance和@TargetMethodOrField,必须结合Kind.CALL模式进行使用,具体原因看一下其代表的意思也就很明确了。 

4.  @Return , @Duration  和 方法参数AnyType的理解
可以理解下,我们常见的日志记录的需求,一般要求记录请求参数和返回结果,再加上对应的处理时间。那这时@Return , @Duration就派上用场了
  • @Return : 就是获取方法的返回对象。
  • @Duration :  就是整个Probe method调用所耗费的时间,单位us。
  • AnyType :  就是获取对应请求的参数,可以泛指任意类型。 同样你如果明确参数对象的,可以强制指定具体参数的类型
一般常见的使用: public static void log(@Return Object result, Object proxy, Method method, Object[] args, @Duration long durationL) 
说明: @Return和@Duration,必须结合Kind.Return模式进行使用,具体原因也挺明确了

5. @OnEvent的理解
就是和命令行进行交互,对事件的响应处理。比如btrace运行后,通过Ctrl + C指令,会有如下提示:
Please enter your option:
	1. exit
	2. send an event
	3. send a named event
 如果你选择2或者3,就是对btrace client发起一个event事件。也挺好理解的
   @OnEvent
    public static void event() {
        println("event");
    }

    @OnEvent("A")  // 相应name A event
    public static void eventA() {
        println("eventA");
    }

    @OnEvent("B") // 相应name B event
    public static void eventB() {
        println("eventB");
    }
 
说明: 一般可通过event事件,控制一下输出统计的内容信息。

 

6. @OnExit的理解
老实说,我也并不是非常理解。只知道通过OnExit可以监控btrace脚本发起的exit()调用,在btrace client退出之前做点事情。暂没想到特定的应用场景,数据清理?
   @OnExit
    public static void onexit(int code) {
        println("exit");
    }

    @OnTimer(1000)
    public static void ontime() {
        println(i++);
        if (i == 5) {
            println("do exit");
            exit(0);
        }
    }

推荐jvisualvm btrace GUI


1. 启动,关闭,Event事件发送都挺方便的。

2. 不用每次vi 打开java文件进行编辑,修改script就方便多了

常用btrace监控脚本: 

1.  Jetty监控request/response buffer,有项目在使用中发现出现http 413错误(Request entity too large) , http://www.checkupdown.com/status/E413_cn.html

 

   初步怀疑是和buffer参数有关,原先使用jboss的参数为maxHttpHeadSize=8196,所以写了脚本提取了下线上的jetty参数,后面就修改了jetty参数为8k,解决了问题

 

 

@BTrace
public class JettyHeadBufferTracer {

    @OnMethod(clazz = "org.eclipse.jetty.http.HttpBuffers", method = "/.*get.*Buffers/", location = @Location(value = Kind.ENTRY))
    public static void bufferMonitor(@Self Object self) {
        Field requestBuffersField = field("org.eclipse.jetty.http.HttpBuffers", "_requestBuffers");
        Field responseBuffersField = field("org.eclipse.jetty.http.HttpBuffers", "_responseBuffers");

        Field bufferSizeField = field("org.eclipse.jetty.io.ThreadLocalBuffers", "_bufferSize");
        Field headerSizeField = field("org.eclipse.jetty.io.ThreadLocalBuffers", "_headerSize");
        Object requestBuffers = get(requestBuffersField, self);
        int requestBufferSize = (Integer) get(bufferSizeField, requestBuffers);
        int requestHeaderSize = (Integer) get(headerSizeField, requestBuffers);
        Object responseBuffers = get(responseBuffersField, self);
        int responseBufferSize = (Integer) get(bufferSizeField, responseBuffers);
        int responseHeaderSize = (Integer) get(headerSizeField, responseBuffers);

        println(strcat(strcat(strcat("requestBufferSize : ", str(requestBufferSize)), " requestHeaderSize : "),
                       str(requestHeaderSize)));
        println(strcat(strcat(strcat("responseBufferSize : ", str(responseBufferSize)), " responseHeaderSize : "),
                       str(responseHeaderSize)));
    }
}

 

结果: 

 

requestBufferSize : 8192 requestHeaderSize : 6144
responseBufferSize : 12288 responseHeaderSize : 6144

 

 

2. 项目中使用了dbcp做为数据库连接池,但对于连接池大小是否够用没有很直观的数据可以提供,所以写了个脚本提取一下数据

主要的数据内容:

   * maxActive(最大连接池大小),numActive(目前处于使用中),numIdle(处于空闲状态的连接数)

   * maxTotal(开启ps的最大值),totalActive(目前处于使用ps的总数),keyActive(当前sql的ps使用数),keyIdle(当前sql的ps空闲数)  针对开启了ps cache

 

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
....   
    <property name="poolPreparedStatements" value="true" />  
    <property name="maxOpenPreparedStatements" value="10" />  
....  
</bean>  
 

 

 

@BTrace
public class DbcpTracer {

    @OnMethod(clazz = "org.apache.commons.pool.impl.GenericObjectPool", method = "/.*Object/", location = @Location(value = Kind.ENTRY))
    public static void poolMonitor(@Self Object self) {
        Field maxActiveField = field("org.apache.commons.pool.impl.GenericObjectPool", "_maxActive");
        Field numActiveField = field("org.apache.commons.pool.impl.GenericObjectPool", "_numActive");
        Field poolField = field("org.apache.commons.pool.impl.GenericObjectPool", "_pool");
        Field sizeField = field("org.apache.commons.pool.impl.CursorableLinkedList", "_size");
        int maxActive = (Integer) get(maxActiveField, self);
        int numActive = (Integer) get(numActiveField, self);
        int numIdle = (Integer) get(sizeField, get(poolField, self));

        println(strcat(strcat(strcat(strcat(strcat("maxActive : ", str(maxActive)), " numActive : "), str(numActive)),
                              " numIdle : "), str(numIdle)));
    }

    @OnMethod(clazz = "org.apache.commons.pool.impl.GenericKeyedObjectPool", method = "/.*Object/", location = @Location(value = Kind.ENTRY))
    public static void psMonitor(@Self Object self, Object key) {
        Field maxTotalField = field("org.apache.commons.pool.impl.GenericKeyedObjectPool", "_maxTotal"); // connectio的maxActive
        Field totalActiveField = field("org.apache.commons.pool.impl.GenericKeyedObjectPool", "_totalActive"); // connectio的active
        Field poolMapField = field("org.apache.commons.pool.impl.GenericKeyedObjectPool", "_poolMap"); // connectio的active

        Field keyActiveField = field("org.apache.commons.pool.impl.GenericKeyedObjectPool$ObjectQueue", "activeCount"); // key的active
        Field keyIdleField = field("org.apache.commons.pool.impl.GenericKeyedObjectPool$ObjectQueue", "queue"); // key的idle
        Field keyIdleSizeField = field("org.apache.commons.pool.impl.CursorableLinkedList", "_size");

        Field sqlField = field("org.apache.commons.dbcp.PoolingConnection$PStmtKey", "_sql");

        int maxTotal = (Integer) get(maxTotalField, self);
        int totalActive = (Integer) get(totalActiveField, self);
        Map<Object, Object> poolMap = (Map<Object, Object>) get(poolMapField, self);
        int keyActive = 0, keyIdle = 0;
        if (poolMap != null) {
            Object queue = get(poolMap, key);
            if (queue != null) { // ObjectQueue
                keyActive = (Integer) get(keyActiveField, queue);
                keyIdle = (Integer) get(keyIdleSizeField, get(keyIdleField, queue));
            }
        }
        println(strcat(strcat(strcat(strcat(strcat(strcat(strcat("maxTotal : ", str(maxTotal)), " totalActive : "),
                                                   str(totalActive)), " keyActive : "), str(keyActive)), " keyIdle "),
                       str(keyIdle)));

        println(strcat("Ps Key: ", str(get(sqlField, key))));
    }

}
 

 

 

  • 大小: 85.1 KB
  • 大小: 34 KB
分享到:
评论
7 楼 Maconel 2015-01-18  
DbcpTracer 中有如下代码:
Field maxActiveField = field("org.apache.commons.pool.impl.GenericObjectPool", "_maxActive"); 

但是_maxActive是GenericObjectPool的私有成员变量,在btrace中是不允许这样访问的,楼主是怎么做到的?我这里提示:instance variables are not allowed
6 楼 sswh 2014-03-14  
liuxiaori 写道
请教个问题,如果btrace脚本中依赖多个业务jar包,请问这种场景支持吗?


你说的业务JAR包,是指原业务系统中的Class吗?

如果是的话,可能注意一下下面的问题:

BTrace脚本中以@OnMethed等注解声明的方法,这部分代码会被插入到目标类的字节码中去,
并且这部分代码的ClassLoader是应用本身的类加载器。所以这部分代码是可以访问业务系统的Class的。

BTrace脚本中其他的工具方法(比如,静态的工具方法),这部分代码仍然留在BTrace脚本编译后的Class中,并且脚本类的ClassLoader是引导类加载器。这部分代码不能访问业务系统的Class,否则运行期报NoClassDefFoundError。

5 楼 liuxiaori 2014-03-11  
hi man,

请教个问题,如果btrace脚本中依赖多个业务jar包,请问这种场景支持吗?
4 楼 agapple 2013-11-14  
endall 写道
hi,童鞋,转载下你的思维脑图,仅供学习用,行否?


没问题
3 楼 endall 2013-11-14  
hi,童鞋,转载下你的思维脑图,仅供学习用,行否?
2 楼 sswh 2013-01-30  
写的很好,感谢分享~~

~~~~分割线~~~~~~~

引用
1.  Kind.CALL 和 Kind.ENTRY的使用理解
Kind.ENTRY意指进入匹配probe点,跟你@Location设置的clazz和method没有任何关系。
Kind.CALL意指从某个匹配probe的方法中调用了匹配A class method的点,一定要和clazz,method配合使用。clazz和method的默认值为"",所以不能被匹配。

下面的理解更简单一些:
Kind.ENTRY 是和 Kind.RETURN 对应的
@OnMethod(location = @Location(Kind.RETURN)) 目标方法返回时触发;

@OnMethod(location = @Location(Kind.ENTRY)) 等价于
@OnMethod(location = @Location)等价于
@OnMethod
上面三种写法是等价的,都是指目标方法被调用时触发;

Kind.CALL 和 Kind.LINE 作用类似
@OnMethod(location = @Location(value = Kind.CALL, clazz = "a", method = "b")) 指目标方法体如果调用了a.b()方法时触发;

@OnMethod(location = @Location(value = Kind.LINE, line = 5)) 指目标方法体执行到第n行代码时触发
1 楼 ilfmonday 2012-05-05  
写的很好~~非常受教
顺便问问博主用的思维导图软件是什么呢?感觉非常清爽,我自己一般用iMindMap

相关推荐

    jvisualvm btrace插件离线安装

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

    jdk1.8-Btrace.rar

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

    btrace release-1.2.5.1

    【标题】"btrace release-1.2.5.1" 指的是BTrace的一个特定版本,1.2.5.1。BTrace是一款强大的Java应用动态追踪工具,它允许开发者在运行时对Java应用程序进行性能分析和诊断,而无需修改源代码或重新部署应用。这个...

    Btrace 官方zip包

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

    Btrace资源

    **Btrace资源详解** Btrace 是一个强大的Java应用程序动态跟踪工具,它允许开发者在不修改代码的情况下,对正在运行的应用程序进行实时监控和诊断。这个资源包包含了Btrace的多个组件,下面我们将逐一介绍。 1. **...

    btrace1.3.9.zip

    《深入理解BTrace 1.3.9:Java应用诊断利器》 BTrace,全称为“Bytecode Tracing”,是一款强大的动态代码插桩工具,它允许开发者在运行时对Java应用程序进行性能分析和诊断。BTrace 1.3.9是其一个重要版本,特别...

    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监控远程服务器使用实例

    **BTrace监控远程服务器使用实例** BTrace 是一个强大的、安全的、动态的Java应用程序诊断工具,它允许开发者在运行时对Java应用进行细粒度的监控和性能分析。BTrace利用了Java的动态代理机制(Java Agent)和ASM...

    btrace扩展功能工具

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

    bTrace跟踪线程堆栈

    标题 "bTrace跟踪线程堆栈" 涉及到的是在Java开发中对线程堆栈进行监控和分析的技术,主要使用了开源工具bTrace。bTrace是一款强大的、无侵入式的Java运行时代码注入工具,允许开发者在运行中的Java应用上动态添加...

    btrace-release-1.3.11.3.zip

    标题中的 "btrace-release-1.3.11.3.zip" 表明这是一个 Btrace 的特定发布版本,版本号为 1.3.11.3,通常包含已编译的库文件、文档和其他必要的资源。 在 Java 开发中,性能监控是至关重要的,因为这有助于识别和...

    BTrace安装包 btrace-bin-1.3.11.3.zip + btrace-src-1.3.11.3.zip

    btrace-bin直接解压缩配置环境变量后即可运行使用。 java监控调试工具虚拟机监控程序,利用BTrace可以在线监控java程序状态。 BTrace是一种安全,动态的Java跟踪工具。BTrace通过动态(字节码)检测正在运行的Java...

    BTrace自我总结测试代码

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

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

    **BTrace:深入理解与应用** BTrace 是一个强大的动态代码跟踪工具,它允许开发者在运行时对Java应用程序进行安全的、低开销的、无侵入性的性能和行为分析。这个工具的独特之处在于,它不需要修改或重新编译源代码...

    btrace workbench

    【标题】"btrace workbench" 是一个专为Java开发者设计的强大工具,它与jvisualvm结合使用,提供了深入的应用程序性能分析能力。BTrace(Business Trace)是一种动态跟踪工具,允许开发者在运行时对Java应用程序进行...

    btrace引导文件安装Btrace

    **Btrace 概述** Btrace(Business Tracing for Java)是一种强大的动态追踪工具,专为Java应用程序设计。它允许开发者在不修改源代码的情况下,实时监控和分析应用程序的行为。Btrace利用Java代理(Java Agents)...

    btrace调试工具

    **BTrace调试工具详解** BTrace是一款强大的Java应用程序动态跟踪工具,它允许开发者在不修改源代码或重新启动应用的情况下,对正在运行的Java应用程序进行实时的性能分析和诊断。这款工具的核心在于其字节码注入...

    btrace工具

    Btrace:java性能调优及问题追踪工具 Btrace:java性能调优及问题追踪工具

    btrace.jar

    【btrace.jar】是一款强大的Java在线诊断工具,它允许开发者在不重启应用程序的情况下,实时地对Java程序进行动态追踪和分析。这个工具的核心价值在于它能够帮助我们在生产环境中无侵入地解决性能问题或者追踪特定的...

Global site tag (gtag.js) - Google Analytics