BTrace植入过的代码,会一直在,直到应用重启为止。所以即使Btrace退出了,业务函数每次执行时都会执行Btrace植入的代码

在Btrace脚本中只能使用 BTraceUtils 中的函数, 这在有些情况下很不方便
我们需要开启Btrace的unsafe模式
以最新的2.0版本为例, 开启方法如下
首先在命令行中 增加 -u参数指明开启 unsafe模式

btrace -u -o d:\log.txt PID d:\script.java

另外在脚本中也要增加 @BTrace(unsafe=true)

import org.openjdk.btrace.core.types.AnyType;
import org.openjdk.btrace.core.annotations.*;

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.openjdk.btrace.core.BTraceUtils.*;

@BTrace(unsafe=true)
public class script {

	@OnMethod(
		clazz = "datalayer.CoreD", 
		method = "execute", 
		location = @Location(Kind.ENTRY)
	)
	public static void TraceSql_execute(String sqlstr) {
		if (sqlstr != null)
			println(sqlstr);
	}
	
	@OnMethod(
		clazz = "datalayer.BaseD", 
		method = "query", 
		location = @Location(Kind.ENTRY)
	)
	public static void TraceSql_query(String sqlstr) {
		if (sqlstr != null)
			println(sqlstr);
	}
	
	@OnMethod(
		clazz = "datalayer.BaseD", 
		method = "queryPrepared", 
		location = @Location(Kind.ENTRY)
	)
	public static void TraceSql_queryPrepared(String sqlstr, String sqlkey) {
		if (sqlstr != null)
		{
			String newstr = sqlstr;			
			if (sqlkey != null)
			{
				newstr = sqlstr.replace("?", "'" + sqlkey + "'");
			}
			println(newstr);
		}
	}
	
	@OnMethod(
		clazz = "datalayer.BaseD", 
		method = "queryPrepared", 
		location = @Location(Kind.RETURN)
	)
	public static void TraceSql_queryPrepared_Ret(@Return List<AnyType> ret_list ) {		
		String callstack = jstackStr(3);		
		int intIndex = indexOf(callstack, "HttpConnector.getBytes");
		if (ret_list != null)
		{
			print("  queryPrepared result size ");
			print(ret_list.size());
			println(" ");
		}
	}
}

如上 List<AnyType> 可用来拦截类中的模板参数

拦截类型

  • Kind.ENTRY-被trace方法参数
  • Kind.RETURN-被trace方法返回值
  • Kind.THROW -抛异常
  • Kind.ARRAY_SET, Kind.ARRAY_GET -数组索引
  • Kind.CATCH -捕获异常
  • Kind.FIELD_SET -属性值
  • Kind.LINE -行号
  • Kind.NEW -类名
  • Kind.ERROR -抛异常

打印 byte[] 数组内容
在新的BTrace中不支持, 将提示 byte[]无法转换为java.lang.Object[]
可以添加 trusted = true 来解决. 示例如下:

@BTrace(trusted = true)
public class TrustedTrace {
  @OnMethod(clazz = "MyClass", method = "m", location = Location(Kind.RETURN))
  public static void intercept(@Return byte[] data) {
    println(Arrays.toString(data));
  }
}

转载请注明转自: 听风 , 本文固定链接: BTrace 使用备忘