You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by ta...@apache.org on 2021/11/07 10:53:22 UTC

[skywalking-java] branch main updated: Support set instance properties in json format (#67)

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

tanjian pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-java.git


The following commit(s) were added to refs/heads/main by this push:
     new b169ef3  Support set instance properties in json format (#67)
b169ef3 is described below

commit b169ef3cdd377105050fbb9cada71305231ac47a
Author: Jared Tan <ji...@daocloud.io>
AuthorDate: Sun Nov 7 18:51:34 2021 +0800

    Support set instance properties in json format (#67)
    
    * set instance properties in json format: agent.instance_properties_json
    
    * add docs.
    
    * Update docs/en/setup/service-agent/java-agent/configurations.md
    
    * polish and add e2e.
    
    * update
    
    * Update test/e2e/case/expected/service-instance.yml
    
    Co-authored-by: kezhenxu94 <ke...@apache.org>
    
    * Update apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InstanceJsonPropertiesUtil.java
    
    Co-authored-by: kezhenxu94 <ke...@apache.org>
    
    * update
    
    * update SW_INSTANCE_PROPERTIES_JSON
    
    Co-authored-by: 吴晟 Wu Sheng <wu...@foxmail.com>
    Co-authored-by: kezhenxu94 <ke...@apache.org>
---
 CHANGES.md                                         |  1 +
 .../skywalking/apm/agent/core/conf/Config.java     | 12 ++++-
 .../agent/core/remote/ServiceManagementClient.java | 17 +++-----
 .../core/util/InstanceJsonPropertiesUtil.java      | 51 ++++++++++++++++++++++
 apm-sniffer/config/agent.config                    |  2 +
 .../kafka/KafkaServiceManagementServiceClient.java | 10 +----
 .../service-agent/java-agent/configurations.md     |  3 +-
 test/e2e/base/base-compose.yml                     |  2 +
 test/e2e/case/expected/service-instance.yml        |  2 +
 9 files changed, 79 insertions(+), 21 deletions(-)

diff --git a/CHANGES.md b/CHANGES.md
index 2054625..9152043 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,6 +8,7 @@ Release Notes.
 * Support `Transaction` and fix duplicated methods enhancements for `jedis-2.x` plugin.
 * Add ConsumerWrapper/FunctionWrapper to support CompletableFuture.x.thenAcceptAsync/thenApplyAsync.
 * Build CLI from Docker instead of source codes, add alpine based Docker image.
+* Support set instance properties in json format.
 
 #### Documentation
 
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 4195d19..46e109b 100755
--- 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
@@ -104,10 +104,19 @@ public class Config {
 
         /**
          * service instance properties e.g. agent.instance_properties[org]=apache
+         * Notice it will be overridden by `agent.instance_properties_json `, if the key duplication.
+         * For example: <code>e.g. agent.instance_properties_json = {"org": "apache-skywalking"}</code>
          */
+        @Deprecated
         public static Map<String, String> INSTANCE_PROPERTIES = new HashMap<>();
 
         /**
+         * service instance properties in json format.
+         * e.g. agent.instance_properties_json = {"org": "apache-skywalking"}
+         */
+        public static String INSTANCE_PROPERTIES_JSON = "";
+
+        /**
          * How depth the agent goes, when log cause exceptions.
          */
         public static int CAUSE_EXCEPTION_DEPTH = 5;
@@ -169,7 +178,8 @@ public class Config {
          */
         public static long HEARTBEAT_PERIOD = 30;
         /**
-         * The agent sends the instance properties to the backend every `collector.heartbeat_period * collector.properties_report_period_factor` seconds
+         * The agent sends the instance properties to the backend every `collector.heartbeat_period *
+         * collector.properties_report_period_factor` seconds
          */
         public static int PROPERTIES_REPORT_PERIOD_FACTOR = 10;
         /**
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/ServiceManagementClient.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/ServiceManagementClient.java
index 707b7e6..f129955 100755
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/ServiceManagementClient.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/ServiceManagementClient.java
@@ -19,7 +19,6 @@
 package org.apache.skywalking.apm.agent.core.remote;
 
 import io.grpc.Channel;
-import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledFuture;
@@ -35,6 +34,7 @@ import org.apache.skywalking.apm.agent.core.jvm.LoadedLibraryCollector;
 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.agent.core.os.OSUtil;
+import org.apache.skywalking.apm.agent.core.util.InstanceJsonPropertiesUtil;
 import org.apache.skywalking.apm.network.common.v3.Commands;
 import org.apache.skywalking.apm.network.common.v3.KeyStringValuePair;
 import org.apache.skywalking.apm.network.management.v3.InstancePingPkg;
@@ -69,14 +69,7 @@ public class ServiceManagementClient implements BootService, Runnable, GRPCChann
     public void prepare() {
         ServiceManager.INSTANCE.findService(GRPCChannelManager.class).addChannelListener(this);
 
-        SERVICE_INSTANCE_PROPERTIES = new ArrayList<>();
-
-        for (String key : Config.Agent.INSTANCE_PROPERTIES.keySet()) {
-            SERVICE_INSTANCE_PROPERTIES.add(KeyStringValuePair.newBuilder()
-                                                              .setKey(key)
-                                                              .setValue(Config.Agent.INSTANCE_PROPERTIES.get(key))
-                                                              .build());
-        }
+        SERVICE_INSTANCE_PROPERTIES = InstanceJsonPropertiesUtil.parseProperties();
     }
 
     @Override
@@ -108,7 +101,8 @@ public class ServiceManagementClient implements BootService, Runnable, GRPCChann
         if (GRPCChannelStatus.CONNECTED.equals(status)) {
             try {
                 if (managementServiceBlockingStub != null) {
-                    if (Math.abs(sendPropertiesCounter.getAndAdd(1)) % Config.Collector.PROPERTIES_REPORT_PERIOD_FACTOR == 0) {
+                    if (Math.abs(
+                        sendPropertiesCounter.getAndAdd(1)) % Config.Collector.PROPERTIES_REPORT_PERIOD_FACTOR == 0) {
 
                         managementServiceBlockingStub
                             .withDeadlineAfter(GRPC_UPSTREAM_TIMEOUT, TimeUnit.SECONDS)
@@ -118,7 +112,8 @@ public class ServiceManagementClient implements BootService, Runnable, GRPCChann
                                                                         .addAllProperties(OSUtil.buildOSInfo(
                                                                             Config.OsInfo.IPV4_LIST_SIZE))
                                                                         .addAllProperties(SERVICE_INSTANCE_PROPERTIES)
-                                                                        .addAllProperties(LoadedLibraryCollector.buildJVMInfo())
+                                                                        .addAllProperties(
+                                                                            LoadedLibraryCollector.buildJVMInfo())
                                                                         .build());
                     } else {
                         final Commands commands = managementServiceBlockingStub.withDeadlineAfter(
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InstanceJsonPropertiesUtil.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InstanceJsonPropertiesUtil.java
new file mode 100644
index 0000000..7862a53
--- /dev/null
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/util/InstanceJsonPropertiesUtil.java
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.agent.core.util;
+
+import com.google.gson.Gson;
+import com.google.gson.reflect.TypeToken;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.apache.skywalking.apm.agent.core.conf.Config;
+import org.apache.skywalking.apm.network.common.v3.KeyStringValuePair;
+import org.apache.skywalking.apm.util.StringUtil;
+
+public class InstanceJsonPropertiesUtil {
+    private static final Gson GSON = new Gson();
+
+    public static List<KeyStringValuePair> parseProperties() {
+        List<KeyStringValuePair> properties = new ArrayList<>();
+
+        if (StringUtil.isNotEmpty(Config.Agent.INSTANCE_PROPERTIES_JSON)) {
+            Config.Agent.INSTANCE_PROPERTIES.putAll(
+                GSON.fromJson(
+                    Config.Agent.INSTANCE_PROPERTIES_JSON,
+                    new TypeToken<Map<String, Object>>() {
+                    }.getType()
+                ));
+        }
+
+        Config.Agent.INSTANCE_PROPERTIES.forEach((key, val) -> properties.add(KeyStringValuePair.newBuilder()
+                                                                                                .setKey(key)
+                                                                                                .setValue(val)
+                                                                                                .build()));
+        return properties;
+    }
+}
diff --git a/apm-sniffer/config/agent.config b/apm-sniffer/config/agent.config
index d626014..d5fa9b4 100755
--- a/apm-sniffer/config/agent.config
+++ b/apm-sniffer/config/agent.config
@@ -54,6 +54,8 @@ agent.class_cache_mode=${SW_AGENT_CLASS_CACHE_MODE:MEMORY}
 # generate an 32-bit uuid. BY Default, SkyWalking uses UUID@hostname as the instance name. Max length is 50(UTF-8 char)
 agent.instance_name=${SW_AGENT_INSTANCE_NAME:}
 
+agent.instance_properties_json=${SW_INSTANCE_PROPERTIES_JSON:}
+
 # How depth the agent goes, when log all cause exceptions.
 agent.cause_exception_depth=${SW_AGENT_CAUSE_EXCEPTION_DEPTH:5}
 
diff --git a/apm-sniffer/optional-reporter-plugins/kafka-reporter-plugin/src/main/java/org/apache/skywalking/apm/agent/core/kafka/KafkaServiceManagementServiceClient.java b/apm-sniffer/optional-reporter-plugins/kafka-reporter-plugin/src/main/java/org/apache/skywalking/apm/agent/core/kafka/KafkaServiceManagementServiceClient.java
index c8eb5b6..bc0bb2e 100644
--- a/apm-sniffer/optional-reporter-plugins/kafka-reporter-plugin/src/main/java/org/apache/skywalking/apm/agent/core/kafka/KafkaServiceManagementServiceClient.java
+++ b/apm-sniffer/optional-reporter-plugins/kafka-reporter-plugin/src/main/java/org/apache/skywalking/apm/agent/core/kafka/KafkaServiceManagementServiceClient.java
@@ -18,7 +18,6 @@
 
 package org.apache.skywalking.apm.agent.core.kafka;
 
-import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledFuture;
@@ -37,6 +36,7 @@ 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.agent.core.os.OSUtil;
 import org.apache.skywalking.apm.agent.core.remote.ServiceManagementClient;
+import org.apache.skywalking.apm.agent.core.util.InstanceJsonPropertiesUtil;
 import org.apache.skywalking.apm.network.common.v3.KeyStringValuePair;
 import org.apache.skywalking.apm.network.management.v3.InstancePingPkg;
 import org.apache.skywalking.apm.network.management.v3.InstanceProperties;
@@ -65,13 +65,7 @@ public class KafkaServiceManagementServiceClient implements BootService, Runnabl
         producerManager.addListener(this);
         topic = producerManager.formatTopicNameThenRegister(KafkaReporterPluginConfig.Plugin.Kafka.TOPIC_MANAGEMENT);
 
-        SERVICE_INSTANCE_PROPERTIES = new ArrayList<>();
-        for (String key : Config.Agent.INSTANCE_PROPERTIES.keySet()) {
-            SERVICE_INSTANCE_PROPERTIES.add(KeyStringValuePair.newBuilder()
-                                                              .setKey(key)
-                                                              .setValue(Config.Agent.INSTANCE_PROPERTIES.get(key))
-                                                              .build());
-        }
+        SERVICE_INSTANCE_PROPERTIES = InstanceJsonPropertiesUtil.parseProperties();
     }
 
     @Override
diff --git a/docs/en/setup/service-agent/java-agent/configurations.md b/docs/en/setup/service-agent/java-agent/configurations.md
index 1dfe170..60a2715 100644
--- a/docs/en/setup/service-agent/java-agent/configurations.md
+++ b/docs/en/setup/service-agent/java-agent/configurations.md
@@ -14,7 +14,8 @@ property key | Description | Default |
 `agent.is_cache_enhanced_class`|If true, SkyWalking agent will cache all instrumented classes files to memory or disk files (decided by class cache mode), allow another java agent to enhance those classes that enhanced by SkyWalking agent. To use some Java diagnostic tools (such as BTrace, Arthas) to diagnose applications or add a custom java agent to enhance classes, you need to enable this feature. |`false`|
 `agent.class_cache_mode`|The instrumented classes cache mode: `MEMORY` or `FILE`. `MEMORY`: cache class bytes to memory, if instrumented classes is too many or too large, it may take up more memory. `FILE`: cache class bytes in `/class-cache` folder, automatically clean up cached class files when the application exits.|`MEMORY`|
 `agent.instance_name` |Instance name is the identity of an instance, should be unique in the service. If empty, SkyWalking agent will generate an 32-bit uuid. Default, use `UUID`@`hostname` as the instance name. Max length is 50(UTF-8 char)|`""`|
-`agent.instance_properties[key]=value` | Add service instance custom properties. | Not set|
+`agent.instance_properties[key]=value` | Add service instance custom properties. Notice it could be overridden by `agent.instance_properties_json `, if the key duplication. | Not set|
+`agent.instance_properties_json={"key":"value"}` | Add service instance custom properties in json format.  | Not set|
 `agent.cause_exception_depth`|How depth the agent goes, when log all cause exceptions.|`5`|
 `agent.force_reconnection_period `|Force reconnection period of grpc, based on grpc_channel_check_interval.|`1`|
 `agent.operation_name_threshold `|The operationName max length, setting this value > 190 is not recommended.|`150`|
diff --git a/test/e2e/base/base-compose.yml b/test/e2e/base/base-compose.yml
index d8523b3..af4578c 100644
--- a/test/e2e/base/base-compose.yml
+++ b/test/e2e/base/base-compose.yml
@@ -46,6 +46,8 @@ services:
       SW_AGENT_COLLECTOR_BACKEND_SERVICES: oap:11800
       SW_AGENT_INSTANCE_NAME: provider1
       SW_LOGGING_OUTPUT: CONSOLE
+      JAVA_TOOL_OPTIONS: -javaagent:/skywalking/agent/skywalking-agent.jar=agent.instance_properties[org]=apache
+      SW_INSTANCE_PROPERTIES_JSON: "{\"org\": \"apache-skywalking\"}"
     healthcheck:
       test: [ "CMD", "sh", "-c", "nc -zn 127.0.0.1 9090"]
       interval: 5s
diff --git a/test/e2e/case/expected/service-instance.yml b/test/e2e/case/expected/service-instance.yml
index 4fa45b3..59b8e01 100644
--- a/test/e2e/case/expected/service-instance.yml
+++ b/test/e2e/case/expected/service-instance.yml
@@ -20,6 +20,8 @@
   name: {{ notEmpty .name }}
   attributes:
   {{- contains .attributes }}
+  - name: org
+    value: apache-skywalking
   - name: OS Name
     value: Linux
   - name: hostname