Skywalking Agent源码解读 - 从premain方法开始

 

源代码解读的版本为8.7.0。

入口

从MANIFEST.MF文件中找到,

Premain-Class: org.apache.skywalking.apm.agent.SkyWalkingAgent

SkyWalkingAgent

premain方法

主要做了这些逻辑:

//SkyWalking agent initialized

SnifferConfigInitializer.initializeCoreConfig(agentArgs);

//SkyWalking agent initialized

pluginFinder = new PluginFinder(new PluginBootstrap().loadPlugins());

//SkyWalking agent inject bootstrap instrumentation

agentBuilder = BootstrapInstrumentBoost.inject(pluginFinder, instrumentation, agentBuilder, edgeClasses);

//SkyWalking agent open read edge in JDK 9+

agentBuilder = agentBuilder.with(new CacheableTransformerDecorator(Config.Agent.CLASS_CACHE_MODE));

// SkyWalking agent active class cache

if (Config.Agent.IS_CACHE_ENHANCED_CLASS) {

agentBuilder = agentBuilder.with(new CacheableTransformerDecorator(Config.Agent.CLASS_CACHE_MODE));

}

//Skywalking agent boot

ServiceManager.INSTANCE.boot();

1. SnifferConfigInitializer.initializeCoreConfig(agentArgs);

Java
 public static void initializeCoreConfig(String agentOptions) {
 // AGENT_SETTINGS 为Properties类变量
    AGENT_SETTINGS = new Properties();
    // 加载默认配置:config/agent.config,解析读入至AGENT_SETTINGS变量中
    try (final InputStreamReader configFileStream = loadConfig()) {
        AGENT_SETTINGS.load(configFileStream);
        for (String key : AGENT_SETTINGS.stringPropertyNames()) {
            String value = (String) AGENT_SETTINGS.get(key);
            AGENT_SETTINGS.put(key, PropertyPlaceholderHelper.INSTANCE.replacePlaceholders(value, AGENT_SETTINGS));
        }

    } catch (Exception e) {
        LOGGER.error(e, "Failed to read the config file, skywalking is going to run in default config.");
    }
// 读取可能存在的system properties,覆盖默认配置
    try {
        overrideConfigBySystemProp();
    } catch (Exception e) {
        LOGGER.error(e, "Failed to read the system properties.");
    }
// 读取agentArgs可能传入的参数,覆盖默认配置
    agentOptions = StringUtil.trim(agentOptions, ',');
    if (!StringUtil.isEmpty(agentOptions)) {
        try {
            agentOptions = agentOptions.trim();
            LOGGER.info("Agent options is {}.", agentOptions);

            overrideConfigByAgentOptions(agentOptions);
        } catch (Exception e) {
            LOGGER.error(e, "Failed to parse the agent options, val is {}.", agentOptions);
        }
    }

    initializeConfig(Config.class);
    // reconfigure logger after config initialization
    configureLogger();
    LOGGER = LogManager.getLogger(SnifferConfigInitializer.class);

    if (StringUtil.isEmpty(Config.Agent.SERVICE_NAME)) {
        throw new ExceptionInInitializerError("`agent.service_name` is missing.");
    }
    if (StringUtil.isEmpty(Config.Collector.BACKEND_SERVICE)) {
        throw new ExceptionInInitializerError("`collector.backend_service` is missing.");
    }
    if (Config.Plugin.PEER_MAX_LENGTH <= 3) {
        LOGGER.warn(
            "PEER_MAX_LENGTH configuration:{} error, the default value of 200 will be used.",
            Config.Plugin.PEER_MAX_LENGTH
        );
        Config.Plugin.PEER_MAX_LENGTH = 200;
    }

    IS_INIT_COMPLETED = true;
}

2. pluginFinder = new PluginFinder(new PluginBootstrap().loadPlugins());

Java

/**
 * The <code>PluginFinder</code> represents a finder , which assist to find the one from the given {@link
 * AbstractClassEnhancePluginDefine} list.
 */
public class PluginFinder {
    private final Map<String, LinkedList<AbstractClassEnhancePluginDefine>> nameMatchDefine = new HashMap<String, LinkedList<AbstractClassEnhancePluginDefine>>();
    private final List<AbstractClassEnhancePluginDefine> signatureMatchDefine = new ArrayList<AbstractClassEnhancePluginDefine>();
    private final List<AbstractClassEnhancePluginDefine> bootstrapClassMatchDefine = new ArrayList<AbstractClassEnhancePluginDefine>();

    public PluginFinder(List<AbstractClassEnhancePluginDefine> plugins) {
        for (AbstractClassEnhancePluginDefine plugin : plugins) {
            ClassMatch match = plugin.enhanceClass();

            if (match == null) {
                continue;
            }

            if (match instanceof NameMatch) {
                NameMatch nameMatch = (NameMatch) match;
                LinkedList<AbstractClassEnhancePluginDefine> pluginDefines = nameMatchDefine.get(nameMatch.getClassName());
                if (pluginDefines == null) {
                    pluginDefines = new LinkedList<AbstractClassEnhancePluginDefine>();
                    nameMatchDefine.put(nameMatch.getClassName(), pluginDefines);
                }
                pluginDefines.add(plugin);
            } else {
                signatureMatchDefine.add(plugin);
            }

            if (plugin.isBootstrapInstrumentation()) {
                bootstrapClassMatchDefine.add(plugin);
            }
        }
    }

    public List<AbstractClassEnhancePluginDefine> find(TypeDescription typeDescription) {
        List<AbstractClassEnhancePluginDefine> matchedPlugins = new LinkedList<AbstractClassEnhancePluginDefine>();
        String typeName = typeDescription.getTypeName();
        if (nameMatchDefine.containsKey(typeName)) {
            matchedPlugins.addAll(nameMatchDefine.get(typeName));
        }

        for (AbstractClassEnhancePluginDefine pluginDefine : signatureMatchDefine) {
            IndirectMatch match = (IndirectMatch) pluginDefine.enhanceClass();
            if (match.isMatch(typeDescription)) {
                matchedPlugins.add(pluginDefine);
            }
        }

        return matchedPlugins;
    }

    public ElementMatcher<? super TypeDescription> buildMatch() {
        ElementMatcher.Junction judge = new AbstractJunction<NamedElement>() {
            @Override
            public boolean matches(NamedElement target) {
                return nameMatchDefine.containsKey(target.getActualName());
            }
        };
        judge = judge.and(not(isInterface()));
        for (AbstractClassEnhancePluginDefine define : signatureMatchDefine) {
            ClassMatch match = define.enhanceClass();
            if (match instanceof IndirectMatch) {
                judge = judge.or(((IndirectMatch) match).buildJunction());
            }
        }
        return new ProtectiveShieldMatcher(judge);
    }

    public List<AbstractClassEnhancePluginDefine> getBootstrapClassMatchDefine() {
        return bootstrapClassMatchDefine;
    }
}

new PluginBootstrap().loadPlugins()

Java
/**
 * load all plugins.
 *
 * @return plugin definition list.
 */
public List<AbstractClassEnhancePluginDefine> loadPlugins() throws AgentPackageNotFoundException {
  // 加载插件包(默认为plugins/activations目录下)
    AgentClassLoader.initDefaultLoader();
// 读取和加载skywalking-plugin.def
    PluginResourcesResolver resolver = new PluginResourcesResolver();
    List<URL> resources = resolver.getResources();

    if (resources == null || resources.size() == 0) {
        LOGGER.info("no plugin files (skywalking-plugin.def) found, continue to start application.");
        return new ArrayList<AbstractClassEnhancePluginDefine>();
    }

    for (URL pluginUrl : resources) {
        try {
            PluginCfg.INSTANCE.load(pluginUrl.openStream());
        } catch (Throwable t) {
            LOGGER.error(t, "plugin file [{}] init failure.", pluginUrl);
        }
    }

    List<PluginDefine> pluginClassList = PluginCfg.INSTANCE.getPluginClassList();

    List<AbstractClassEnhancePluginDefine> plugins = new ArrayList<AbstractClassEnhancePluginDefine>();
    for (PluginDefine pluginDefine : pluginClassList) {
        try {
            LOGGER.debug("loading plugin class {}.", pluginDefine.getDefineClass());
            AbstractClassEnhancePluginDefine plugin = (AbstractClassEnhancePluginDefine) Class.forName(pluginDefine.getDefineClass(), true, AgentClassLoader
                .getDefault()).newInstance();
            plugins.add(plugin);
        } catch (Throwable t) {
            LOGGER.error(t, "load plugin [{}] failure.", pluginDefine.getDefineClass());
        }
    }

    plugins.addAll(DynamicPluginLoader.INSTANCE.load(AgentClassLoader.getDefault()));

    return plugins;

}

AgentClassLoader.initDefaultLoader();

Java
/**
 * Init the default class loader.
 *
 * @throws AgentPackageNotFoundException if agent package is not found.
 */
public static void initDefaultLoader() throws AgentPackageNotFoundException {
    if (DEFAULT_LOADER == null) {
        synchronized (AgentClassLoader.class) {
            if (DEFAULT_LOADER == null) {
                DEFAULT_LOADER = new AgentClassLoader(PluginBootstrap.class.getClassLoader());
            }
        }
    }
}
// 其中MOUNT为Arrays.asList("plugins", "activations");
public AgentClassLoader(ClassLoader parent) throws AgentPackageNotFoundException {
    super(parent);
    File agentDictionary = AgentPackagePath.getPath();
    classpath = new LinkedList<>();
    Config.Plugin.MOUNT.forEach(mountFolder -> classpath.add(new File(agentDictionary, mountFolder)));
}

3. agentBuilder

是bytebuddy创建相关的字节码,待补充。TODO

4. ServiceManager.INSTANCE.boot()

boot()

TypeScript
public void boot() {
    bootedServices = loadAllServices();

    prepare();
    startup();
    onComplete();
}

bootedServices = loadAllServices();

TypeScript
private Map<Class, BootService> loadAllServices() {
    Map<Class, BootService> bootedServices = new LinkedHashMap<>();
    List<BootService> allServices = new LinkedList<>();
    load(allServices);
    for (final BootService bootService : allServices) {
        Class<? extends BootService> bootServiceClass = bootService.getClass();
        boolean isDefaultImplementor = bootServiceClass.isAnnotationPresent(DefaultImplementor.class);
        if (isDefaultImplementor) {
            if (!bootedServices.containsKey(bootServiceClass)) {
                bootedServices.put(bootServiceClass, bootService);
            } else {
                //ignore the default service
            }
        } else {
            OverrideImplementor overrideImplementor = bootServiceClass.getAnnotation(OverrideImplementor.class);
            if (overrideImplementor == null) {
                if (!bootedServices.containsKey(bootServiceClass)) {
                    bootedServices.put(bootServiceClass, bootService);
                } else {
                    throw new ServiceConflictException("Duplicate service define for :" + bootServiceClass);
                }
            } else {
                Class<? extends BootService> targetService = overrideImplementor.value();
                if (bootedServices.containsKey(targetService)) {
                    boolean presentDefault = bootedServices.get(targetService)
                                                           .getClass()
                                                           .isAnnotationPresent(DefaultImplementor.class);
                    if (presentDefault) {
                        bootedServices.put(targetService, bootService);
                    } else {
                        throw new ServiceConflictException(
                            "Service " + bootServiceClass + " overrides conflict, " + "exist more than one service want to override :" + targetService);
                    }
                } else {
                    bootedServices.put(targetService, bootService);
                }
            }
        }

    }
    return bootedServices;
}

load(allServices);

Java
void load(List<BootService> allServices) {
    for (final BootService bootService : ServiceLoader.load(BootService.class, AgentClassLoader.getDefault())) {
        allServices.add(bootService);
    }
}

代码解读:

ServiceLoader为SPI机制,从apm-sniffer工程下的apm-agent-core模块, resouces/META-INF/services目录下的org.apache.skywalking.apm.agent.core.boot.BootService文件读取下面文件内容,这些内容为需要启动的类,SPI加载这些BootService的实现类,添加至List<BootService> allServices 返回给bootedServices。

Plain Text

org.apache.skywalking.apm.agent.core.remote.TraceSegmentServiceClient
org.apache.skywalking.apm.agent.core.context.ContextManager
org.apache.skywalking.apm.agent.core.sampling.SamplingService
org.apache.skywalking.apm.agent.core.remote.GRPCChannelManager
org.apache.skywalking.apm.agent.core.jvm.JVMMetricsSender
org.apache.skywalking.apm.agent.core.jvm.JVMService
org.apache.skywalking.apm.agent.core.remote.ServiceManagementClient
org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService
org.apache.skywalking.apm.agent.core.commands.CommandService
org.apache.skywalking.apm.agent.core.commands.CommandExecutorService
org.apache.skywalking.apm.agent.core.profile.ProfileTaskChannelService
org.apache.skywalking.apm.agent.core.profile.ProfileSnapshotSender
org.apache.skywalking.apm.agent.core.profile.ProfileTaskExecutionService
org.apache.skywalking.apm.agent.core.meter.MeterService
org.apache.skywalking.apm.agent.core.meter.MeterSender
org.apache.skywalking.apm.agent.core.context.status.StatusCheckService
org.apache.skywalking.apm.agent.core.remote.LogReportServiceClient
org.apache.skywalking.apm.agent.core.conf.dynamic.ConfigurationDiscoveryService
org.apache.skywalking.apm.agent.core.remote.EventReportServiceClient
org.apache.skywalking.apm.agent.core.ServiceInstanceGenerator

prepare()

TypeScript
private void prepare() {
    bootedServices.values().stream().sorted(Comparator.comparingInt(BootService::priority)).forEach(service -> {
        try {
            service.prepare();
        } catch (Throwable e) {
            LOGGER.error(e, "ServiceManager try to pre-start [{}] fail.", service.getClass().getName());
        }
    });
}

代码解读:

按照BootService中的priority(按自然排序,从小到大)排序依次执行bootedServices = loadAllServices()返回的service对象的prepare方法。

startup()

TypeScript
private void startup() {
    bootedServices.values().stream().sorted(Comparator.comparingInt(BootService::priority)).forEach(service -> {
        try {
            service.boot();
        } catch (Throwable e) {
            LOGGER.error(e, "ServiceManager try to start [{}] fail.", service.getClass().getName());
        }
    });
}

代码解读:

按照BootService中的priority(按自然排序,从小到大)排序依次执行bootedServices = loadAllServices()返回的service对象的boot方法。

onComplete()

TypeScript
private void onComplete() {
    for (BootService service : bootedServices.values()) {
        try {
            service.onComplete();
        } catch (Throwable e) {
            LOGGER.error(e, "Service [{}] AfterBoot process fails.", service.getClass().getName());
        }
    }
}

代码解读:执行bootedServices = loadAllServices()返回的service对象的onComplete方法。

prioritySPI加载的类

其中

org.apache.skywalking.apm.agent.core.remote.GRPCChannelManager

org.apache.skywalking.apm.agent.core.ServiceInstanceGenerator

的priority为最大值(Integer.MAX_VALUE);

其他类的priority都为默认值0。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值