源代码解读的版本为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方法。
按priority看SPI加载的类
其中
org.apache.skywalking.apm.agent.core.remote.GRPCChannelManager
org.apache.skywalking.apm.agent.core.ServiceInstanceGenerator
的priority为最大值(Integer.MAX_VALUE);
其他类的priority都为默认值0。