diff --git a/apm-sniffer/apm-sdk-plugin/dubbo-2.7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/asf/dubbo/DubboInterceptor.java b/apm-sniffer/apm-sdk-plugin/dubbo-2.7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/asf/dubbo/DubboInterceptor.java index 7c11b23a2..23fad057a 100644 --- a/apm-sniffer/apm-sdk-plugin/dubbo-2.7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/asf/dubbo/DubboInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/dubbo-2.7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/asf/dubbo/DubboInterceptor.java @@ -23,11 +23,10 @@ import org.apache.dubbo.rpc.Invocation; import org.apache.dubbo.rpc.Invoker; import org.apache.dubbo.rpc.Result; import org.apache.dubbo.rpc.RpcContext; -import java.lang.reflect.Method; -import org.apache.skywalking.apm.agent.core.context.ContextCarrier; -import org.apache.skywalking.apm.agent.core.context.tag.Tags; import org.apache.skywalking.apm.agent.core.context.CarrierItem; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; @@ -35,12 +34,17 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceM import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import java.lang.reflect.Method; + /** * {@link DubboInterceptor} define how to enhance class {@link org.apache.dubbo.monitor.support.MonitorFilter#invoke(Invoker, * Invocation)}. the trace context transport to the provider side by {@link RpcContext#attachments}.but all the version * of dubbo framework below 2.8.3 don't support {@link RpcContext#attachments}, we support another way to support it. */ public class DubboInterceptor implements InstanceMethodsAroundInterceptor { + + public static final String ARGUMENTS = "arguments"; + /** *

Consumer:

The serialized trace context data will * inject to the {@link RpcContext#attachments} for transport to provider side. @@ -50,7 +54,7 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor { */ @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, - MethodInterceptResult result) throws Throwable { + MethodInterceptResult result) throws Throwable { Invoker invoker = (Invoker) allArguments[0]; Invocation invocation = (Invocation) allArguments[1]; RpcContext rpcContext = RpcContext.getContext(); @@ -61,6 +65,9 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor { final String host = requestURL.getHost(); final int port = requestURL.getPort(); + + boolean needCollectArguments; + int argumentsLengthThreshold; if (isConsumer) { final ContextCarrier contextCarrier = new ContextCarrier(); span = ContextManager.createExitSpan(generateOperationName(requestURL, invocation), contextCarrier, host + ":" + port); @@ -74,6 +81,8 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor { invocation.getAttachments().remove(next.getHeadKey()); } } + needCollectArguments = DubboPluginConfig.Plugin.Dubbo.COLLECT_CONSUMER_ARGUMENTS; + argumentsLengthThreshold = DubboPluginConfig.Plugin.Dubbo.CONSUMER_ARGUMENTS_LENGTH_THRESHOLD; } else { ContextCarrier contextCarrier = new ContextCarrier(); CarrierItem next = contextCarrier.items(); @@ -83,16 +92,20 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor { } span = ContextManager.createEntrySpan(generateOperationName(requestURL, invocation), contextCarrier); + span.setPeer(rpcContext.getRemoteAddressString()); + needCollectArguments = DubboPluginConfig.Plugin.Dubbo.COLLECT_PROVIDER_ARGUMENTS; + argumentsLengthThreshold = DubboPluginConfig.Plugin.Dubbo.PROVIDER_ARGUMENTS_LENGTH_THRESHOLD; } Tags.URL.set(span, generateRequestURL(requestURL, invocation)); + collectArguments(needCollectArguments, argumentsLengthThreshold, span, invocation); span.setComponent(ComponentsDefine.DUBBO); SpanLayer.asRPCFramework(span); } @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, - Object ret) throws Throwable { + Object ret) throws Throwable { Result result = (Result) ret; if (result != null && result.getException() != null) { dealException(result.getException()); @@ -104,7 +117,7 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor { @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, - Class[] argumentsTypes, Throwable t) { + Class[] argumentsTypes, Throwable t) { dealException(t); } @@ -152,4 +165,26 @@ public class DubboInterceptor implements InstanceMethodsAroundInterceptor { requestURL.append(generateOperationName(url, invocation)); return requestURL.toString(); } + + private void collectArguments(boolean needCollectArguments, int argumentsLengthThreshold, AbstractSpan span, Invocation invocation) { + if (needCollectArguments && argumentsLengthThreshold > 0) { + Object[] parameters = invocation.getArguments(); + if (parameters != null && parameters.length > 0) { + StringBuilder stringBuilder = new StringBuilder(); + boolean first = true; + for (Object parameter : parameters) { + if (!first) { + stringBuilder.append(","); + } + stringBuilder.append(parameter); + if (stringBuilder.length() > argumentsLengthThreshold) { + stringBuilder.append("..."); + break; + } + first = false; + } + span.tag(ARGUMENTS, stringBuilder.toString()); + } + } + } } diff --git a/apm-sniffer/apm-sdk-plugin/dubbo-2.7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/asf/dubbo/DubboPluginConfig.java b/apm-sniffer/apm-sdk-plugin/dubbo-2.7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/asf/dubbo/DubboPluginConfig.java new file mode 100644 index 000000000..8b95e756e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/dubbo-2.7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/asf/dubbo/DubboPluginConfig.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.asf.dubbo; + +import org.apache.skywalking.apm.agent.core.boot.PluginConfig; + +public class DubboPluginConfig { + + public static class Plugin { + + @PluginConfig(root = DubboPluginConfig.class) + public static class Dubbo { + + public static boolean COLLECT_CONSUMER_ARGUMENTS = false; + + public static int CONSUMER_ARGUMENTS_LENGTH_THRESHOLD = 256; + + public static boolean COLLECT_PROVIDER_ARGUMENTS = false; + + public static int PROVIDER_ARGUMENTS_LENGTH_THRESHOLD = 256; + } + } +} diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md index 2aeab208d..ba122ccc1 100755 --- a/docs/en/setup/service-agent/java-agent/README.md +++ b/docs/en/setup/service-agent/java-agent/README.md @@ -134,7 +134,12 @@ property key | Description | Default | `plugin.influxdb.trace_influxql`|If true, trace all the influxql(query and write) in InfluxDB access, default is true.|`true`| `correlation.element_max_number`|Max element count of the correlation context.|`3`| `correlation.value_max_length`|Max value length of correlation context element.|`128`| +`plugin.dubbo.collect_consumer_arguments`| Apache Dubbo consumer collect `arguments` in RPC call, use `Object#toString` to collect `arguments`. |`false`| +`plugin.dubbo.consumer_arguments_length_threshold`| When `plugin.dubbo.collect_consumer_arguments` is `true`, Arguments of length from the front will to the OAP backend |`256`| +`plugin.dubbo.collect_provider_arguments`| Apache Dubbo provider collect `arguments` in RPC call, use `Object#toString` to collect `arguments`. |`false`| +`plugin.dubbo.consumer_provider_length_threshold`| When `plugin.dubbo.provider_consumer_arguments` is `true`, Arguments of length from the front will to the OAP backend |`256`| `plugin.kafka.bootstrap_servers`| A list of host/port pairs to use for establishing the initial connection to the Kafka cluster. | `localhost:9092` +`plugin.kafka.consumer_config`| Kafka producer configuration. || `plugin.kafka.producer_config`| Kafka producer configuration. Read [producer configure](http://kafka.apache.org/24/documentation.html#producerconfigs) to get more details. Check [Kafka report doc](How-to-enable-kafka-reporter.md) for more details and examples. | | `plugin.kafka.topic_meter` | Specify which Kafka topic name for Meter System data to report to. | `skywalking_meters` | `plugin.kafka.topic_metrics` | Specify which Kafka topic name for JVM metrics data to report to. | `skywalking_metrics` | diff --git a/test/plugin/scenarios/dubbo-2.7.x-scenario/bin/startup.sh b/test/plugin/scenarios/dubbo-2.7.x-scenario/bin/startup.sh index 7e8e22eba..e02b485fb 100644 --- a/test/plugin/scenarios/dubbo-2.7.x-scenario/bin/startup.sh +++ b/test/plugin/scenarios/dubbo-2.7.x-scenario/bin/startup.sh @@ -18,4 +18,5 @@ home="$(cd "$(dirname $0)"; pwd)" -java -jar ${agent_opts} ${home}/../libs/dubbo-2.7.x-scenario.jar & \ No newline at end of file +java -Dskywalking.plugin.dubbo.collect_consumer_arguments=true \ +-Dskywalking.plugin.dubbo.collect_provider_arguments=true -jar ${agent_opts} ${home}/../libs/dubbo-2.7.x-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/dubbo-2.7.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/dubbo-2.7.x-scenario/config/expectedData.yaml index ffc15904b..a6939e6aa 100644 --- a/test/plugin/scenarios/dubbo-2.7.x-scenario/config/expectedData.yaml +++ b/test/plugin/scenarios/dubbo-2.7.x-scenario/config/expectedData.yaml @@ -14,57 +14,59 @@ # See the License for the specific language governing permissions and # limitations under the License. segmentItems: -- serviceName: dubbo-2.7.x-scenario - segmentSize: ge 3 - segments: - - segmentId: not null - spans: - - operationName: org.apache.skywalking.apm.testcase.dubbo.services.GreetService.doBusiness() - operationId: 0 - parentSpanId: -1 - spanId: 0 - spanLayer: RPCFramework - startTime: nq 0 - endTime: nq 0 - componentId: 3 - isError: false - spanType: Entry - peer: '' - tags: - - {key: url, value: not null} - refs: - - {parentEndpoint: /dubbo-2.7.x-scenario/case/dubbo, networkAddress: 'localhost:20080', - refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null, parentServiceInstance: not - null, parentService: dubbo-2.7.x-scenario, traceId: not null} - skipAnalysis: 'false' - - segmentId: not null - spans: - - operationName: org.apache.skywalking.apm.testcase.dubbo.services.GreetService.doBusiness() - operationId: 0 - parentSpanId: 0 - spanId: 1 - spanLayer: RPCFramework - startTime: nq 0 - endTime: nq 0 - componentId: 3 - isError: false - spanType: Exit - peer: localhost:20080 - tags: - - {key: url, value: 'dubbo://localhost:20080/org.apache.skywalking.apm.testcase.dubbo.services.GreetService.doBusiness()'} - skipAnalysis: 'false' - - operationName: /dubbo-2.7.x-scenario/case/dubbo - operationId: 0 - parentSpanId: -1 - spanId: 0 - spanLayer: Http - startTime: nq 0 - endTime: nq 0 - componentId: 1 - isError: false - spanType: Entry - peer: '' - tags: - - {key: url, value: 'http://localhost:8080/dubbo-2.7.x-scenario/case/dubbo'} - - {key: http.method, value: GET} - skipAnalysis: 'false' + - serviceName: dubbo-2.7.x-scenario + segmentSize: ge 3 + segments: + - segmentId: not null + spans: + - operationName: org.apache.skywalking.apm.testcase.dubbo.services.GreetService.doBusiness(String) + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 3 + isError: false + spanType: Entry + peer: not null + tags: + - {key: url, value: not null} + - {key: arguments, value: helloWorld} + refs: + - {parentEndpoint: /dubbo-2.7.x-scenario/case/dubbo, networkAddress: 'localhost:20080', + refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null, + parentServiceInstance: not null, parentService: dubbo-2.7.x-scenario, traceId: not null} + skipAnalysis: 'false' + - segmentId: not null + spans: + - operationName: org.apache.skywalking.apm.testcase.dubbo.services.GreetService.doBusiness(String) + operationId: 0 + parentSpanId: 0 + spanId: 1 + spanLayer: RPCFramework + startTime: nq 0 + endTime: nq 0 + componentId: 3 + isError: false + spanType: Exit + peer: localhost:20080 + tags: + - {key: url, value: 'dubbo://localhost:20080/org.apache.skywalking.apm.testcase.dubbo.services.GreetService.doBusiness(String)'} + - {key: arguments, value: helloWorld} + skipAnalysis: 'false' + - operationName: /dubbo-2.7.x-scenario/case/dubbo + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 1 + isError: false + spanType: Entry + peer: '' + tags: + - {key: url, value: 'http://localhost:8080/dubbo-2.7.x-scenario/case/dubbo'} + - {key: http.method, value: GET} + skipAnalysis: 'false' diff --git a/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/controller/CaseController.java b/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/controller/CaseController.java index 886ccb704..7ffa1fbbf 100644 --- a/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/controller/CaseController.java +++ b/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/controller/CaseController.java @@ -44,7 +44,7 @@ public class CaseController { @ResponseBody public String dubbo() { GreetService greetService = referenceConfig.get(); - System.out.println(greetService.doBusiness()); + System.out.println(greetService.doBusiness("helloWorld")); return SUCCESS; } } diff --git a/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/services/GreetService.java b/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/services/GreetService.java index 843884fff..51ddcc226 100644 --- a/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/services/GreetService.java +++ b/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/services/GreetService.java @@ -19,5 +19,5 @@ package org.apache.skywalking.apm.testcase.dubbo.services; public interface GreetService { - String doBusiness(); + String doBusiness(String s); } diff --git a/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/services/impl/GreetServiceImpl.java b/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/services/impl/GreetServiceImpl.java index 4e4cebebc..a3835756c 100644 --- a/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/services/impl/GreetServiceImpl.java +++ b/test/plugin/scenarios/dubbo-2.7.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/dubbo/services/impl/GreetServiceImpl.java @@ -21,9 +21,9 @@ package org.apache.skywalking.apm.testcase.dubbo.services.impl; import org.apache.skywalking.apm.testcase.dubbo.services.GreetService; public class GreetServiceImpl implements GreetService { - + @Override - public String doBusiness() { - return "{name:'helloWorld'}"; + public String doBusiness(String s) { + return "{name:'" + s + "'}"; } }