zoukankan      html  css  js  c++  java
  • 用btrace定位问题

    btrace 截取方法出入参

    用btrace的手法,网上有很多。简单记录下我自己的使用经历。

    btrace脚本:

    import static com.sun.btrace.BTraceUtils.exit;  
    import static com.sun.btrace.BTraceUtils.field;  
    import static com.sun.btrace.BTraceUtils.get;  
    import static com.sun.btrace.BTraceUtils.jstack;  
    import static com.sun.btrace.BTraceUtils.printEnv;  
    import static com.sun.btrace.BTraceUtils.printFields;  
    import static com.sun.btrace.BTraceUtils.printProperties;  
    import static com.sun.btrace.BTraceUtils.printVmArguments;  
    import static com.sun.btrace.BTraceUtils.println;  
      
      
    import com.sun.btrace.BTraceUtils.Strings;  
    import com.sun.btrace.BTraceUtils.Sys;  
    import com.sun.btrace.annotations.BTrace;  
    import com.sun.btrace.annotations.Duration;  
    import com.sun.btrace.annotations.Kind;  
    import com.sun.btrace.annotations.Location;  
    import com.sun.btrace.annotations.OnMethod; 
    import com.sun.btrace.annotations.Return;   
    import com.sun.btrace.annotations.Self;  
    
    import static com.sun.btrace.BTraceUtils.*; 
      
      
    @BTrace  
    public class t {  
      
      
    //print System Properties:  
    static {  
    println("System Properties:");  
    printProperties();  
    println("VM Flags:");  
    printVmArguments();  
    println("OS Enviroment:");  
    printEnv();  
    exit(0);  
    }  
      
        @OnMethod(clazz = "com.xxxxxxx.FlowServiceImpl", method = "queryFlowList",location=@Location(Kind.RETURN))  
        public static void traceStoreInTransactionExecute(java.util.Map<String, Object> content, java.lang.Integer iDisplayStart,
            java.lang.Integer iDisplayLength,  @Return java.util.List<com.xxxxxxxx.ScenarioJournalBo> ret) {  
        println(str(ret));
        println(str(content));
        println(str(iDisplayStart));   
        println(str(iDisplayLength));   
        }  
      
     
      
    }

    此处脚本 用于监控方法入参,和出参.

    监控性能

    用于监控性能,执行某个方法的时间消耗,单位是纳秒 换成毫秒要除以1000000

    这个比一般写代码去监控好用些,毕竟只是配置一下

    import static com.sun.btrace.BTraceUtils.exit;
    import static com.sun.btrace.BTraceUtils.field;
    import static com.sun.btrace.BTraceUtils.get;
    import static com.sun.btrace.BTraceUtils.jstack;
    import static com.sun.btrace.BTraceUtils.printEnv;
    import static com.sun.btrace.BTraceUtils.printFields;
    import static com.sun.btrace.BTraceUtils.printProperties;
    import static com.sun.btrace.BTraceUtils.printVmArguments;
    import static com.sun.btrace.BTraceUtils.println;
    
    import com.sun.btrace.BTraceUtils.Strings;
    import com.sun.btrace.BTraceUtils.Sys;
    import com.sun.btrace.annotations.BTrace;
    import com.sun.btrace.annotations.Duration;
    import com.sun.btrace.annotations.Kind;
    import com.sun.btrace.annotations.Location;
    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 SP02 {
    
    @TLS private static long startTime;
    
    
    //print System Properties:  
    static {
    println("System Properties:");
    printProperties();
    println("VM Flags:");
    printVmArguments();
    println("OS Enviroment:");
    printEnv();
    exit(0);
    }
    
        // @OnMethod(clazz="com.xxxClass",method="beforeInvoke")
        //public static void onCall(){
         //   startTime=Time.millis();
    //println("s");
       // }
    
        @OnMethod(clazz="com.xxxClass",method="processCall",location=@Location(Kind.RETURN))
        public static void onReturn(@Duration long d ){
            println(Strings.strcat("-processCall ", Strings.str(d)));
        }
    
        @OnMethod(clazz="com.xxxClass",method="updateSournal",location=@Location(Kind.RETURN))
        public static void onReturn1(@Duration long d ){
            println(Strings.strcat("-updateSnal ", Strings.str(d)));
        }
    
        @OnMethod(clazz="com.xxxClass",method="writeResponsR",location=@Location(Kind.RETURN))
        public static void onReturn2(@Duration long d ){
            println(Strings.strcat("-writeRR ", Strings.str(d)));
        }
    
        @OnMethod(clazz="org.springframework.web.servlet.DispatcherServlet",method="doDispatch",location=@Location(Kind.RETURN))
        public static void onReturn3(@Duration long d ){
            println(Strings.strcat("-doDispatch ", Strings.str(d)));
        }
    
        @OnMethod(clazz="com.xxx.AnnotationMethodHandlerAdapter",method="handle",location=@Location(Kind.RETURN))
        public static void onReturn4(@Duration long d ){
            println(Strings.strcat("-handle ", Strings.str(d)));
        }
    
    }

    执行

    ./btrace 25615 SP02.java
    #25615 是你要监控的进程id(用jps可以看到)

    注意:

    1. 此手法若用于生产,最好在生产上包的时候 上btrace工具,因为不是jdk自带,不要要用的时候 找不到这个工具。

    2. 如果btrace脚本中一来业务的类,则需要在执行的命令行中 指定classpath含有业务的jar(或者class目录)

    3. 监控的脚本的类名需要与监控脚本文件名相同(与java代码一个规则。)

    classpath问题 (以下段落均针对mac环境)

    怎样快速的取classpath? 在linux/mac上都是  -classpath xx.jar全路径 冒号分隔 yy.jar全路径。但是如何快速的拿到这个classpath?在mac/linux上有个简单的办法,在你需要用btrace监听的工程中写个带有main方法的类,并不要让main方法结束,可以用

    try
    {
           System.in.read();
     }
      catch (IOException e)
    {
          e.printStackTrace();
     }

    也可以用Thread.sleep等办法。

    然后用

    ps -ef|grep "java">1.log

    然后到1.log中就可以找到了所有依赖的jar构成的classpath信息了,准确快捷。

    带有classpath的btrace使用示例是:

    ./btrace -classptah xxx/xx1.jar:xxx/xx2.jar 目标进程号 监听脚本类.java

    JAVA_HOME问题

    使用btrace需要设置JAVA_HOME环境变量 否则会报错:

    Please set JAVA_HOME before running this script

    我在mac设置是:

    export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home

    JAVA_VERSION问题

    mac上使用btrace需要设置JAVA_VERSION环境变量,否则报错:

    Please set JAVA_VERSION to the target java version

    我的设置是:

    export JAVA_VERSION=CurrentJDK

    查找办法是:

    看看这个路径System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Classes/classes.jar

    报错:类文件具有错误的版本 52.0,应为 50.0

    上面的jdk版本不对 导致了这个问题

    重新设置:

    export JAVA_HOME=/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home
    export JAVA_VERSION=1.6.0

    至此能正常使用起来了

    在研究btrace的过程中 发现了一个淘宝的 工具greys https://yq.aliyun.com/articles/2390

    有空把玩一下。

  • 相关阅读:
    Jhipster 一个Spring Boot + Angular/React 全栈框架
    从企业架构到智慧油田的理论与实践
    DevExpress VCL 的 cxDBTreeList 的使用方法
    Delphi 三层框架 DataSnap 的服务器端设置
    雷达方程
    雷达方向信号产生
    目标
    流水线&并行处理
    CORDIC原理与FPGA实现(2)
    CORDIC原理与FPGA实现(1)
  • 原文地址:https://www.cnblogs.com/simoncook/p/6761853.html
Copyright © 2011-2022 走看看