java agent 01.搭建agent

创建一个java maven工程

Step1 添加bytebuddy及日志依赖


        
            org.springframework
            spring-web
            5.2.9.RELEASE
            provided
        

        
        
            net.bytebuddy
            byte-buddy
            1.10.19
        

        
            org.slf4j
            slf4j-api
            1.7.30
            provided
        
    

Step2 书写Agent的入口处

agent有两个入口函数,分别是premain和agentmain,用于两种启动场景-javaagent启动场景和attach启动场景,我们这里先书写-javaagent启动场景

package com.github.shoothzj.demo.agent;

import net.bytebuddy.ByteBuddy;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.matcher.ElementMatchers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.instrument.Instrumentation;

import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;

/**
 * @author hezhangjian
 */
public class AgentMain {

    private static final Logger log = LoggerFactory.getLogger(AgentMain.class);

    /**
     * call on -javaagnet
     * @param agentArgs
     * @param inst
     */
    public static void premain(String agentArgs, Instrumentation inst) {
        System.out.println("start agent premain");
        final ByteBuddy byteBuddy = new ByteBuddy();
        new AgentBuilder.Default(byteBuddy)
                //这些类都是常见的无需切面注入的类,忽略掉可以提升agent加载速度
                .ignore(nameStartsWith("net.bytebuddy.")
                        .or(nameStartsWith("org.slf4j.")
                        .or(nameStartsWith("org.apache.logging.")
                        .or(nameStartsWith("org.groovy."))
                        .or(nameStartsWith("javassist"))
                        .or(nameStartsWith(".asm."))
                        .or(nameStartsWith("sun.reflect"))
                        .or(ElementMatchers.isSynthetic()))))
                //你想切面的包名
                .type(ElementMatchers.nameStartsWith("com.github.shoothzj.agent.test"))
                .transform(new AgentTransformer())
                .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
                .installOn(inst);
    }

    public static void agentmain(String agentArgs, Instrumentation inst) {
        System.out.println("start agent main");
    }

}

这个时候Transform先书写一个空实现

package com.github.shoothzj.demo.agent;

import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.utility.JavaModule;

/**
 * @author hezhangjian
 */
public class AgentTransformer implements AgentBuilder.Transformer{

    @Override
    public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule javaModule) {
        return builder;
    }

}

Step3 maven pom文件配置打包


        
            
                org.apache.maven.plugins
                maven-shade-plugin
                3.2.4
                
                    
                        package
                        
                            shade
                        
                        
                            
                                
                                    
                                        com.github.shoothzj.demo.agent.AgentMain
                                        true
                                        true
                                    
                                
                            
                            
                                
                                    org.slf4j:slf4j-api
                                    org.apache.logging.log4j:log4j-api
                                    org.apache.logging.log4j:log4j-core
                                    org.apache.logging.log4j:log4j-slf4j-impl
                                    org.apache.logging.log4j:log4j-jcl
                                
                            
                            
                                
                                    *:*
                                    
                                        META-INF/*.SF
                                        META-INF/*.DSA
                                        META-INF/*.RSA
                                    
                                
                            
                            
                                
                                    org.slf4j
                                    com.github.shoothzj.org.slf4j
                                
                                
                                    org.apache.logging
                                    com.github.shoothzj.org.apache.logging
                                
                            
                        
                    
                
            
        
    

这里配置了打java agent的包,和打shade包规避类冲突的问题,关于打shade包,可以参考https://www.jianshu.com/p/8171607ce03f

创建一个测试SpringBoot工程

Step1 书写主函数

package com.github.shoothzj.demo.agent.test;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author hezhangjian
 */
@Slf4j
@SpringBootApplication
public class AgentTestMain {

    public static void main(String[] args) {
        SpringApplication.run(AgentTestMain.class);
    }

}

Step2 修改运行参数,加载java agent

这里我的agent,maven package后的路径在 /Users/akka/master/maven-demo/demo-agent/target/demo-agent-0.0.1.SNAPSHOT.jar

-javaagent:/Users/akka/master/maven-demo/demo-agent/target/demo-agent-0.0.1.SNAPSHOT.jar

image-20201230215511785

Step3 运行结果

image-20201231082704607

可以看到agent已经正常启动

你可能感兴趣的:(java agent 01.搭建agent)