线上排查工具btrace和jvm-inspector使用说明

公西天逸
2023-12-01
btrace
=================================================================
btrace官网: https://kenai.com/projects/btrace/pages/UserGuide
下载1.2可执行包的,上传到线上机器。

解压后将chmod 755 btrace,将btrace设为可执行。
一个简单的btrace脚本(就是一个java代码文件)示例:
------------------------------------------------------------
import com.sun.btrace.annotations.*;
import com.sun.btrace.AnyType;
import static com.sun.btrace.BTraceUtils.*;

@BTrace public class TraceLog4j {
    @OnMethod(clazz="/org\\.slf4j.*/",method="/error.*/")
    public static void m(@ProbeClassName String probeClass, @ProbeMethodName String probeMethod, AnyType[] args) {
        print(probeClass);
        print(".");
        println(probeMethod);
        printArray(args);
    }
}
------------------------------------------------------------
这个脚本的作用是:检测到org.slf4j包下所有类的error方法调用时,就会打印出类名、方法名以及参数值列表。
保存后,先找到你要trace的进程的pid。
使用命令:sudo btrace <pid> TraceLog4j.java 看输出即可(执行前可能需要先export JAVA_HOME)。

参数注解:
@Self:指定被trace方法的this
@ProbeClassName/ProbeMethodName:被trace方法的类名和方法名
@Return 指定trace方法的返回值
@TargetInstance:指定被trace方法内部调用到的实例
@TargetMethodOrField:被trace方法内部调用到的方法 

属性注解:
@TLS:指定变量为ThreadLocal。

关于TargetInstance和TargetMethodOrField,官方示例代码如下:
------------------------------------------------------------
package com.sun.btrace.samples;
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace public class AllCalls2 {
    @OnMethod(clazz="/javax\\.swing\\..*/", method="/.*/",
        location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/"))      
    public static void n(@Self Object self, @ProbeClassName String pcm, @ProbeMethodName String pmn,
        @TargetInstance Object instance, @TargetMethodOrField String method, String text) {
        println(Strings.strcat("Context: ", Strings.strcat(pcm, Strings.strcat("#", pmn))));
        print(method);
        print("  ");
        println(text);
    }
}
------------------------------------------------------------
这个脚本会打印javax.swing包内所有方法中间接调用的方法。

取self对象的特定field的值,可以使用:str(get(field("ClassName", "fieldName"), self))

注意:btrace为了保证JVM的安全和稳定,限定了脚本中只能调用BTraceUtils提供的方法,方法列表在这里:
https://btrace.kenai.com/javadoc/1.2/com/sun/btrace/BTraceUtils.html

这里有几个比较不错的例子: http://inter12.iteye.com/blog/1759882  


jvm-inspector
=================================================================
淘宝自己开发的工具, 程序就一个jar包,启动非常简单:
java -Xbootclasspath/a:/opt/taobao/java/lib/tools.jar -jar jvm-inspect-2.0.1.jar <pid>
运行后会出现一个交互式的界面。
 
classesdump:可以dump出一个类的所有类加载器
trace:跟踪方法调用,如:trace com.taobao.tae.grid.servlet.TaePhpServlet.render()
不过不太清楚怎么使用brace的类似get(field..)取对象字段值的方法。
 类似资料: