之前很早有同事分享过Btrace的原理,基于java Instruction 实现的,方便跟踪代码。对于线上应用,我们不能进行debug来获取运行的详细信息,通过BTrace可以搞定一些问题。Btrace使用到的技术主要有
术语主要有三个:
Probe Point :在何处执行trace语句, 这里的"何处"可以是具体的跟踪地点和执行事件, 在BTrace中通过各种注解来指定
Trace Actions or Actions:在何时执行trace语句
Action Methods :定义在trace脚本中的trace语句, 具体来说就是脚本中的无返回值静态方法(1.2之后可以是非静态方法)
使用BTrace
(1)下载BTrace的工程代码
mkdir /home/admin/btrace
cd /home/admin/btrace
wget http://kenai.com/downloads/btrace/releases/release-1.2.2/btrace-bin.tar.gz
tar -xzvf /home/admin/btrace/btrace-bin.tar.gz
export JAVA_HOME=/java
(2)编写自定义的BTrace脚本(java文件)
常用的几个注解
A、方法上的注解OnMethod
clazz: 类名称,可以是全称,也可以是正则表达式(也可以是正则表达式(表达式必须写在"//"中, 比如"/java\\.awt\\..+/").)
例如: clazz="+java.lang.ClassLoader"--》实现ClassLoader接口的类;
method:方法名称,
location:例如location=@Location(Kind.RETURN)是一个枚举值
例如:
@OnMethod(
clazz="/java\\.io\\..*Input.*/",
method="/read.*/"
)
B 、方法上的注解OnTimer 用来指定时长(ms)执行一次trace. 时长通过"value"属性指定。例如 @OnTimer(4000)
C、 其他方法上的注解、
-
OnError 当trace代码抛异常时该注解的方法会被执行. 如果同一个trace脚本中其他方法抛异常, 该注解方法也会被执行.
-
OnExit 当trace方法调用内置exit(int)方法(用来结束整个trace程序)时, 该注解的方法会被执行. 参考自带例子ProbeExit.java.
-
OnEvent 用来截获"外部"btrace client触发的事件, 比如按Ctrl-C 中断btrace执行时将执行使用了该注解的方法, 该注解的value值为具体事件名称.
-
OnLowMemory 当内存超过某个设定值将触发该注解的方法, 具体参考MemAlerter.java
D、参数上的注解:Self 用来指定被trace方法的this
E、参数上的注解:Return 用来指定被trace方法的返回值
F、参数上的注解:ProbeClassName 和ProbeMethodName 被trace的类名称和方法名称
G、参数:.TargetInstance (since 1.1) 用来指定被trace方法内部被调用到的实例
H、参数:TargetMethodOrField (since 1.1) 用来指定被trace方法内部被调用的方法名, 可参考例子AllCalls1.java 合 AllCalls2.java
I、属性上的注解:TLS 将一个脚本变量与一个ThreadLocal变量关联
常用的几种脚本
A、查看一个方法的入参和返回值
B、查看一个方法执行耗时
C、谁调用这个方法
D、代码中的特定行有没有被调用
下面转自毕玄的博客:http://rdc.taobao.com/team/jm/archives/509
(3)命令运行自定义脚本(获取反馈信息)
运行一个例子程序(-cp是设置环境变量,18528是java的进程ID,然后后面是编写的java的文件)
btrace -cp [btrace的jar所在的路径,默认为btrace/build下] [pid] [需要运行的java代码]
sudo -u admin sh btrace -cp /home/admin/btrace/build 18528 /home/admin/btrace/samples/ThreadCounter.java
代码备注:
获取一个类中方法的返回值、响应时间以及调用情况
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
import
static
com.sun.btrace.BTraceUtils.*;
import
com.sun.btrace.annotations.*;
@BTrace
public
class
BtraceAll {
@TLS
private
static
long
beginTime;
@OnMethod
(
clazz=
"com.taobao.commonway.core.service.impl.TimeInfoManagerImpl"
,
method=
"getCityName"
)
public
static
void
traceMethodBegin(){
beginTime = timeMillis();
}
@OnMethod
(
clazz=
"com.taobao.commonway.core.service.impl.TimeInfoManagerImpl"
,
method=
"getCityName"
,
location=
@Location
(Kind.RETURN)
)
public
static
void
traceMethdReturn(
@Return
String result,
@ProbeClassName
String clazzName,
@ProbeMethodName
String methodName){
println(
"==========================================================================="
);
println(strcat(strcat(clazzName,
"."
), methodName));
println(strcat(
"Time taken : "
, str(timeMillis() - beginTime)));
println(
"java thread method trace:---------------------------------------------------"
);
jstack();
println(
"----------------------------------------------------------------------------"
);
println(strcat(
"Reuslt :"
,str(result)));
println(
"============================================================================"
);
}
}
|
参考:
http://rdc.taobao.com/team/jm/archives/509
http://kenai.com/projects/btrace/
http://macrochen.iteye.com/blog/838920
=========================================================================================================
下面是houseMD的使用,感觉比btrace好用一点,但是灵活性不是很高,常见问题都能用一下。
安装
(1)sudo -u admin curl -Lk https://raw.github.com/zhongl/HouseMD/master/bin/install
(2) sudo -u admin sh install.sh | bash
(3) export JAVA_HOME=/opt/taobao/java
(4)sudo -u admin /home/admin/houseMD/housemd -h 23259 ( java pid)进入housemd的控制台
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
#! /bin/bash
CHECKSUM=
"checksum"
curl -Lk https:
//api
.github.com
/repos/zhongl/HouseMD/downloads
|
grep
-E
"[0-9a-f]+\s+[^ \"]+"
-o |
head
-1 > $CHECKSUM
JAR_NAME=`
cat
$CHECKSUM |
grep
-E housemd.+ -o`
curl -Lk https:
//github
.com
/downloads/zhongl/HouseMD/
$JAR_NAME > $JAR_NAME
SHASUM=`
which
shasum ||
which
sha1sum`
if
[ -z $SHASUM ];
then
echo
"Warning, shasum or sha1sum could not find to validate the download jar."
else
$SHASUM -c $CHECKSUM || {
rm
-rf $JAR_NAME $CHECKSUM ;
echo
"Download failed, please try again!"
;
exit
1;
}
fi
mv
$JAR_NAME housemd.jar
rm
-rf $CHECKSUM
curl -Lk https:
//raw
.github.com
/zhongl/HouseMD/master/bin/housemd
> housemd
chmod
u+x housemd
|
(1)查看类加载路径(loaded 类名称,如果查看加载层次,加参数-h)
1
2
3
|
housemd> loaded CollectionUtil
com.taobao.util.CollectionUtil -> /home/admin/commonway/.
default
/deploy/commonway.war/WEB-INF/lib/util-
1.0
.jar
com.alibaba.citrus.util.CollectionUtil -> /home/admin/commonway/.
default
/deploy/commonway.war/WEB-INF/lib/citrus-webx-all-in-one-
3.0
.
3
.jar
|
(2)查看一个类或者特定方法的运行情况
-t 时间 一定时间的运行情况
-s 打出栈信息
-d打印详细信息
打印接下来10秒内方法的调用情况(方法全名(含参数列表), 当前类的加载器对象, 总计调用次数, 平均调用耗时, 调用的自身对象)
1
2
3
4
5
6
7
8
9
|
housemd> trace -t
10
TimeInfoManagerImpl.querySellerAvgSpeed
INFO : Probe
class
com.taobao.commonway.core.service.impl.TimeInfoManagerImpl
No traced method invoked
com/taobao/commonway/core/service/impl/TimeInfoManagerImpl.querySellerAvgSpeed(
long
, String) sun.misc.Launcher$AppClassLoader
@4aad3ba4
3
5ms com.taobao.commonway.core.service.impl.TimeInfoManagerImpl
@794352d2
INFO : Ended by timeout
INFO : Reset
class
com.taobao.commonway.core.service.impl.TimeInfoManagerImpl
|
打印调用的详细信息
1
2
3
4
5
6
7
8
9
10
11
|
housemd> trace -d TimeInfoManagerImpl.querySellerAvgSpeed
INFO : Probe
class
com.taobao.commonway.core.service.impl.TimeInfoManagerImpl
No traced method invoked
No traced method invoked
com/taobao/commonway/core/service/impl/TimeInfoManagerImpl.querySellerAvgSpeed(
long
, String) sun.misc.Launcher$AppClassLoader
@4aad3ba4
1
3ms com.taobao.commonway.core.service.impl.TimeInfoManagerImpl
@794352d2
INFO : You can get invocation detail from /tmp/trace/
23259
@commonway079145
.pre.cm3.tbsite.net/detail
INFO : Ended by timeout
INFO : Reset
class
com.taobao.commonway.core.service.impl.TimeInfoManagerImpl
|
日志中的详细信息
(日期, 时间戳, 调用耗时, 调用线程名, 调用方法的自身对象, 调用方法全名, 调用方法参数值列表, 返回值(或异常))
1
2
3
4
5
6
7
8
9
10
|
more /tmp/trace/
23259
@commonway079145
.pre.cm3.tbsite.net/detail
2012
-
11
-
20
16
:
44
:
06
3ms [http-
0.0
.
0.0
-
7001
-
6
] com.taobao.commonway.core.service.impl.TimeInfoManagerImpl
@794352d2
com/taobao/commonw
ay/core/service/impl/TimeInfoManagerImpl.querySellerAvgSpeed [
341952863
121.0
.
29.228
] com.taobao.commonway.common.TimeResultDO
@1a882
b79[
consignTime=
20
timeCost=
66
industryCtime=
21
industryStime=
44
]
|
(3)查看类中属性的值(inspect 类名称)( 属性全名, 属性值, 自身对象实例 , 此类的类加载器)
1
2
3
4
5
6
7
8
9
10
|
housemd> inspect TimeResultDO.consignTime
INFO : Probe
class
com.taobao.commonway.common.TimeResultDO
TimeResultDO.consignTime
20
com.taobao.commonway.common.TimeResultDO
@eec91ef
[
consignTime=
20
timeCost=
66
industryCtime=
21
industryStime=
44
] org.jboss.mx.loading.UnifiedClassLoader3
@37debcf3
{ url=file:/home/admin/commonway/.
default
/deploy/commonway.war/ ,addedOrder=
44
}
INFO : Ended by timeout
INFO : Reset
class
com.taobao.commonway.common.TimeResultDO
|
https://github.com/zhongl/HouseMD/wiki/UserGuideCN
https://github.com/downloads/zhongl/HouseMD/housemd_2.9.2-0.2.4.min.jar