『互联网架构』插桩处理埋点

网友投稿 700 2022-11-04

『互联网架构』插桩处理埋点

『互联网架构』插桩处理埋点

上节说了javaagent和javassist,其实javassist也是基于ASM实现的。一般人不懂得JVM指令的话,根本ASM搞不起来,也用到了访问者的设计模式,看起来跟咱们写代码不是一个套路,学习成本比较高,所以有了javassist。

(一)插桩

修改上节源码,进行插桩

IdigAgentTest package com.idig8;

import com.idig8.agent.test.UserServiceImpl;

import java.lang.instrument.Instrumentation;

public class IdigAgentTest {public static void main(String[] args) {System.out.println("hello world idig8!");UserServiceImpl userService = new UserServiceImpl();userService.hello();}}

![](https://s2./images/blog/202207/04100613_62c24b155914385718.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) > UserServiceImpl 增加hello方法,打印方法里面的内容 ``` java package com.idig8.agent.test; public class UserServiceImpl { public UserServiceImpl(){ System.out.println("hello world!"); } public void hello(){ String p1 ="100"; System.out.print("p1 = "+p1); } }

IdigAgent 增加插桩的方法 package com.idig8.agent.test;

import javassist.*;

import java.io.IOException;import java.lang.instrument.ClassFileTransformer;import java.lang.instrument.IllegalClassFormatException;import java.lang.instrument.Instrumentation;import java.security.ProtectionDomain;

public class IdigAgent {public static void premain(String args, Instrumentation instrumentation) {System.out.println("premain:" + args);

instrumentation.addTransformer(new ClassFileTransformer() { @Override public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { if (!"com/idig8/agent/test/UserServiceImpl".equals(className)) { return null; } // javassist 工具 改造 try { ClassPool pool = new ClassPool(); pool.insertClassPath(new LoaderClassPath(loader)); CtClass ctclass = pool.get("com.idig8.agent.test.UserServiceImpl"); CtMethod method = ctclass.getDeclaredMethod("hello"); method.insertBefore(" System.out.println(System.currentTimeMillis());");

// method.insertBefore("long begin = System.currentTimeMillis();"// +" System.out.println(begin);");//// method.insertAfter(" long end = System.currentTimeMillis();\n" +// " System.out.println(end - begin);");return ctclass.toBytecode();} catch (NotFoundException e) {e.printStackTrace();} catch (CannotCompileException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}

return null; } }); }

}

![](https://s2./images/blog/202207/04100613_62c24b155f8e273892.png?x-oss-process=image/watermark,size_14,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=) > pom中添加javassist的jar包 ``` java org.javassist javassist 3.18.1-GA

javassist.CannotCompileException: [source error] no such field: begin

为什么呢,因为插桩的时候都是以代码快的形式,局部变量。

在实际开发中不用修改原有的方法,而是会新写一个方法,在新方法进行出来,调用要插桩的方法。新方法的参数和要插桩的保持一致,包括注解,参数。其实有点类似动态代理。

public void hello$agent() { { long begin = System.currentTimeMillis(); try{ hello(); }finally { long end = System.currentTimeMillis(); System.out.println(end - begin); } } }

具体如何实现,后面会说

PS:还需要结合之前文章,了解如何完成插桩和埋点。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:轻量级的实时内存管理应用程序,用于监视和清理计算机上的系统内存
下一篇:用于测量,监视和分析在运行的Python程序中Python对象的内存行为的开发工具
相关文章

 发表评论

暂时没有评论,来抢沙发吧~