-
@param value the value containing the placeholders to be replaced
-
@param properties the {@code Properties} to use for replacement
-
@return the supplied value with placeholders replaced inline
*/
public String replacePlaceholders(String value, final Properties properties) {
return replacePlaceholders(value, new PlaceholderResolver() {
@Override
public String resolvePlaceholder(String placeholderName) {
return getConfigValue(placeholderName, properties);
}
});
}
// 优先级 System.Properties(-D) > System environment variables > Config file
private String getConfigValue(String key, final Properties properties) {
// 从Java虚拟机系统属性中获取(-D)
String value = System.getProperty(key);
if (value == null) {
// 从操作系统环境变量获取, 比如 JAVA_HOME、Path 等环境变量
value = System.getenv(key);
}
if (value == null) {
// 从配置文件中获取
value = properties.getProperty(key);
}
return value;
}
复制代码
3.overrideConfigBySystemProp() 读取 System.getProperties() 中以 skywalking. 开头的系统属性覆盖配置;
/**
-
Override the config by system properties. The property key must start with
skywalking
, the result should be as -
same as in
agent.config
-
-
such as: Property key of
agent.service_name
should beskywalking.agent.service_name
*/
private static void overrideConfigBySystemProp() throws IllegalAccessException {
Properties systemProperties = System.getProperties();
for (final Map.Entry<Object, Object> prop : systemProperties.entrySet()) {
String key = prop.getKey().toString();
// 必须是以 skywalking. 开头的属性
if (key.startsWith(ENV_KEY_PREFIX)) {
String realKey = key.substring(ENV_KEY_PREFIX.length());
AGENT_SETTINGS.put(realKey, prop.getValue());
}
}
}
复制代码
4.overrideConfigByAgentOptions() 解析 agentArgs 参数配置覆盖配置;
- agentArgs 就是 premain 方法的第一个参数,以
-javaagent:/path/to/skywalking-agent.jar=k1=v1,k2=v2
的形式传值。
5.initializeConfig() 将以上读取到的配置信息映射到 Config 类的静态属性,后面会重点分析;
6.configureLogger() 根据配置的 Config.Logging.RESOLVER 重配置 Log,更多关于日志参见文章 SkyWalking Java Agent 日志组件分析;
static void configureLogger() {
switch (Config.Logging.RESOLVER) {
case JSON:
LogManager.setLogResolver(new JsonLogResolver());
break;
case PATTERN:
default:
LogManager.setLogResolver(new PatternLogResolver());
}
}
复制代码
7.必填参数验证,验证非空参数 agent.service_name 和 collector.servers。
定位 skywalking-agent.jar 所在目录
skywalking-agent 目录结构如下:
config 目录存放的是默认配置文件 agent.config,读取默认配置文件,以及后面加载插件都需要用到 skywalking-agent.jar 所在目录。
/**
-
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.”);
}
复制代码
new File(AgentPackagePath.getPath(), DEFAULT_CONFIG_FILE_NAME) 定位默认配置文件的位置, AgentPackagePath.getPath() 方法用来获取 skywalking-agent.jar 所在目录
/**
-
AgentPackagePath is a flag and finder to locate the SkyWalking agent.jar. It gets the absolute path of the agent jar.
-
The path is the required metadata for agent core looking up the plugins and toolkit activations. If the lookup
-
mechanism fails, the agent will exit directly.
*/
public class AgentPackagePath {
private static final ILog LOGGER = LogManager.getLogger(AgentPackagePath.class);
private static File AGENT_PACKAGE_PATH;
public static File getPath() throws AgentPackageNotFoundException {
if (AGENT_PACKAGE_PATH == null) {
// 返回 skywalking-agent.jar 文件所在的目录 E:\develop\source\sample\source\skywalking-java\skywalking-agent
AGENT_PACKAGE_PATH = findPath();
}
return AGENT_PACKAGE_PATH;
}
public static boolean isPathFound() {
return AGENT_PACKAGE_PATH != null;
}
private static File findPath() throws AgentPackageNotFoundException {
// 将 AgentPackagePath 全类名中的.替换成 /
// org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class
String classResourcePath = AgentPackagePath.class.getName().replaceAll(“.”, “/”) + “.class”;
// 使用 AppClassLoader 加载资源,通常情况下 AgentPackagePath 类是被 AppClassLoader 加载的。
URL resource = ClassLoader.getSystemClassLoader().getResource(classResourcePath);
if (resource != null) {
String urlString = resource.toString();
//jar:file:/E:/source/skywalking-java/skywalking-agent/skywalking-agent.jar!/org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class
LOGGER.debug(“The beacon class location is {}.”, urlString);
// 判断 url 中是否包含!,如果包含则说明 AgentPackagePath.class 是包含在jar中。
int insidePathIndex = urlString.indexOf(‘!’);
boolean isInJar = insidePathIndex > -1;
if (isInJar) {
// file:/E:/source/skywalking-java/skywalking-agent/skywalking-agent.jar
urlString = urlString.substring(urlString.indexOf(“file:”), insidePathIndex);
File agentJarFile = null;
try {
// E:\source\skywalking-java\skywalking-agent\skywalking-agent.jar
agentJarFile = new File(new URL(urlString).toURI());
} catch (MalformedURLException | URISyntaxException e) {
LOGGER.error(e, “Can not locate agent jar file by url:” + urlString);
}
if (agentJarFile.exists()) {
// 返回 skywalking-agent.jar 文件所在的目录
return agentJarFile.getParentFile();
}
} else {
int prefixLength = “file:”.length();
String classLocation = urlString.substring(
prefixLength, urlString.length() - classResourcePath.length());
return new File(classLocation);
}
}
LOGGER.error(“Can not locate agent jar file.”);
throw new AgentPackageNotFoundException(“Can not locate agent jar file.”);
}
}
复制代码
通过类加载器 AppClassLoader 加载 AgentPackagePath.class 资源,定位到 skywalking-agent.jar 所在的目录,保存到静态成员变量 AGENT_PACKAGE_PATH 中,下次获取直接读取静态变量。
配置优先级
Agent Options > System.Properties(-D) > System environment variables > Config file
System.getProperties() 和 System.getenv() 区别,请参考文章 www.cnblogs.com/clarke157/p…
-
System.getProperties() 获取 Java 虚拟机相关的系统属性(比如 java.version、 java.io.tmpdir 等),通过 java -D配置;
-
System.getenv() 获取系统环境变量(比如 JAVA_HOME、Path 等),通过操作系统配置。
将配置信息映射到 Config 类
在我们的日常开发中一般是直接从 Properties 读取需要的配置项,SkyWalking Java Agent 并没有这么做,而是定义一个配置类 Config,将配置项映射到 Config 类的静态属性中,其他地方需要配置项的时候,直接从类的静态属性获取就可以了,非常方便使用。
ConfigInitializer 就是负责将 Properties 中的 key/value 键值对映射到类(比如 Config 类)的静态属性,其中 key 对应类的静态属性,value 赋值给静态属性的值。
/**
- This is the core config in sniffer agent.
*/
public class Config {
public static class Agent {
/**
- Namespace isolates headers in cross process propagation. The HEADER name will be
HeaderName:Namespace
.
*/
public static String NAMESPACE = “”;
/**
-
Service name is showed in skywalking-ui. Suggestion: set a unique name for each service, service instance
-
nodes share the same code
*/
@Length(50)
public static String SERVICE_NAME = “”;
// 省略部分代码…
}
public static class Collector {
/**
- Collector skywalking trace receiver service addresses.
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
华为、OPPO等大厂,18年进入阿里一直到现在。**
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-gSAXwQLX-1710890635714)]
[外链图片转存中…(img-Elgv14eU-1710890635715)]
[外链图片转存中…(img-najwfJbR-1710890635716)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-JevGrx2s-1710890635716)]