You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2018/11/25 16:12:06 UTC

[incubator-skywalking] branch master updated: feat:Active System.env Config In Both Collector And agent.config. (#1957)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git


The following commit(s) were added to refs/heads/master by this push:
     new b790307  feat:Active System.env Config In Both Collector And agent.config. (#1957)
b790307 is described below

commit b79030765b0fe98e13fa4fa7bdc349d648fca6eb
Author: Jared.Tan <ji...@daocloud.io>
AuthorDate: Mon Nov 26 00:12:01 2018 +0800

    feat:Active System.env Config In Both Collector And agent.config. (#1957)
    
    * feat:Active System.env Config In Both Collector And agent.config.
    1、moving related codes into apm-util module.
    2、update Setting-override.md about how to use.
    
    * resolve docs.
    
    * typo
    
    * finish test case.
    
    * Update README.md
---
 apm-commons/apm-util/pom.xml                       |  1 -
 .../apm}/util/PlaceholderConfigurerSupport.java    |  2 +-
 .../apm}/util/PropertyPlaceholderHelper.java       | 34 ++++++++-----------
 .../org/apache/skywalking/apm/util/StringUtil.java | 12 +++++++
 apm-sniffer/apm-agent-core/pom.xml                 | 10 +++++-
 .../skywalking/apm/agent/core/conf/Config.java     | 12 ++++---
 .../agent/core/conf/SnifferConfigInitializer.java  | 17 ++++++++--
 .../core/conf/SnifferConfigInitializerTest.java    | 38 +++++++++++++++++++---
 apm-sniffer/config/agent.config                    | 18 +++++-----
 docs/en/setup/service-agent/java-agent/README.md   | 30 +++++++++++++++++
 .../service-agent/java-agent/Setting-override.md   | 22 ++++++++++++-
 oap-server/server-library/library-util/pom.xml     |  6 +++-
 .../oap/server/library/util/StringUtils.java       | 12 -------
 .../util/PropertyPlaceholderHelperTest.java        |  2 ++
 .../starter/config/ApplicationConfigLoader.java    |  4 +--
 15 files changed, 160 insertions(+), 60 deletions(-)

diff --git a/apm-commons/apm-util/pom.xml b/apm-commons/apm-util/pom.xml
index 370d224..e49e5c4 100644
--- a/apm-commons/apm-util/pom.xml
+++ b/apm-commons/apm-util/pom.xml
@@ -33,5 +33,4 @@
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     </properties>
-
 </project>
diff --git a/oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/PlaceholderConfigurerSupport.java b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/PlaceholderConfigurerSupport.java
similarity index 95%
rename from oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/PlaceholderConfigurerSupport.java
rename to apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/PlaceholderConfigurerSupport.java
index 4ef02e9..493d6b8 100644
--- a/oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/PlaceholderConfigurerSupport.java
+++ b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/PlaceholderConfigurerSupport.java
@@ -16,7 +16,7 @@
  *
  */
 
-package org.apache.skywalking.oap.server.library.util;
+package org.apache.skywalking.apm.util;
 
 /**
  * @author jian.tan
diff --git a/oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/PropertyPlaceholderHelper.java b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/PropertyPlaceholderHelper.java
similarity index 87%
rename from oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/PropertyPlaceholderHelper.java
rename to apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/PropertyPlaceholderHelper.java
index 60d6c4a..41957f4 100644
--- a/oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/PropertyPlaceholderHelper.java
+++ b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/PropertyPlaceholderHelper.java
@@ -16,17 +16,13 @@
  *
  */
 
-package org.apache.skywalking.oap.server.library.util;
+package org.apache.skywalking.apm.util;
 
-import com.google.common.base.Strings;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
-import org.apache.logging.log4j.core.util.Assert;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Utility class for working with Strings that have placeholder values in them. A placeholder takes the form {@code
@@ -34,9 +30,7 @@ import org.slf4j.LoggerFactory;
  * Values for substitution can be supplied using a {@link Properties} instance or using a {@link PlaceholderResolver}.
  */
 public class PropertyPlaceholderHelper {
-    private static final Logger logger = LoggerFactory.getLogger(PropertyPlaceholderHelper.class);
-
-    private static final Map<String, String> WELL_KNOWN_SIMPLE_PREFIXES = new HashMap<>(4);
+    private static final Map<String, String> WELL_KNOWN_SIMPLE_PREFIXES = new HashMap<String, String>(4);
 
     static {
         WELL_KNOWN_SIMPLE_PREFIXES.put("}", "{");
@@ -66,8 +60,9 @@ public class PropertyPlaceholderHelper {
      */
     public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,
         String valueSeparator, boolean ignoreUnresolvablePlaceholders) {
-        Assert.requireNonEmpty(placeholderPrefix, "'placeholderPrefix' must not be null");
-        Assert.requireNonEmpty(placeholderSuffix, "'placeholderSuffix' must not be null");
+        if (StringUtil.isEmpty(placeholderPrefix) || StringUtil.isEmpty(placeholderSuffix)) {
+            throw new UnsupportedOperationException("'placeholderPrefix or placeholderSuffix' must not be null");
+        }
         this.placeholderPrefix = placeholderPrefix;
         this.placeholderSuffix = placeholderSuffix;
         String simplePrefixForSuffix = WELL_KNOWN_SIMPLE_PREFIXES.get(this.placeholderSuffix);
@@ -89,16 +84,19 @@ public class PropertyPlaceholderHelper {
      * @return the supplied value with placeholders replaced inline
      */
     public String replacePlaceholders(String value, final Properties properties) {
-        Assert.requireNonEmpty(properties, "'properties' must not be null");
-        return replacePlaceholders(value, placeholderName -> this.getConfigValue(placeholderName, properties));
+        return replacePlaceholders(value, new PlaceholderResolver() {
+            @Override public String resolvePlaceholder(String placeholderName) {
+                return PropertyPlaceholderHelper.this.getConfigValue(placeholderName, properties);
+            }
+        });
     }
 
     private String getConfigValue(String key, final Properties properties) {
         String value = System.getProperty(key);
-        if (Strings.isNullOrEmpty(value)) {
+        if (StringUtil.isEmpty(value)) {
             value = System.getenv(key);
         }
-        if (Strings.isNullOrEmpty(value)) {
+        if (StringUtil.isEmpty(value)) {
             value = properties.getProperty(key);
         }
         return value;
@@ -113,7 +111,6 @@ public class PropertyPlaceholderHelper {
      * @return the supplied value with placeholders replaced inline
      */
     public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
-        Assert.requireNonEmpty(value, "'value' must not be null");
         return parseStringValue(value, placeholderResolver, new HashSet<String>());
     }
 
@@ -152,9 +149,6 @@ public class PropertyPlaceholderHelper {
                     // previously resolved placeholder value.
                     propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
                     result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
-                    if (logger.isTraceEnabled()) {
-                        logger.trace("Resolved placeholder '" + placeholder + "'");
-                    }
                     startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
                 } else if (this.ignoreUnresolvablePlaceholders) {
                     // Proceed with unprocessed value.
@@ -175,14 +169,14 @@ public class PropertyPlaceholderHelper {
         int index = startIndex + this.placeholderPrefix.length();
         int withinNestedPlaceholder = 0;
         while (index < buf.length()) {
-            if (StringUtils.substringMatch(buf, index, this.placeholderSuffix)) {
+            if (StringUtil.substringMatch(buf, index, this.placeholderSuffix)) {
                 if (withinNestedPlaceholder > 0) {
                     withinNestedPlaceholder--;
                     index = index + this.placeholderSuffix.length();
                 } else {
                     return index;
                 }
-            } else if (StringUtils.substringMatch(buf, index, this.simplePrefix)) {
+            } else if (StringUtil.substringMatch(buf, index, this.simplePrefix)) {
                 withinNestedPlaceholder++;
                 index = index + this.simplePrefix.length();
             } else {
diff --git a/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/StringUtil.java b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/StringUtil.java
index 4c27745..ce236b4 100644
--- a/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/StringUtil.java
+++ b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/StringUtil.java
@@ -50,4 +50,16 @@ public final class StringUtil {
         }
         return sb.toString();
     }
+
+    public static boolean substringMatch(CharSequence str, int index, CharSequence substring) {
+        if (index + substring.length() > str.length()) {
+            return false;
+        }
+        for (int i = 0; i < substring.length(); i++) {
+            if (str.charAt(index + i) != substring.charAt(i)) {
+                return false;
+            }
+        }
+        return true;
+    }
 }
diff --git a/apm-sniffer/apm-agent-core/pom.xml b/apm-sniffer/apm-agent-core/pom.xml
index 6bf8c96..e91b0ec 100644
--- a/apm-sniffer/apm-agent-core/pom.xml
+++ b/apm-sniffer/apm-agent-core/pom.xml
@@ -16,7 +16,8 @@
   ~
   -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
@@ -58,6 +59,7 @@
         <shade.org.apache.commons.source>org.apache.commons</shade.org.apache.commons.source>
         <shade.org.apache.commons.target>${shade.package}.${shade.org.apache.http.source}
         </shade.org.apache.commons.target>
+        <ststem-rules.version>1.18.0</ststem-rules.version>
     </properties>
 
     <dependencies>
@@ -142,6 +144,12 @@
             <artifactId>apm-datacarrier</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>com.github.stefanbirkner</groupId>
+            <artifactId>system-rules</artifactId>
+            <version>${ststem-rules.version}</version>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
     <dependencyManagement>
         <dependencies>
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
index 9754119..a3a049e 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
@@ -37,8 +37,8 @@ public class Config {
         public static String NAMESPACE = "";
 
         /**
-         * Application code is showed in sky-walking-ui. Suggestion: set an unique name for each application, one
-         * application's nodes share the same code.
+         * Application code is showed in skywalking-ui. Suggestion: set a unique name for each service,
+         * service instance nodes share the same code
          */
         public static String SERVICE_NAME = "";
 
@@ -50,7 +50,7 @@ public class Config {
 
         /**
          * Negative or zero means off, by default. {@link #SAMPLE_N_PER_3_SECS} means sampling N {@link TraceSegment} in
-         * 10 seconds tops.
+         * 3 seconds tops.
          */
         public static int SAMPLE_N_PER_3_SECS = -1;
 
@@ -147,13 +147,15 @@ public class Config {
     public static class Plugin {
         public static class MongoDB {
             /**
-             * If true, trace all the parameters, default is false. Only trace the operation, not include parameters.
+             * If true, trace all the parameters in MongoDB access, default is false. Only trace the operation, not include parameters.
              */
             public static boolean TRACE_PARAM = false;
         }
 
         public static class Elasticsearch {
-
+            /**
+             * If true, trace all the DSL(Domain Specific Language) in ElasticSearch access, default is false.
+             */
             public static boolean TRACE_DSL = false;
         }
     }
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/SnifferConfigInitializer.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/SnifferConfigInitializer.java
index b18c0fe..0c4b8ba 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/SnifferConfigInitializer.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/SnifferConfigInitializer.java
@@ -34,6 +34,8 @@ import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath;
 import org.apache.skywalking.apm.agent.core.logging.api.ILog;
 import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
 import org.apache.skywalking.apm.util.ConfigInitializer;
+import org.apache.skywalking.apm.util.PlaceholderConfigurerSupport;
+import org.apache.skywalking.apm.util.PropertyPlaceholderHelper;
 import org.apache.skywalking.apm.util.StringUtil;
 
 /**
@@ -65,13 +67,22 @@ public class SnifferConfigInitializer {
             configFileStream = loadConfig();
             Properties properties = new Properties();
             properties.load(configFileStream);
+            PropertyPlaceholderHelper helper =
+                new PropertyPlaceholderHelper(PlaceholderConfigurerSupport.DEFAULT_PLACEHOLDER_PREFIX,
+                    PlaceholderConfigurerSupport.DEFAULT_PLACEHOLDER_SUFFIX,
+                    PlaceholderConfigurerSupport.DEFAULT_VALUE_SEPARATOR, true);
+            for (String key : properties.stringPropertyNames()) {
+                String value = (String)properties.get(key);
+                //replace the key's value. properties.replace(key,value) in jdk8+
+                properties.put(key, helper.replacePlaceholders(value, properties));
+            }
             ConfigInitializer.initialize(properties, Config.class);
         } catch (Exception e) {
             logger.error(e, "Failed to read the config file, skywalking is going to run in default config.");
         }
 
         try {
-            overrideConfigBySystemEnv();
+            overrideConfigBySystemProp();
         } catch (Exception e) {
             logger.error(e, "Failed to read the system env.");
         }
@@ -142,7 +153,7 @@ public class SnifferConfigInitializer {
     }
 
     /**
-     * Override the config by system env. The env key must start with `skywalking`, the reuslt should be as same as in
+     * Override the config by system properties. The env key must start with `skywalking`, the reuslt should be as same as in
      * `agent.config`
      * <p>
      * such as:
@@ -150,7 +161,7 @@ public class SnifferConfigInitializer {
      *
      * @return the config file {@link InputStream}, or null if not needEnhance.
      */
-    private static void overrideConfigBySystemEnv() throws IllegalAccessException {
+    private static void overrideConfigBySystemProp() throws IllegalAccessException {
         Properties properties = new Properties();
         Properties systemProperties = System.getProperties();
         Iterator<Map.Entry<Object, Object>> entryIterator = systemProperties.entrySet().iterator();
diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/conf/SnifferConfigInitializerTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/conf/SnifferConfigInitializerTest.java
index 3c5183f..305466e 100644
--- a/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/conf/SnifferConfigInitializerTest.java
+++ b/apm-sniffer/apm-agent-core/src/test/java/org/apache/skywalking/apm/agent/core/conf/SnifferConfigInitializerTest.java
@@ -16,22 +16,33 @@
  *
  */
 
-
 package org.apache.skywalking.apm.agent.core.conf;
 
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Properties;
 import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
 import org.apache.skywalking.apm.agent.core.logging.core.LogLevel;
+import org.apache.skywalking.apm.util.ConfigInitializer;
+import org.apache.skywalking.apm.util.PlaceholderConfigurerSupport;
+import org.apache.skywalking.apm.util.PropertyPlaceholderHelper;
 import org.junit.After;
+import org.junit.Rule;
 import org.junit.Test;
-
-import java.util.Iterator;
-import java.util.Map;
+import org.junit.contrib.java.lang.system.EnvironmentVariables;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.Assert.fail;
 
 public class SnifferConfigInitializerTest {
+    /**
+     * The EnvironmentVariables rule allows you to set environment variables for your test. All changes to environment
+     * variables are reverted after the test.
+     */
+    @Rule
+    public final EnvironmentVariables environmentVariables = new EnvironmentVariables()
+        .set("AGENT_SERVICE_NAME", "testAppFromSystemEnv").set("AGENT_COLLECTOR_SERVER", "localhost:11111");
 
     @Test
     public void testLoadConfigFromJavaAgentDir() throws AgentPackageNotFoundException, ConfigNotFoundException {
@@ -65,6 +76,25 @@ public class SnifferConfigInitializerTest {
     }
 
     @Test
+    public void testConfigOverridingFromSystemEnv() throws IllegalAccessException {
+        Properties properties = new Properties();
+        properties.put("agent.service_name", "${AGENT_SERVICE_NAME:testAppFromSystem}");
+        properties.put("collector.backend_service", "${AGENT_COLLECTOR_SERVER:127.0.0.1:8090}");
+        properties.put("logging.level", "INFO");
+
+        PropertyPlaceholderHelper placeholderHelper =
+            new PropertyPlaceholderHelper(PlaceholderConfigurerSupport.DEFAULT_PLACEHOLDER_PREFIX,
+                PlaceholderConfigurerSupport.DEFAULT_PLACEHOLDER_SUFFIX,
+                PlaceholderConfigurerSupport.DEFAULT_VALUE_SEPARATOR, true);
+        properties.put("agent.service_name", placeholderHelper.replacePlaceholders((String)properties.get("agent.service_name"), properties));
+        properties.put("collector.backend_service", placeholderHelper.replacePlaceholders((String)properties.get("collector.backend_service"), properties));
+        ConfigInitializer.initialize(properties, Config.class);
+        assertThat(Config.Agent.SERVICE_NAME, is("testAppFromSystemEnv"));
+        assertThat(Config.Collector.BACKEND_SERVICE, is("localhost:11111"));
+        assertThat(Config.Logging.LEVEL, is(LogLevel.INFO));
+    }
+
+    @Test
     public void testAgentOptionsSeparator() throws AgentPackageNotFoundException, ConfigNotFoundException {
         System.setProperty("skywalking.agent.service_name", "testApp");
         System.setProperty("skywalking.collector.backend_service", "127.0.0.1:8090");
diff --git a/apm-sniffer/config/agent.config b/apm-sniffer/config/agent.config
index c4306c9..37f2b42 100644
--- a/apm-sniffer/config/agent.config
+++ b/apm-sniffer/config/agent.config
@@ -15,31 +15,31 @@
 # limitations under the License.
 
 # The agent namespace
-# agent.namespace=default-namespace
+# agent.namespace=${SW_AGENT_NAMESPACE:default-namespace}
 
 # The service name in UI
-agent.service_name=Your_ApplicationName
+agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
 
 # The number of sampled traces per 3 seconds
 # Negative number means sample traces as many as possible, most likely 100%
-# agent.sample_n_per_3_secs=-1
+# agent.sample_n_per_3_secs=${SW_AGENT_SAMPLE:-1}
 
 # Authentication active is based on backend setting, see application.yml for more details.
-# agent.authentication = xxxx
+# agent.authentication = ${SW_AGENT_AUTHENTICATION:xxxx}
 
 # The max amount of spans in a single segment.
 # Through this config item, skywalking keep your application memory cost estimated.
-# agent.span_limit_per_segment=300
+# agent.span_limit_per_segment=${SW_AGENT_SPAN_LIMIT:300}
 
 # Ignore the segments if their operation names start with these suffix.
-# agent.ignore_suffix=.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg
+# agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg}
 
 # If true, skywalking agent will save all instrumented classes files in `/debugging` folder.
 # Skywalking team may ask for these files in order to resolve compatible problem.
-# agent.is_open_debugging_class = true
+# agent.is_open_debugging_class = ${SW_AGENT_OPEN_DEBUG:true}
 
 # Backend service addresses.
-collector.backend_service=127.0.0.1:11800
+collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:127.0.0.1:11800}
 
 # Logging level
-logging.level=DEBUG
+logging.level=${SW_LOGGING_LEVEL:DEBUG}
diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md
index cd07e7a..c43272e 100644
--- a/docs/en/setup/service-agent/java-agent/README.md
+++ b/docs/en/setup/service-agent/java-agent/README.md
@@ -45,6 +45,36 @@ Add `-javaagent` argument to command line in which you start your app. eg:
  ```shell
  java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar -jar yourApp.jar
  ```
+ 
+## Table of Agent Configuration Properties
+This is the properties list supported in `agent/config/agent.config`.
+
+property key | Description | Default |
+----------- | ---------- | --------- | 
+`agent.namespace` | Namespace isolates headers in cross process propagation. The HEADER name will be `HeaderName:Namespace`. | Not set | 
+`agent.service_name` | Application(5.x)/Service(6.x) code is showed in sky-walking-ui. Suggestion: set a unique name for each service, service instance nodes share the same code | `Your_ApplicationName` |
+`agent.sample_n_per_3_secs`|Negative or zero means off, by default.SAMPLE_N_PER_3_SECS means sampling N TraceSegment in 3 seconds tops.|Not set|
+`agent.authentication`|Authentication active is based on backend setting, see application.yml for more details.For most scenarios, this needs backend extensions, only basic match auth provided in default implementation.|Not set|
+`agent.span_limit_per_segment`|The max number of spans in a single segment. Through this config item, skywalking keep your application memory cost estimated.|Not set |
+`agent.ignore_suffix`|If the operation name of the first span is included in this set, this segment should be ignored.|Not set|
+`agent.is_open_debugging_class`|If true, skywalking agent will save all instrumented classes files in `/debugging` folder.Skywalking team may ask for these files in order to resolve compatible problem.|Not set|
+`agent.active_v2_header`|Active V2 header in default.|`true`|
+`agent.active_v1_header `|Deactive V1 header in default.|`false`|
+`collector.grpc_channel_check_interval`|grpc channel status check interval.|`30`|
+`collector.app_and_service_register_check_interval`|application and service registry check interval.|`3`|
+`collector.backend_service`|Collector skywalking trace receiver service addresses.|`127.0.0.1:11800`|
+`logging.level`|The log level. Default is debug.|`DEBUG`|
+`logging.file_name`|Log file name.|`skywalking-api.log`|
+`logging.dir`|Log files directory. Default is blank string, means, use "system.out" to output logs.|`""`|
+`logging.max_file_size`|The max size of log file. If the size is bigger than this, archive the current file, and write into a new file.|`300 * 1024 * 1024`|
+`jvm.buffer_size`|The buffer size of collected JVM info.|`60 * 10`|
+`buffer.channel_size`|The buffer channel size.|`5`|
+`buffer.buffer_size`|The buffer size.|`300`|
+`dictionary.service_code_buffer_size`|The buffer size of application codes and peer|`10 * 10000`|
+`dictionary.endpoint_name_buffer_size`|The buffer size of endpoint names and peer|`1000 * 10000`|
+`plugin.mongodb.trace_param`|If true, trace all the parameters in MongoDB access, default is false. Only trace the operation, not include parameters.|`false`|
+`plugin.elasticsearch.trace_dsl`|If true, trace all the DSL(Domain Specific Language) in ElasticSearch access, default is false.|`false`|
+ 
 ## Supported middlewares, frameworks and libraries
 See [supported list](Supported-list.md).
 
diff --git a/docs/en/setup/service-agent/java-agent/Setting-override.md b/docs/en/setup/service-agent/java-agent/Setting-override.md
index 5abbdcf..3835825 100644
--- a/docs/en/setup/service-agent/java-agent/Setting-override.md
+++ b/docs/en/setup/service-agent/java-agent/Setting-override.md
@@ -43,7 +43,27 @@ Add the properties after the agent path in JVM arguments.
 -javaagent:/path/to/skywalking-agent.jar=agent.ignore_suffix='.jpg,.jpeg'
 ```
 
+## System environment variables
+- Example
+
+  Override `agent.application_code` and `logging.level` by this.
+
+```
+# The service name in UI
+agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
+
+# Logging level
+logging.level=${SW_LOGGING_LEVEL:INFO}
+```
+
+If the `SW_AGENT_NAME ` environment variable exists in your operating system and its value is `skywalking-agent-demo`, 
+then the value of `agent.service_name` here will be overwritten to `skywalking-agent-demo`, otherwise, it will be set to `Your_ApplicationName`.
+
+By the way, Placeholder nesting is also supported, like `${SW_AGENT_NAME:${ANOTHER_AGENT_NAME:Your_ApplicationName}}`.
+In this case, if the `SW_AGENT_NAME ` environment variable not exists, but the ```ANOTHER_AGENT_NAME``` 
+environment variable exists and its value is `skywalking-agent-demo`, then the value of `agent.service_name` here will be overwritten to `skywalking-agent-demo`,otherwise, it will be set to `Your_ApplicationName`.
+
 
 ## Override priority
 
-Agent Options >  System.Properties(-D) > Config file
+Agent Options > System.Properties(-D) > System environment variables > Config file
diff --git a/oap-server/server-library/library-util/pom.xml b/oap-server/server-library/library-util/pom.xml
index 87ca944..84577cd 100644
--- a/oap-server/server-library/library-util/pom.xml
+++ b/oap-server/server-library/library-util/pom.xml
@@ -29,6 +29,10 @@
     <artifactId>library-util</artifactId>
     <packaging>jar</packaging>
 
+    <properties>
+        <ststem-rules.version>1.18.0</ststem-rules.version>
+    </properties>
+
     <dependencies>
         <dependency>
             <groupId>joda-time</groupId>
@@ -43,7 +47,7 @@
         <dependency>
             <groupId>com.github.stefanbirkner</groupId>
             <artifactId>system-rules</artifactId>
-            <version>1.18.0</version>
+            <version>${ststem-rules.version}</version>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/StringUtils.java b/oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/StringUtils.java
index 1375c80..2d425c4 100644
--- a/oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/StringUtils.java
+++ b/oap-server/server-library/library-util/src/main/java/org/apache/skywalking/oap/server/library/util/StringUtils.java
@@ -36,16 +36,4 @@ public class StringUtils {
     public static String getOrDefault(String value, String defaultValue) {
         return value == null ? defaultValue : value;
     }
-
-    public static boolean substringMatch(CharSequence str, int index, CharSequence substring) {
-        if (index + substring.length() > str.length()) {
-            return false;
-        }
-        for (int i = 0; i < substring.length(); i++) {
-            if (str.charAt(index + i) != substring.charAt(i)) {
-                return false;
-            }
-        }
-        return true;
-    }
 }
diff --git a/oap-server/server-library/library-util/src/test/java/org/apache/skywalking/oap/server/library/util/PropertyPlaceholderHelperTest.java b/oap-server/server-library/library-util/src/test/java/org/apache/skywalking/oap/server/library/util/PropertyPlaceholderHelperTest.java
index 81fb6d7..6c72092 100644
--- a/oap-server/server-library/library-util/src/test/java/org/apache/skywalking/oap/server/library/util/PropertyPlaceholderHelperTest.java
+++ b/oap-server/server-library/library-util/src/test/java/org/apache/skywalking/oap/server/library/util/PropertyPlaceholderHelperTest.java
@@ -22,6 +22,8 @@ import java.io.FileNotFoundException;
 import java.io.Reader;
 import java.util.Map;
 import java.util.Properties;
+import org.apache.skywalking.apm.util.PlaceholderConfigurerSupport;
+import org.apache.skywalking.apm.util.PropertyPlaceholderHelper;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
diff --git a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ApplicationConfigLoader.java b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ApplicationConfigLoader.java
index 5d93503..80e9659 100644
--- a/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ApplicationConfigLoader.java
+++ b/oap-server/server-starter/src/main/java/org/apache/skywalking/oap/server/starter/config/ApplicationConfigLoader.java
@@ -24,8 +24,8 @@ import java.util.Map;
 import java.util.Properties;
 import org.apache.skywalking.oap.server.library.module.ApplicationConfiguration;
 import org.apache.skywalking.oap.server.library.util.CollectionUtils;
-import org.apache.skywalking.oap.server.library.util.PlaceholderConfigurerSupport;
-import org.apache.skywalking.oap.server.library.util.PropertyPlaceholderHelper;
+import org.apache.skywalking.apm.util.PlaceholderConfigurerSupport;
+import org.apache.skywalking.apm.util.PropertyPlaceholderHelper;
 import org.apache.skywalking.oap.server.library.util.ResourceUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;