基于 SkyWalking Java Agent 8.8.0 版本
今天我们要分析的是 SkyWalking Java Agent 配置相关内容,我们接触到的框架大都需要一些配置文件,比如 SpringBoot 中的 application.yml。 SkyWalking Java Agent 在 premain 方法中首先做的就是通过 SnifferConfigInitializer.initializeCoreConfig(agentArgs);
初始化核心配置。
/**
* The main entrance of sky-walking agent, based on javaagent mechanism.
*/
public class SkyWalkingAgent {
private static ILog LOGGER = LogManager.getLogger(SkyWalkingAgent.class);
/**
* Main entrance. Use byte-buddy transform to enhance all classes, which define in plugins.
*/
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);
}
// 省略部分代码....
}
// 省略部分代码....
}
复制代码
今天我们要重点分析的就是这行代码的内部实现
SnifferConfigInitializer.initializeCoreConfig(agentArgs);
复制代码
初始化核心配置
SnifferConfigInitializer 类使用多种方式初始化配置,内部实现有以下几个重要步骤:
1.loadConfig() 加载配置文件
- 从指定的配置文件路径读取配置文件内容,通过 -Dskywalking_config=/xxx/yyy 可以指定配置文件位置;
- 如果没有指定配置文件路径,则从默认配置文件 config/agent.config 读取;
- 将配置文件内容加载到 Properties;
/**
* Load the specified config file or default config file
*
* @return the config file {@link InputStream}, or null if not needEnhance.
*/
private static InputStreamReader loadConfig() throws AgentPackageNotFoundException, ConfigNotFoundException {
// System.getProperty() 读取 Java 虚拟机中的系统属性, Java 虚拟机中的系统属性在运行Java程序的时候通过 java -Dk1=v1 配置.
String specifiedConfigPath = System.getProperty(SPECIFIED_CONFIG_PATH);
// 使用指定的配置文件或默认的配置文件, AgentPackagePath.getPath() 获取 skywalking-agent.jar 所在目录
File configFile = StringUtil.isEmpty(specifiedConfigPath) ? new File(
AgentPackagePath.getPath(), DEFAULT_CONFIG_FILE_NAME) : new File(specifiedConfigPath);
if (configFile.exists() && configFile.isFile()) {
try {
LOGGER.info("Config file found in {}.", configFile);
return new InputStreamReader(new FileInputStream(configFile), StandardCharsets.UTF_8);
} catch (FileNotFoundException e) {
throw new ConfigNotFoundException("Failed to load agent.config", e);
}
}
throw new ConfigNotFoundException("Failed to load agent.config.");
}
复制代码
2.replacePlaceholders() 解析占位符 placeholder
- 从配置文件中读取到的配置值都是以 placeholder 形式(比如 agent.service_name=${SW_AGENT_NAME:Your_ApplicationName})存在的,这里需要将占位符解析为实际值。
/**
* Replaces all placeholders of format {@code ${name}} with the corresponding property from the supplied {@link
* Properties}.
*
* @param value the value containing the placeholders to be replaced
* @param properties the {@code Properties} to use for replacement
*