源代码解读的版本为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。