[原]BTrace介绍和生产环境例子

标签: | 发表时间:2014-08-16 22:57 | 作者:a511596982
出处:http://blog.csdn.net/a511596982

BTrace latest realese:

release-1.2.5.1 

BTrace guide(1.2-20101020):

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

例子:在压缩包内有。

 

一/简单介绍

 

BTrace 是一个可靠的,用来动态跟踪Java程序的工具。它通过动态对运行中的Java程序进行字节码生成来工作。BTrace会对运行中的Java程序的类插入一些跟踪操作 来对被跟踪的程序进行热替换。
BTrace 名词
探测点 (Probe Point)
就是一系列的跟踪语句被执行的“地方”或者“事件”。探测点就是我们想要执行一些跟踪语句的地方或者事件。
跟踪动作或简称动作 (Trace Actions)
就是那些当探测点被触发时所执行的跟踪语句。
动作方法
BTrace的跟踪语句是必须定义在一个类的某个静态方法里的,这个静态方法就叫“动作”方法。
BTrace 程序结构
一个BTrace程序就是一个普通的Java类,这个类至少有一个这样的方法:
public static void ***
其次这个方法还需要加上BTrace相关的注解。这些注解用来指明被跟踪程序的“位置”(也就是前面提到的探测点)。跟踪动作需要在这个静态方法的方法体里指定。这些(注意,可以有多个)静态方法就是所谓的“动作”方法。
BTrace的限制
为了保证跟踪动作是“只读”的(也就是这些动作不可以修改被跟踪程序的状态)和有限度的(比如在固定时间里结束)。一个BTrace程序只允许完成一些指定的动作。下面是BTrace一些不可以完成的事情:
  • 不能创建新的对象
  • 不能创建新的数组
  • 不能抛出异常
  • 不能捕获异常
  • 不能进行任何的实例函数或者静态函数 -- 只有com.sun.btrace.BTraceUtils类中的静态函数或者BTrace程序自己声明的
  • 函数才可以被BTrace调用
  • 对1.2版本以前的程序,不能由实例级别的field和函数。只有静态公开的并且无返回值的函数才允许在BTrace类中使用。所有
的field必须是静态的。
  • 不可以在目标程序的类,或者对象的静态或者实例级别的field进行赋值。但是,BTrace自身的类是可以给它的静态field进行赋值的。
  • (也就是意味着跟踪的状态时可以更改的)
  • 不能有outer,inner,嵌套的或者本地类。
  • 不能有同步代码块或者同步的函数
  • 不能有循环语句(for,while, do..while)
  • 不能继承其它类(父类只能是java.lang.Object)
  • 不能实现接口
  • 不能包含断言(assert)语句
  • can NOT use class literals (这个我也没搞明白是啥意思)

二/具体例子

现网碰到问题,目前需要拦截框架请求,并判断req中storeId字段为11008时,输出其他参数,方便进一步查问题。

需要拦截的类结构如图:

需要拦截match方法,match方法这里有好几个重载方法,目前只需要拦截第一个。

btrace代码:

(补充一点:在btrace代码中,没法去调用非BTraceUtils之外的方法,也就是说,要输出类各字段信息是没法通过toString()方法,因为调用instance.toString()方法是不安全,编译fail,需要自己去解析每个字段值)

package btrace;


import com.sun.btrace.AnyType;
import com.sun.btrace.annotations.*;


import java.lang.reflect.Field;


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


/**
 * Created by vernonzheng on 14-8-15.
 */
@BTrace
public class FrameFilterTrace {
    @OnMethod(
            clazz="com.skymobi.market.applist.service.imp.CustomizedFrameMatcher",
            method="match",
            type = "com.skymobi.market.applist.entity.FrameStorageMetadata (com.skymobi.market.applist.bean.common.TlvCommonHeaderReq)"
    )
    public static void onMatch(AnyType request){
        Class frameRequestCl = classOf(request);
        String storeId = getVal("storeId",frameRequestCl, request);
        Class tlvCommentHeaderReqCl = getSuperclass(frameRequestCl);
        Class networkTrackCl = getSuperclass(tlvCommentHeaderReqCl);
        Class terminalRequestCl = getSuperclass(networkTrackCl);
        if(storeId!=null){
            if(compare(storeId,"10118")){
                //asHsman,asHstype,bizSource,sessionId,channelNo,storeId,clientVer,hsman,hstype,mnc,imsi,
                //networkType,capability
                println(strcat("vernon----store_id=10118--输出参数 : ", str(request)));
                println(strcat("storeId:",storeId));
                println(strcat("channelNo:",getVal("channelNo",frameRequestCl,request)));
                println(strcat("asHsman:",getVal("asHsman",frameRequestCl,request)));
                println(strcat("asHstype:",getVal("asHstype",frameRequestCl,request)));
                println(strcat("bizSource:",getVal("bizSource",tlvCommentHeaderReqCl,request)));
                println(strcat("sessionId:",getVal("sessionId",tlvCommentHeaderReqCl,request)));
                println(strcat("clientVer:",getVal("clientVer",tlvCommentHeaderReqCl,request)));
                println(strcat("hsman:",getVal("hsman",terminalRequestCl,request)));
                println(strcat("hstype:",getVal("hstype",terminalRequestCl,request)));
                println(strcat("mnc:",getVal("mnc",terminalRequestCl,request)));
                println(strcat("imsi:",getVal("imsi",terminalRequestCl,request)));
                println(strcat("networkType:",getVal("networkType",terminalRequestCl, request)));
                println("----------------------------------------------------------");
            }
        }
    }
    private static String getVal(String filedName,Class cl,AnyType instance){
        Field field = field(classOf(cl), filedName, false);
        if(field!=null) {
            return str(get(field, instance));
        }else{
            return "is null";
        }
    }
}


把FrameFilterTrace.java 和下载好的btrace-bin .tar.gz丢到现网上,解压btrace-bin .tar.gz,

把FrameFilterTrace.java拷贝到bin目录,

vi btrace脚本,在头上加上(export BTRACE_HOME=解压路径),如果JAVA_HOME没有设置,也export一下。

然后jps,找到jvm PID,

执行btrace PID FrameFilterTrace.java > catch.log

完成!

输出如图:


参考:

https://kenai.com/projects/btrace/pages/UserGuide

http://linmingren2003.blog.163.com/blog/static/56751003201121871725139/

http://www.stacktrace.cn/?p=28

作者:a511596982 发表于2014/8/16 14:57:43 原文链接
阅读:675 评论:0 查看评论

相关 [btrace 生产 环境] 推荐:

[原]BTrace介绍和生产环境例子

- - Vern的专栏
BTrace 是一个可靠的,用来动态跟踪Java程序的工具. 它通过动态对运行中的Java程序进行字节码生成来工作. BTrace会对运行中的Java程序的类插入一些跟踪操作 来对被跟踪的程序进行热替换. 探测点 (Probe Point). 就是一系列的跟踪语句被执行的“地方”或者“事件”. 探测点就是我们想要执行一些跟踪语句的地方或者事件.

BTrace功能

- - zzm
       在生产环境中可能经常遇到各种问题,定位问题需要获取程序运行时的数据信息,如方法参数、返回值、全局变量、堆栈信息等. 为了获取这些数据信息,我们可以 通过改写代码,增加日志信息的打印,再发布到生产环境. 通过这种方式,一方面将增大定位问题的成本和周期,对于紧急问题无法做到及时响应;另一方面重新部 署后环境可能已被破坏,很难重新问题的场景.

BTrace使用简介

- LightingMan - 淘宝JAVA中间件团队博客
BTrace通过动态的挂接用java写的代码到运行时上来获取到一些运行细节,例如典型的使用btrace的方法为:. btrace -cp [btrace的jar所在的路径,默认为btrace/build下] [pid] [需要运行的java代码]. 如在程序运行的情况下,想知道调用CaseObject的execute方法的以下几种情况,在BTrace中可以这么做:.

BTrace简单实用教程

- - ITeye博客
BTrace本身也是可以独立运行的程序,作用是在不停止目标程序运行的前提下,通过HotSpot虚拟机的HotSwap技术动态插入原本不存在的调试代码. 比如遇到了我们的程序出问题,而又没有足够的打印语句时,我们一般的方法是不得不停掉服务,然后修改代码,增加打印语句,重新编译重新运行来解决,效率很低.

在生产环境运行容器

- - IT瘾-tuicool
【编者的话】Vivek Juneja是一名工作首尔的云服务工程师. 他从2008年就开始接触云服务,是最早的AWS和Eucalyptus的使用者. 本文中总结了在生产环境中使用容器的几个方面,特别是对虚拟机与容器的混合部署的观点很值得推荐给大家. 如果只是把容器限制在开发测试环境中,那么您并没有享受到面向容器研发和发布工作的全部红利.

BTrace入门及使用实例

- - 互联网 - ITeye博客
Btrace (Byte Trace)是sun推出的一款java 动态、安全追踪(监控)工具,可以不停机的情况下监控线上情况,并且做到最少的侵入,占用最少的系统资源. 1.下载[btrace|http://kenai.com/projects/btrace/downloads/directory/releases]包 并把btrace的命令放到path中.

MySQL生产环境突发故障处理手册

- gOODiDEA - MySQL OPS
1.2 碎片整理和统计信息更新 OPTIMIZE 操作等于recreate + analyze 的组合操作,所以会堵塞更新类型SQL语句. 对于备机上跑只读类型操作的业务,可以考虑使用此操作命令,对于主服务器不建议使用此命令,为此备机上执行OPTIMIZE 语句,必须这样写: [...].

生产环境 MySQL 表的维护:check、optimize和analyze

- - CSDN博客数据库推荐文章
        optimize可以回收空间、减少碎片、提高I/O.         目前支持的存储引擎有:InnoDB、MyASIM和ARCHIVE.         如果是Replication环境、可加NO_WRITE_TO_BINLOG(或者LOCAL、意思完全相同)、比如:.         以下是一个简单测试:.

[MySQL] 生产环境MySQL数据库事务一直在RUNNING

- - CSDN博客数据库推荐文章
运营人员反映,有一单子提交卡住了,页面一直没有返回. 1,刚开始怀疑是应用服务器或者db压力过高hang住了,马上去check应用服务器以及db的负载,看起来都OK,蛮低的,应该不是DB性能问题. 2,最后去看下是否是表锁住了,查看到有2个事务一直RUNNING,没有结束. 3,通过trx_mysql_thread_id: 1662332的去查询information_schema.processlist找到执行事务的客户端请求的SQL线程.

virgo-tomcat-server的生产环境线上配置与管理 - 520_1351

- - 博客园_首页
Virgo Tomcat Server简称VTS,VTS是一个应用服务器,它是轻量级, 模块化, 基于OSGi系统. 与OSGi紧密结合并且可以开发bundles形式的Spring web apps应用. 他们同样拥有OSGi和Spring的特性. VTS由SpringSource 的Spring DM server过渡而来, virgo官网地址: http://www.eclipse.org/virgo.