关于 Java 的如何进行单体应用 tracing 的问题

267 天前
 Zzhiter

各位大佬好,我现在有一个需求:

启动一个程序 A 一直执行单测 B ,对于每次测试 C ,需要获取到 C 当次测试用例的执行路径信息: 即调用点在哪里,依次经过了哪些函数,最后在哪里终止(终止点某个函数的某一行)

程序的执行过程是一个不断压栈弹栈的过程,想要获取完整的执行路径,只有最后的栈快照是不行的。 目前想到的方法是这样的:

在每个方法的第一行插入一段代码,这段代码可以完成以下功能: 调用 A 程序中的静态方法,把自己的函数名称传递给 A 。

在 A 程序中维护一个 C 的执行路径序列,这样在 C 运行结束的时候,就可以获取到 C 执行了哪些函数。具体在某一行截至这个还没考虑。

不知道自己考虑的对不对,或者大家还有没有什么更好的方案,希望可以多多交流

2244 次点击
所在节点    Java
22 条回复
foolishcrab
267 天前
写过几乎一模一样的代码,基于 agent 的字节码修改,逻辑跟你描述的差不多,是可以实现的
iseki
267 天前
主要还是得考虑跨线程时怎么处理
Zzhiter
267 天前
@iseki 对的,这个是比较难的一个点
Zzhiter
267 天前
@foolishcrab 好的,谢谢大佬
Mmahaha
267 天前
前段时间也在研究这个,方法和 1L 说的一样,用的是 javaassist
Zzhiter
267 天前
@Mmahaha 对,我现在了解到有 ASM ,javassist ,bytebuddy ,还在想具体用哪一个
Ayanokouji
267 天前
如果只是调试,arthas 应该可以吧
Zzhiter
267 天前
@Ayanokouji 嗯嗯,关键在于想把整个流程自动化,如果要是 arthas 有 api 就好了😂😂
winv87
267 天前
几年前看过 jvm sandbox ,Arthas 相当于成品,看看这个试试呢
Ayanokouji
267 天前
@winv87 arthas 有 api 的,但是不清楚满不满足你的需求
Zzhiter
267 天前
@Ayanokouji 感谢!我去看一下
mpi2018
267 天前
wolfie
267 天前
感觉实现原理不是很难,需要增强全部 class ,skywalking 就在启动时指定 javaagent 并用 bytebuddy 增强的。

https://github.com/apache/skywalking
dyv9
265 天前
以前为了测试公司自研的框架事务不能回滚错在回哪里,俺用 AspectJ 读取 ejb-jar.xml / web.xml 里面的事务相关设置,用 AspectJ 把涉及到事务边界的地方拿来记录事件,在事务上下文切换时要检测在这事务边界内使用的 JDBC 连接等资源当前应该是绑定到哪个事务,为什么作为参数传递下去会越界,检测到 把一个在事务 A 中打开的连接传参到事务 B 中导致的事务不一致。这些类似的东西只能是操作字节码自动插入代码,用 AspectJ 静态编织很方便。
Aresxue
265 天前
这不就是 arthas 的 trace 嘛,直接搞过来。pinpoint 、jvm sandbox 等也可以抄一抄。
xhd2015
260 天前
这个在 go 中已经实现了,原理是代码重写。java 应该更容易,参考这个例子: https://github.com/xhd2015/xgo/blob/master/cmd/xgo/trace/testdata/stack_trace.jpg

这是一个完整的调用堆栈
Zzhiter
260 天前
@xhd2015 太厉害了,我学习一下,楼主竟然还是工大学长
xhd2015
260 天前
巧了。你的关于插入代码想法是正确的
Zzhiter
260 天前
@xhd2015 我现在在想的问题是,A 中调用了很多次的 B ,比如 B 在一个循环中的话,B 是存几次,存一次感觉有点不精确,存多次好像又不太合理
xhd2015
260 天前
@Zzhiter 存多次,存在数组中。其实调用栈就是一棵树,每次调用都是产生一个子结点。存储结构:
StactTrace{
ClassName string
Method string
Request Object
Response Object
Children StackTrace[]
}
可以参考这个定义: https://github.com/xhd2015/xgo/blob/1211c519c8005ddbd66189cf64e958aa69e5789f/runtime/trace/stack.go#L16

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1028385

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX