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

[GitHub] wu-sheng closed pull request #1957: feat:Active System.env Config In Both Collector And agent.config.

wu-sheng closed pull request #1957: feat:Active System.env Config In Both Collector And agent.config.
URL: https://github.com/apache/incubator-skywalking/pull/1957
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/apm-commons/apm-util/pom.xml b/apm-commons/apm-util/pom.xml
index 370d22414a..e49e5c4f12 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 4ef02e95db..493d6b8e2b 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 60d6c4a175..41957f4de1 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 @@
  * 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 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 PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuf
      * @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 @@ private String getConfigValue(String key, final Properties properties) {
      * @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 @@ protected String parseStringValue(String value, PlaceholderResolver placeholderR
                     // 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 @@ private int findPlaceholderEndIndex(CharSequence buf, int startIndex) {
         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 4c27745e47..ce236b43d7 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 static String join(final char delimiter, final String... strings) {
         }
         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 6bf8c9686c..e91b0ecf1a 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 9754119238..a3a049e183 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 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 @@
 
         /**
          * 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 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 b18c0fe2a7..0c4b8ba725 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.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 static void initialize(String agentOptions) throws ConfigNotFoundExceptio
             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 static boolean isInitCompleted() {
     }
 
     /**
-     * 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 static boolean isInitCompleted() {
      *
      * @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 3c5183fec6..305466ef2c 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 {
@@ -64,6 +75,25 @@ public void testConfigOverriding() throws AgentPackageNotFoundException, ConfigN
         assertThat(Config.Logging.LEVEL, is(LogLevel.DEBUG));
     }
 
+    @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");
diff --git a/apm-sniffer/config/agent.config b/apm-sniffer/config/agent.config
index c4306c9418..37f2b42724 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 cd07e7a1dd..c43272ef52 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 5abbdcf61f..3835825533 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 87ca944fb6..84577cd316 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 1375c8098e..2d425c46b9 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 static boolean isNotEmpty(Object str) {
     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 81fb6d7c75..6c72092f60 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.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 5d93503d92..80e965902a 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.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;


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services