diff --git a/CHANGES.md b/CHANGES.md index 2067841a9..9f870b9d4 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -19,6 +19,7 @@ Release Notes. * Fix Span not finished in gateway plugin when the gateway request timeout. * Support `-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector` in gRPC log report. * Fix tcnative libraries relocation for aarch64. +* Add `plugin.jdbc.trace_sql_parameters` into Configuration Discovery Service. #### Documentation diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/dynamic/ConfigurationDiscoveryService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/dynamic/ConfigurationDiscoveryService.java index ed596adfc..9e53452bc 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/dynamic/ConfigurationDiscoveryService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/dynamic/ConfigurationDiscoveryService.java @@ -43,6 +43,7 @@ import org.apache.skywalking.apm.agent.core.logging.api.LogManager; import org.apache.skywalking.apm.agent.core.remote.GRPCChannelListener; import org.apache.skywalking.apm.agent.core.remote.GRPCChannelManager; import org.apache.skywalking.apm.agent.core.remote.GRPCChannelStatus; +import org.apache.skywalking.apm.agent.core.util.CollectionUtil; import org.apache.skywalking.apm.network.language.agent.v3.ConfigurationDiscoveryServiceGrpc; import org.apache.skywalking.apm.network.language.agent.v3.ConfigurationSyncRequest; import org.apache.skywalking.apm.network.common.v3.Commands; @@ -118,10 +119,16 @@ public class ConfigurationDiscoveryService implements BootService, GRPCChannelLi * * @param watcher dynamic configuration watcher */ - public void registerAgentConfigChangeWatcher(AgentConfigChangeWatcher watcher) { + public synchronized void registerAgentConfigChangeWatcher(AgentConfigChangeWatcher watcher) { WatcherHolder holder = new WatcherHolder(watcher); if (register.containsKey(holder.getKey())) { - throw new IllegalStateException("Duplicate register, watcher=" + watcher); + List watcherHolderList = register.get(holder.getKey()); + for (WatcherHolder watcherHolder : watcherHolderList) { + if (watcherHolder.getWatcher().getClass().equals(watcher.getClass())) { + LOGGER.debug("Duplicate register, watcher={}", watcher); + return; + } + } } register.put(holder.getKey(), holder); } @@ -142,31 +149,33 @@ public class ConfigurationDiscoveryService implements BootService, GRPCChannelLi config.forEach(property -> { String propertyKey = property.getKey(); - WatcherHolder holder = register.get(propertyKey); - if (holder != null) { - AgentConfigChangeWatcher watcher = holder.getWatcher(); - String newPropertyValue = property.getValue(); - if (StringUtil.isBlank(newPropertyValue)) { - if (watcher.value() != null) { - // Notify watcher, the new value is null with delete event type. - watcher.notify( - new AgentConfigChangeWatcher.ConfigChangeEvent( - null, AgentConfigChangeWatcher.EventType.DELETE - )); + List holderList = register.get(propertyKey); + for (WatcherHolder holder : holderList) { + if (holder != null) { + AgentConfigChangeWatcher watcher = holder.getWatcher(); + String newPropertyValue = property.getValue(); + if (StringUtil.isBlank(newPropertyValue)) { + if (watcher.value() != null) { + // Notify watcher, the new value is null with delete event type. + watcher.notify( + new AgentConfigChangeWatcher.ConfigChangeEvent( + null, AgentConfigChangeWatcher.EventType.DELETE + )); + } else { + // Don't need to notify, stay in null. + } } else { - // Don't need to notify, stay in null. + if (!newPropertyValue.equals(watcher.value())) { + watcher.notify(new AgentConfigChangeWatcher.ConfigChangeEvent( + newPropertyValue, AgentConfigChangeWatcher.EventType.MODIFY + )); + } else { + // Don't need to notify, stay in the same config value. + } } } else { - if (!newPropertyValue.equals(watcher.value())) { - watcher.notify(new AgentConfigChangeWatcher.ConfigChangeEvent( - newPropertyValue, AgentConfigChangeWatcher.EventType.MODIFY - )); - } else { - // Don't need to notify, stay in the same config value. - } + LOGGER.warn("Config {} from OAP, doesn't match any watcher, ignore.", propertyKey); } - } else { - LOGGER.warn("Config {} from OAP, doesn't match any watcher, ignore.", propertyKey); } }); this.uuid = responseUuid; @@ -238,17 +247,25 @@ public class ConfigurationDiscoveryService implements BootService, GRPCChannelLi * Local dynamic configuration center. */ public static class Register { - private final Map register = new HashMap<>(); + private final Map> register = new HashMap<>(); private boolean containsKey(String key) { return register.containsKey(key); } private void put(String key, WatcherHolder holder) { - register.put(key, holder); + List watcherHolderList = register.get(key); + if (CollectionUtil.isEmpty(watcherHolderList)) { + ArrayList newWatchHolderList = new ArrayList<>(); + newWatchHolderList.add(holder); + register.put(key, newWatchHolderList); + } else { + watcherHolderList.add(holder); + register.put(key, watcherHolderList); + } } - public WatcherHolder get(String name) { + public List get(String name) { return register.get(name); } @@ -259,12 +276,13 @@ public class ConfigurationDiscoveryService implements BootService, GRPCChannelLi @Override public String toString() { ArrayList registerTableDescription = new ArrayList<>(register.size()); - register.forEach((key, holder) -> { - AgentConfigChangeWatcher watcher = holder.getWatcher(); - registerTableDescription.add(new StringBuilder().append("key:") - .append(key) - .append("value(current):") - .append(watcher.value()).toString()); + register.forEach((key, holderList) -> { + for (WatcherHolder holder : holderList) { + registerTableDescription.add(new StringBuilder().append("key:") + .append(key) + .append("value(current):") + .append(holder.getWatcher().value()).toString()); + } }); return registerTableDescription.stream().collect(Collectors.joining(",", "[", "]")); } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/JDBCDriverInterceptor.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/JDBCDriverInterceptor.java index a0cba0f78..ea71968dc 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/JDBCDriverInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/JDBCDriverInterceptor.java @@ -20,6 +20,9 @@ package org.apache.skywalking.apm.plugin.jdbc; import java.lang.reflect.Method; import java.sql.Connection; + +import org.apache.skywalking.apm.agent.core.boot.ServiceManager; +import org.apache.skywalking.apm.agent.core.conf.dynamic.ConfigurationDiscoveryService; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import org.apache.skywalking.apm.plugin.jdbc.connectionurl.parser.URLParser; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; @@ -34,7 +37,10 @@ public class JDBCDriverInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { - + TraceSqlParametersWatcher traceSqlParametersWatcher = new TraceSqlParametersWatcher("plugin.jdbc.trace_sql_parameters"); + ConfigurationDiscoveryService configurationDiscoveryService = ServiceManager.INSTANCE.findService( + ConfigurationDiscoveryService.class); + configurationDiscoveryService.registerAgentConfigChangeWatcher(traceSqlParametersWatcher); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/JDBCPluginConfig.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/JDBCPluginConfig.java index 8b8b953a0..8619c5446 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/JDBCPluginConfig.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/JDBCPluginConfig.java @@ -28,7 +28,7 @@ public class JDBCPluginConfig { * If set to true, the parameters of the sql (typically {@link java.sql.PreparedStatement}) would be * collected. */ - public static boolean TRACE_SQL_PARAMETERS = false; + public static volatile boolean TRACE_SQL_PARAMETERS = false; /** * For the sake of performance, SkyWalking won't save the entire parameters string into the tag, but only * the first {@code SQL_PARAMETERS_MAX_LENGTH} characters. diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PSSetterDefinitionOfJDBCInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PSSetterDefinitionOfJDBCInstrumentation.java index 8ee16bf55..1d5ae8713 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PSSetterDefinitionOfJDBCInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/PSSetterDefinitionOfJDBCInstrumentation.java @@ -40,11 +40,10 @@ public class PSSetterDefinitionOfJDBCInstrumentation implements InstanceMethodsI public ElementMatcher getMethodsMatcher() { ElementMatcher.Junction matcher = none(); - if (JDBCPluginConfig.Plugin.JDBC.TRACE_SQL_PARAMETERS) { - final Set setters = ignorable ? PS_IGNORABLE_SETTERS : PS_SETTERS; - for (String setter : setters) { - matcher = matcher.or(named(setter)); - } + // remove TRACE_SQL_PARAMETERS judgement for dynamic config + final Set setters = ignorable ? PS_IGNORABLE_SETTERS : PS_SETTERS; + for (String setter : setters) { + matcher = matcher.or(named(setter)); } return matcher; diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/TraceSqlParametersWatcher.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/TraceSqlParametersWatcher.java new file mode 100644 index 000000000..d28715df5 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/TraceSqlParametersWatcher.java @@ -0,0 +1,46 @@ +/* + * 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.jdbc; + +import org.apache.skywalking.apm.agent.core.conf.dynamic.AgentConfigChangeWatcher; + +public class TraceSqlParametersWatcher extends AgentConfigChangeWatcher { + + private final boolean defaultValue; + + public TraceSqlParametersWatcher(String propertyKey) { + super(propertyKey); + defaultValue = JDBCPluginConfig.Plugin.JDBC.TRACE_SQL_PARAMETERS; + } + + @Override + public void notify(ConfigChangeEvent value) { + if (EventType.DELETE.equals(value.getEventType())) { + JDBCPluginConfig.Plugin.JDBC.TRACE_SQL_PARAMETERS = defaultValue; + } else { + JDBCPluginConfig.Plugin.JDBC.TRACE_SQL_PARAMETERS = Boolean.parseBoolean(value.getNewValue()); + } + } + + @Override + public String value() { + return Boolean.toString(JDBCPluginConfig.Plugin.JDBC.TRACE_SQL_PARAMETERS); + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v5/define/DriverInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v5/define/DriverInstrumentation.java new file mode 100644 index 000000000..a0d788c1f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v5/define/DriverInstrumentation.java @@ -0,0 +1,39 @@ +/* + * 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.jdbc.mysql.v5.define; + +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation; + +import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch.byMultiClassMatch; + +/** + * {@link DriverInstrumentation} presents that skywalking intercepts {@link com.mysql.jdbc.Driver}. + */ +public class DriverInstrumentation extends AbstractDriverInstrumentation { + @Override + protected ClassMatch enhanceClass() { + return byMultiClassMatch("com.mysql.jdbc.Driver", "com.mysql.cj.jdbc.Driver", "com.mysql.jdbc.NonRegisteringDriver"); + } + + @Override + protected String[] witnessClasses() { + return new String[] {Constants.WITNESS_MYSQL_5X_CLASS}; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/resources/skywalking-plugin.def index 57fea2cc3..f62d8fbe3 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/resources/skywalking-plugin.def @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.DriverInstrumentation mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.Mysql5xConnectionInstrumentation mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.Mysql50ConnectionInstrumentation mysql-5.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v5.define.CallableInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v8/define/DriverInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v8/define/DriverInstrumentation.java new file mode 100644 index 000000000..93078de32 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/v8/define/DriverInstrumentation.java @@ -0,0 +1,39 @@ +/* + * 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.jdbc.mysql.v8.define; + +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation; + +import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch.byMultiClassMatch; + +/** + * {@link DriverInstrumentation} presents that skywalking intercepts {@link com.mysql.jdbc.Driver}. + */ +public class DriverInstrumentation extends AbstractDriverInstrumentation { + @Override + protected ClassMatch enhanceClass() { + return byMultiClassMatch("com.mysql.jdbc.Driver", "com.mysql.cj.jdbc.Driver", "com.mysql.jdbc.NonRegisteringDriver"); + } + + @Override + protected String[] witnessClasses() { + return new String[] {Constants.WITNESS_MYSQL_8X_CLASS}; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/resources/skywalking-plugin.def index 9c456171c..c0c811261 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/mysql-8.x-plugin/src/main/resources/skywalking-plugin.def @@ -14,6 +14,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.DriverInstrumentation mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.ConnectionImplCreateInstrumentation mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.ConnectionInstrumentation mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.CallableInstrumentation @@ -22,4 +23,4 @@ mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.StatementInstrum mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.PreparedStatementSetterInstrumentation mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.PreparedStatementNullSetterInstrumentation mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.PreparedStatementIgnoredSetterInstrumentation -mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.CacheIpsInstrumentation \ No newline at end of file +mysql-8.x=org.apache.skywalking.apm.plugin.jdbc.mysql.v8.define.CacheIpsInstrumentation diff --git a/docs/en/setup/service-agent/java-agent/Plugin-test.md b/docs/en/setup/service-agent/java-agent/Plugin-test.md index 39453b60e..aea2a4534 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-test.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-test.md @@ -16,23 +16,22 @@ Every plugin maintained in the main repo requires corresponding test cases as we ## Case Base Image Introduction -The test framework provides `JVM-container` and `Tomcat-container` base images including JDK8 and JDK14. You can choose the best one for your test case. If both are suitable for your case, **`JVM-container` is preferred**. +The test framework provides `JVM-container` and `Tomcat-container` base images including JDK8 and JDK17. You can choose the best one for your test case. If both are suitable for your case, **`JVM-container` is preferred**. ### JVM-container Image Introduction -[JVM-container](../../../../../test/plugin/containers/jvm-container) uses `adoptopenjdk/openjdk8:alpine-jre` as the base image. `JVM-container` supports JDK14 and JDK17 as well in CI, which inherits `adoptopenjdk/openjdk8:alpine-jre` and `eclipse-temurin:17-alpine`. +[JVM-container](../../../../../test/plugin/containers/jvm-container) uses `adoptopenjdk/openjdk8:alpine-jre` as the base image. `JVM-container` supports JDK8 and JDK17 as well in CI, which inherits `adoptopenjdk/openjdk8:alpine-jre` and `eclipse-temurin:17-alpine`. It is supported to custom the base Java docker image by specify `base_image_java`. The test case project must be packaged as `project-name.zip`, including `startup.sh` and uber jar, by using `mvn clean package`. Take the following test projects as examples: * [sofarpc-scenario](../../../../../test/plugin/scenarios/sofarpc-scenario) is a single project case. * [webflux-scenario](../../../../../test/plugin/scenarios/webflux-scenario) is a case including multiple projects. -* [jdk14-with-gson-scenario](../../../../../test/plugin/scenarios/jdk14-with-gson-scenario) is a single project case with JDK14. * [jdk17-with-gson-scenario](../../../../../test/plugin/scenarios/jdk17-with-gson-scenario) is a single project case with JDK17. ### Tomcat-container Image Introduction -[Tomcat-container](../../../../../test/plugin/containers/tomcat-container) uses `tomcat:8.5-jdk8-openjdk`, `tomcat:8.5-jdk14-openjdk`, `tomcat:8.5-jdk17-openjdk` as the base image. +[Tomcat-container](../../../../../test/plugin/containers/tomcat-container) uses `tomcat:8.5-jdk8-openjdk`, `tomcat:8.5-jdk17-openjdk` as the base image. It is supported to custom the base Tomcat docker image by specify `base_image_tomcat`. The test case project must be packaged as `project-name.war` by using `mvn package`. @@ -623,7 +622,7 @@ Every test case is a GitHub Actions Job. Please use the scenario directory name mostly you'll just need to decide which file (`plugins-test..yaml`) to add your test case, and simply put one line (as follows) in it, take the existed cases as examples. You can run `python3 tools/select-group.py` to see which file contains the least cases and add your cases into it, in order to balance the running time of each group. -If a test case required to run in JDK 14 environment, please add you test case into file `plugins-jdk14-test..yaml`. +If a test case required to run in JDK 17 environment, please add you test case into file `plugins-jdk17-test..yaml`. ```yaml jobs: diff --git a/docs/en/setup/service-agent/java-agent/configuration-discovery.md b/docs/en/setup/service-agent/java-agent/configuration-discovery.md index b860e35a1..9d99bdd82 100644 --- a/docs/en/setup/service-agent/java-agent/configuration-discovery.md +++ b/docs/en/setup/service-agent/java-agent/configuration-discovery.md @@ -28,5 +28,6 @@ Java agent supports the following dynamic configurations. | agent.ignore_suffix | If the operation name of the first span is included in this set, this segment should be ignored. Multiple values should be separated by `,` | `.txt,.log` | - | | agent.trace.ignore_path | The value is the path that you need to ignore, multiple paths should be separated by `,` [more details](./agent-optional-plugins/trace-ignore-plugin.md) | `/your/path/1/**,/your/path/2/**` | `apm-trace-ignore-plugin` | | agent.span_limit_per_segment | The max number of spans per segment. | `300` | - | +| plugin.jdbc.trace_sql_parameters | If set to true, the parameters of the sql (typically java.sql.PreparedStatement) would be collected. | `false` | - | * `Required plugin(s)`, the configuration affects only when the required plugins activated.