diff --git a/CHANGES.md b/CHANGES.md index aec786051..8133a36e6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ Release Notes. * Compatible with the versions after dubbo-2.7.14 * Follow protocol grammar fix `GCPhrase -> GCPhase`. * Support ZGC GC time and count metric collect. (Require 9.0.0 OAP) +* Support configuration for collecting redis parameters for jedis-2.x and redisson-3.x plugin. #### Documentation diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java index 88381fbd0..ebcc734ab 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptor.java @@ -28,9 +28,13 @@ import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; import org.apache.skywalking.apm.agent.core.context.ContextManager; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.util.StringUtil; public class JedisMethodInterceptor implements InstanceMethodsAroundInterceptor { + private static final String ABBR = "..."; + private static final String DELIMITER_SPACE = " "; + @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { @@ -41,12 +45,24 @@ public class JedisMethodInterceptor implements InstanceMethodsAroundInterceptor SpanLayer.asCache(span); if (allArguments.length > 0 && allArguments[0] instanceof String) { - Tags.DB_STATEMENT.set(span, method.getName() + " " + allArguments[0]); + Tags.DB_STATEMENT.set(span, getDBStatement(method.getName(), (String) allArguments[0])); } else if (allArguments.length > 0 && allArguments[0] instanceof byte[]) { Tags.DB_STATEMENT.set(span, method.getName()); } } + private String getDBStatement(String methodName, String argument) { + StringBuilder dbStatement = new StringBuilder(methodName); + if (JedisPluginConfig.Plugin.Jedis.TRACE_REDIS_PARAMETERS && !StringUtil.isEmpty(argument)) { + dbStatement.append(DELIMITER_SPACE); + if (argument.length() > JedisPluginConfig.Plugin.Jedis.REDIS_PARAMETER_MAX_LENGTH) { + argument = argument.substring(0, JedisPluginConfig.Plugin.Jedis.REDIS_PARAMETER_MAX_LENGTH) + ABBR; + } + dbStatement.append(argument); + } + return dbStatement.toString(); + } + @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisPluginConfig.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisPluginConfig.java new file mode 100644 index 000000000..268faa965 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisPluginConfig.java @@ -0,0 +1,41 @@ +/* + * 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.plugin.jedis.v2; + +import org.apache.skywalking.apm.agent.core.boot.PluginConfig; + +public class JedisPluginConfig { + public static class Plugin { + @PluginConfig(root = JedisPluginConfig.class) + public static class Jedis { + /** + * If set to true, the parameters of the Redis command would be collected. + */ + public static boolean TRACE_REDIS_PARAMETERS = false; + /** + * For the sake of performance, SkyWalking won't save Redis parameter string into the tag. + * If TRACE_REDIS_PARAMETERS is set to true, the first {@code REDIS_PARAMETER_MAX_LENGTH} parameter + * characters would be collected. + *

+ * Set a negative number to save specified length of parameter string to the tag. + */ + public static int REDIS_PARAMETER_MAX_LENGTH = 128; + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptorTest.java index ffa9517fb..276410256 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptorTest.java @@ -69,6 +69,8 @@ public class JedisMethodInterceptorTest { @Before public void setUp() throws Exception { + JedisPluginConfig.Plugin.Jedis.TRACE_REDIS_PARAMETERS = true; + allArgument = new Object[] { "OperationKey", "OperationValue" diff --git a/apm-sniffer/apm-sdk-plugin/redisson-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/redisson/v3/RedisConnectionMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/redisson-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/redisson/v3/RedisConnectionMethodInterceptor.java index 8f96cd0b6..5a62afe32 100644 --- a/apm-sniffer/apm-sdk-plugin/redisson-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/redisson/v3/RedisConnectionMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/redisson-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/redisson/v3/RedisConnectionMethodInterceptor.java @@ -44,6 +44,10 @@ public class RedisConnectionMethodInterceptor implements InstanceMethodsAroundIn private static final ILog LOGGER = LogManager.getLogger(RedisConnectionMethodInterceptor.class); + private static final String ABBR = "..."; + private static final String QUESTION_MARK = "?"; + private static final String DELIMITER_SPACE = " "; + @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { @@ -81,9 +85,14 @@ public class RedisConnectionMethodInterceptor implements InstanceMethodsAroundIn private void addCommandData(StringBuilder dbStatement, CommandData commandData) { dbStatement.append(commandData.getCommand().getName()); - if (commandData.getParams() != null) { + if (RedissonPluginConfig.Plugin.Redisson.TRACE_REDIS_PARAMETERS && commandData.getParams() != null) { for (Object param : commandData.getParams()) { - dbStatement.append(" ").append(param instanceof ByteBuf ? "?" : String.valueOf(param.toString())); + dbStatement.append(DELIMITER_SPACE); + String paramStr = param instanceof ByteBuf ? QUESTION_MARK : String.valueOf(param.toString()); + if (paramStr.length() > RedissonPluginConfig.Plugin.Redisson.REDIS_PARAMETER_MAX_LENGTH) { + paramStr = paramStr.substring(0, RedissonPluginConfig.Plugin.Redisson.REDIS_PARAMETER_MAX_LENGTH) + ABBR; + } + dbStatement.append(paramStr); } } } diff --git a/apm-sniffer/apm-sdk-plugin/redisson-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/redisson/v3/RedissonPluginConfig.java b/apm-sniffer/apm-sdk-plugin/redisson-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/redisson/v3/RedissonPluginConfig.java new file mode 100644 index 000000000..f97c4a715 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/redisson-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/redisson/v3/RedissonPluginConfig.java @@ -0,0 +1,41 @@ +/* + * 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.plugin.redisson.v3; + +import org.apache.skywalking.apm.agent.core.boot.PluginConfig; + +public class RedissonPluginConfig { + public static class Plugin { + @PluginConfig(root = RedissonPluginConfig.class) + public static class Redisson { + /** + * If set to true, the parameters of the Redis command would be collected. + */ + public static boolean TRACE_REDIS_PARAMETERS = false; + /** + * For the sake of performance, SkyWalking won't save Redis parameter string into the tag. + * If TRACE_REDIS_PARAMETERS is set to true, the first {@code REDIS_PARAMETER_MAX_LENGTH} parameter + * characters would be collected. + *

+ * Set a negative number to save specified length of parameter string to the tag. + */ + public static int REDIS_PARAMETER_MAX_LENGTH = 128; + } + } +} diff --git a/docs/en/setup/service-agent/java-agent/configurations.md b/docs/en/setup/service-agent/java-agent/configurations.md index 3911f6d25..4db9f277a 100644 --- a/docs/en/setup/service-agent/java-agent/configurations.md +++ b/docs/en/setup/service-agent/java-agent/configurations.md @@ -102,10 +102,15 @@ property key | Description | **System Environment Variable** | Default `plugin.springannotation.classname_match_regex` | Match spring beans with regular expression for the class name. Multiple expressions could be separated by a comma. This only works when `Spring annotation plugin` has been activated. | SW_SPRINGANNOTATION_CLASSNAME_MATCH_REGEX | `All the spring beans tagged with @Bean,@Service,@Dao, or @Repository.` `plugin.toolkit.log.transmit_formatted` | Whether or not to transmit logged data as formatted or un-formatted. | SW_PLUGIN_TOOLKIT_LOG_TRANSMIT_FORMATTED | `true` `plugin.lettuce.trace_redis_parameters` | If set to true, the parameters of Redis commands would be collected by Lettuce agent.| SW_PLUGIN_LETTUCE_TRACE_REDIS_PARAMETERS | `false` -`plugin.lettuce.redis_parameter_max_length` | If set to positive number and `plugin.lettuce.trace_redis_parameters` is set to `true`, Redis command parameters would be collected and truncated to this length.| SW_PLUGIN_LETTUCE_REDIS_PARAMETER_MAX_LENGTH | `128` +`plugin.lettuce.redis_parameter_max_length` | If set to positive number and `plugin.lettuce.trace_redis_parameters` is set to `true`, Redis command parameters would be collected and truncated to this length.| SW_PLUGIN_LETTUCE_REDIS_PARAMETER_MAX_LENGTH | `128` +`plugin.jedis.trace_redis_parameters` | If set to true, the parameters of Redis commands would be collected by Jedis agent.| SW_PLUGIN_JEDIS_TRACE_REDIS_PARAMETERS | `false` +`plugin.jedis.redis_parameter_max_length` | If set to positive number and `plugin.jedis.trace_redis_parameters` is set to `true`, Redis command parameters would be collected and truncated to this length.| SW_PLUGIN_JEDIS_REDIS_PARAMETER_MAX_LENGTH | `128` +`plugin.redisson.trace_redis_parameters` | If set to true, the parameters of Redis commands would be collected by Redisson agent.| SW_PLUGIN_REDISSON_TRACE_REDIS_PARAMETERS | `false` +`plugin.redisson.redis_parameter_max_length` | If set to positive number and `plugin.redisson.trace_redis_parameters` is set to `true`, Redis command parameters would be collected and truncated to this length.| SW_PLUGIN_REDISSON_REDIS_PARAMETER_MAX_LENGTH | `128` `plugin.neo4j.trace_cypher_parameters`|If set to true, the parameters of the cypher would be collected.|SW_PLUGIN_NEO4J_TRACE_CYPHER_PARAMETERS|`false` `plugin.neo4j.cypher_parameters_max_length`|If set to positive number, the `db.cypher.parameters` would be truncated to this length, otherwise it would be completely saved, which may cause performance problem.|SW_PLUGIN_NEO4J_CYPHER_PARAMETERS_MAX_LENGTH|`512` `plugin.neo4j.cypher_body_max_length`|If set to positive number, the `db.statement` would be truncated to this length, otherwise it would be completely saved, which may cause performance problem.|SW_PLUGIN_NEO4J_CYPHER_BODY_MAX_LENGTH|`2048` + # Dynamic Configurations All configurations above are static, if you need to change some agent settings at runtime, please read [CDS - Configuration Discovery Service document](configuration-discovery.md) for more details. diff --git a/test/plugin/scenarios/jedis-scenario/bin/startup.sh b/test/plugin/scenarios/jedis-scenario/bin/startup.sh index 657a2f240..e09105944 100644 --- a/test/plugin/scenarios/jedis-scenario/bin/startup.sh +++ b/test/plugin/scenarios/jedis-scenario/bin/startup.sh @@ -18,5 +18,4 @@ home="$(cd "$(dirname $0)"; pwd)" -java -jar ${agent_opts} -Dredis.host=${REDIS_HOST} -Dredis.port=${REDIS_PORT} \ -${home}/../libs/jedis-scenario.jar & \ No newline at end of file +java -jar ${agent_opts} -Dredis.host=${REDIS_HOST} -Dredis.port=${REDIS_PORT} -Dskywalking.plugin.jedis.trace_redis_parameters=true ${home}/../libs/jedis-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/redisson-scenario/bin/startup.sh b/test/plugin/scenarios/redisson-scenario/bin/startup.sh index 3463dabe3..28a6efa87 100644 --- a/test/plugin/scenarios/redisson-scenario/bin/startup.sh +++ b/test/plugin/scenarios/redisson-scenario/bin/startup.sh @@ -18,4 +18,4 @@ home="$(cd "$(dirname $0)"; pwd)" -java -Dredis.servers=${REDIS_SERVERS} -jar ${agent_opts} ${home}/../libs/redisson-scenario.jar & \ No newline at end of file +java -Dredis.servers=${REDIS_SERVERS} -Dskywalking.plugin.redisson.trace_redis_parameters=true -jar ${agent_opts} ${home}/../libs/redisson-scenario.jar & \ No newline at end of file