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/07 15:15:38 UTC

[GitHub] wu-sheng closed pull request #1887: Support for overriding config with agent options

wu-sheng closed pull request #1887: Support for overriding config with agent options
URL: https://github.com/apache/incubator-skywalking/pull/1887
 
 
   

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-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 d33d30471..325557140 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
@@ -24,7 +24,9 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
@@ -56,7 +58,7 @@
      * <p>
      * At the end, `agent.application_code` and `collector.servers` must be not blank.
      */
-    public static void initialize() throws ConfigNotFoundException, AgentPackageNotFoundException {
+    public static void initialize(String agentOptions) throws ConfigNotFoundException, AgentPackageNotFoundException {
         InputStreamReader configFileStream;
 
         try {
@@ -74,6 +76,17 @@ public static void initialize() throws ConfigNotFoundException, AgentPackageNotF
             logger.error(e, "Failed to read the system env.");
         }
 
+        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);
+            }
+        }
+
         if (StringUtil.isEmpty(Config.Agent.APPLICATION_CODE)) {
             throw new ExceptionInInitializerError("`agent.application_code` is missing.");
         }
@@ -84,6 +97,46 @@ public static void initialize() throws ConfigNotFoundException, AgentPackageNotF
         IS_INIT_COMPLETED = true;
     }
 
+    private static void overrideConfigByAgentOptions(String agentOptions) throws IllegalAccessException {
+        Properties properties = new Properties();
+        for (List<String> terms : parseAgentOptions(agentOptions)) {
+            if (terms.size() != 2) {
+                throw new IllegalArgumentException("[" + terms + "] is not a key-value pair.");
+            }
+            properties.put(terms.get(0), terms.get(1));
+        }
+        if (!properties.isEmpty()) {
+            ConfigInitializer.initialize(properties, Config.class);
+        }
+    }
+
+    private static List<List<String>> parseAgentOptions(String agentOptions) {
+        List<List<String>> options = new ArrayList<List<String>>();
+        List<String> terms = new ArrayList<String>();
+        boolean isInQuotes = false;
+        StringBuilder currentTerm = new StringBuilder();
+        for (char c : agentOptions.toCharArray()) {
+            if (c == '\'' || c == '"') {
+                isInQuotes = !isInQuotes;
+            } else if (c == '=' && !isInQuotes) {   // key-value pair uses '=' as separator
+                terms.add(currentTerm.toString());
+                currentTerm = new StringBuilder();
+            } else if (c == ',' && !isInQuotes) {   // multiple options use ',' as separator
+                terms.add(currentTerm.toString());
+                currentTerm = new StringBuilder();
+
+                options.add(terms);
+                terms = new ArrayList<String>();
+            } else {
+                currentTerm.append(c);
+            }
+        }
+        // add the last term and option without separator
+        terms.add(currentTerm.toString());
+        options.add(terms);
+        return options;
+    }
+
     public static boolean isInitCompleted() {
         return IS_INIT_COMPLETED;
     }
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 814c3cd3b..edd81c97b 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
@@ -21,11 +21,15 @@
 
 import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
 import org.apache.skywalking.apm.agent.core.logging.core.LogLevel;
-import org.junit.AfterClass;
+import org.junit.After;
 import org.junit.Test;
 
+import java.util.Iterator;
+import java.util.Map;
+
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.fail;
 
 public class SnifferConfigInitializerTest {
 
@@ -34,14 +38,67 @@ public void testLoadConfigFromJavaAgentDir() throws AgentPackageNotFoundExceptio
         System.setProperty("skywalking.agent.application_code", "testApp");
         System.setProperty("skywalking.collector.backend_service", "127.0.0.1:8090");
         System.setProperty("skywalking.logging.level", "info");
-        SnifferConfigInitializer.initialize();
+        SnifferConfigInitializer.initialize(null);
         assertThat(Config.Agent.APPLICATION_CODE, is("testApp"));
         assertThat(Config.Collector.BACKEND_SERVICE, is("127.0.0.1:8090"));
         assertThat(Config.Logging.LEVEL, is(LogLevel.INFO));
     }
 
-    @AfterClass
-    public static void clear() {
+    @Test
+    public void testLoadConfigFromAgentOptions() throws AgentPackageNotFoundException, ConfigNotFoundException {
+        String agentOptions = "agent.application_code=testApp,collector.backend_service=127.0.0.1:8090,logging.level=info";
+        SnifferConfigInitializer.initialize(agentOptions);
+        assertThat(Config.Agent.APPLICATION_CODE, is("testApp"));
+        assertThat(Config.Collector.BACKEND_SERVICE, is("127.0.0.1:8090"));
+        assertThat(Config.Logging.LEVEL, is(LogLevel.INFO));
+    }
+
+    @Test
+    public void testConfigOverriding() throws AgentPackageNotFoundException, ConfigNotFoundException {
+        System.setProperty("skywalking.agent.application_code", "testAppFromSystem");
+        System.setProperty("skywalking.collector.backend_service", "127.0.0.1:8090");
+        String agentOptions = "agent.application_code=testAppFromAgentOptions,logging.level=debug";
+        SnifferConfigInitializer.initialize(agentOptions);
+        assertThat(Config.Agent.APPLICATION_CODE, is("testAppFromAgentOptions"));
+        assertThat(Config.Collector.BACKEND_SERVICE, is("127.0.0.1:8090"));
+        assertThat(Config.Logging.LEVEL, is(LogLevel.DEBUG));
+    }
+
+    @Test
+    public void testAgentOptionsSeparator() throws AgentPackageNotFoundException, ConfigNotFoundException {
+        System.setProperty("skywalking.agent.application_code", "testApp");
+        System.setProperty("skywalking.collector.backend_service", "127.0.0.1:8090");
+        String agentOptions = "agent.ignore_suffix='.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg'";
+        SnifferConfigInitializer.initialize(agentOptions);
+        assertThat(Config.Agent.IGNORE_SUFFIX, is(".jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg"));
+    }
+
+    @Test
+    public void testAgentOptionsParser() throws AgentPackageNotFoundException, ConfigNotFoundException {
+        System.setProperty("skywalking.collector.backend_service", "127.0.0.1:8090");
+        String agentOptions = "agent.application_code=test=abc";
+        try {
+            SnifferConfigInitializer.initialize(agentOptions);
+            fail("test=abc without quotes is not a valid value");
+        } catch (ExceptionInInitializerError e) {
+            // ignore
+        }
+        agentOptions = "agent.application_code='test=abc'";
+        SnifferConfigInitializer.initialize(agentOptions);
+        assertThat(Config.Agent.APPLICATION_CODE, is("test=abc"));
+    }
+
+    @After
+    public void clear() {
+        Iterator<Map.Entry<Object, Object>> it = System.getProperties().entrySet().iterator();
+        while (it.hasNext()) {
+            Map.Entry<Object, Object> entry = it.next();
+            if (entry.getKey().toString().startsWith("skywalking.")) {
+                it.remove();
+            }
+        }
+
+        Config.Agent.APPLICATION_CODE = "";
         Config.Logging.LEVEL = LogLevel.DEBUG;
     }
 }
diff --git a/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java b/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java
index c6ca2ca20..fd3b4a0c4 100644
--- a/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java
+++ b/apm-sniffer/apm-agent/src/main/java/org/apache/skywalking/apm/agent/SkyWalkingAgent.java
@@ -61,7 +61,7 @@
     public static void premain(String agentArgs, Instrumentation instrumentation) throws PluginException {
         final PluginFinder pluginFinder;
         try {
-            SnifferConfigInitializer.initialize();
+            SnifferConfigInitializer.initialize(agentArgs);
 
             pluginFinder = new PluginFinder(new PluginBootstrap().loadPlugins());
 
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 ddfc0d935..5abbdcf61 100644
--- a/docs/en/setup/service-agent/java-agent/Setting-override.md
+++ b/docs/en/setup/service-agent/java-agent/Setting-override.md
@@ -1,22 +1,49 @@
 # Setting Override
-In default, SkyWalking provide `agent.config` for agent 
+In default, SkyWalking provide `agent.config` for agent.
 
-Setting override means end user can override the settings in these config file, through using system properties.
- 
+Setting override means end user can override the settings in these config file, through using system properties or agent options.
 
-Use `skywalking.` + key in config file as system properties key, to override the value.
 
-- Why need this prefix?
+## System properties
 
-  The agent system properites and env share with target application, this prefix can avoid variable conflict.
+Use `skywalking.` + key in config file as system properties key, to override the value.
 
-- Override priority
+- Why need this prefix?
 
-  System.Properties(-D) > Config file  
+  The agent system properties and env share with target application, this prefix can avoid variable conflict.
 
 - Example
 
   Override `agent.application_code` by this.
 ```
 -Dskywalking.agent.application_code=31200
-```
\ No newline at end of file
+```
+
+## Agent options
+
+Add the properties after the agent path in JVM arguments.
+
+```
+-javaagent:/path/to/skywalking-agent.jar=[option1]=[value1],[option2]=[value2]
+```
+
+- Example
+
+  Override `agent.application_code` and `logging.level` by this.
+
+```
+-javaagent:/path/to/skywalking-agent.jar=agent.application_code=31200,logging.level=debug
+```
+
+- Special characters
+
+  If a separator(`,` or `=`) in the option or value, it should be wrapped in quotes.
+
+```
+-javaagent:/path/to/skywalking-agent.jar=agent.ignore_suffix='.jpg,.jpeg'
+```
+
+
+## Override priority
+
+Agent Options >  System.Properties(-D) > Config file


 

----------------------------------------------------------------
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