skywalking源码流程
我们已经知道skywalking的入口就是premain方法:
public static void premain(String agentArgs, Instrumentation instrumentation) throws PluginException { final PluginFinder pluginFinder; try { //初始化配置 SnifferConfigInitializer.initializeCoreConfig(agentArgs); } catch (Exception e) { // try to resolve a new logger, and use the new logger to write the error log here //异常重新获取日志类型 LogManager.getLogger(SkyWalkingAgent.class) .error(e, "SkyWalking agent initialized failure. Shutting down."); return; } finally { // refresh logger again after initialization finishes LOGGER = LogManager.getLogger(SkyWalkingAgent.class); } try { //加载插件 pluginFinder = new PluginFinder(new PluginBootstrap().loadPlugins()); } catch (AgentPackageNotFoundException ape) { LOGGER.error(ape, "Locate agent.jar failure. Shutting down."); return; } catch (Exception e) { LOGGER.error(e, "SkyWalking agent initialized failure. Shutting down."); return; } //创建bytebuddy final ByteBuddy byteBuddy = new ByteBuddy().with(TypeValidation.of(Config.Agent.IS_OPEN_DEBUGGING_CLASS)); AgentBuilder agentBuilder = new AgentBuilder.Default(byteBuddy).ignore( nameStartsWith("net.bytebuddy.") .or(nameStartsWith("org.slf4j.")) .or(nameStartsWith("org.groovy.")) .or(nameContains("javassist")) .or(nameContains(".asm.")) .or(nameContains(".reflectasm.")) .or(nameStartsWith("sun.reflect")) .or(allSkyWalkingAgentExcludeToolkit()) .or(ElementMatchers.isSynthetic())); JDK9ModuleExporter.EdgeClasses edgeClasses = new JDK9ModuleExporter.EdgeClasses(); try { agentBuilder = BootstrapInstrumentBoost.inject(pluginFinder, instrumentation, agentBuilder, edgeClasses); } catch (Exception e) { LOGGER.error(e, "SkyWalking agent inject bootstrap instrumentation failure. Shutting down."); return; } try { agentBuilder = JDK9ModuleExporter.openReadEdge(instrumentation, agentBuilder, edgeClasses); } catch (Exception e) { LOGGER.error(e, "SkyWalking agent open read edge in JDK 9+ failure. Shutting down."); return; } if (Config.Agent.IS_CACHE_ENHANCED_CLASS) { try { agentBuilder = agentBuilder.with(new CacheableTransformerDecorator(Config.Agent.CLASS_CACHE_MODE)); LOGGER.info("SkyWalking agent class cache [{}] activated.", Config.Agent.CLASS_CACHE_MODE); } catch (Exception e) { LOGGER.error(e, "SkyWalking agent can't active class cache."); } } agentBuilder.type(pluginFinder.buildMatch()) .transform(new Transformer(pluginFinder)) .with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION) .with(new RedefinitionListener()) .with(new Listener()) .installOn(instrumentation); try { ServiceManager.INSTANCE.boot(); } catch (Exception e) { LOGGER.error(e, "Skywalking agent boot failure."); } //添加shutdown Runtime.getRuntime() .addShutdownHook(new Thread(ServiceManager.INSTANCE::shutdown, "skywalking service shutdown thread")); }
可以看到首先执行的是加载配置的方法,我们往下看:
public static void initializeCoreConfig(String agentOptions) { AGENT_SETTINGS = new Properties(); //读取指定文件中配置并放入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."); } try { //读取系统环境变量配置 overrideConfigBySystemProp(); } catch (Exception e) { LOGGER.error(e, "Failed to read the system properties."); } //读取-javaagent传入的参数 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); } } //将上面读取完的参数都放到Config配置里面 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; }
这里会从指定文件,环境变量和指定参数配置下依次读取,然后设置日志级别。
接下来就是插件的加载过程: