The Dubbo plugin can collect more information by custom (#5209)

This commit is contained in:
于玉桔 2020-08-04 23:26:56 +08:00 committed by GitHub
parent df397228f1
commit 4149ac59fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 148 additions and 66 deletions

View File

@ -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";
/**
* <h2>Consumer:</h2> 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());
}
}
}
}

View File

@ -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;
}
}
}

View File

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

View File

@ -18,4 +18,5 @@
home="$(cd "$(dirname $0)"; pwd)"
java -jar ${agent_opts} ${home}/../libs/dubbo-2.7.x-scenario.jar &
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 &

View File

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

View File

@ -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;
}
}

View File

@ -19,5 +19,5 @@
package org.apache.skywalking.apm.testcase.dubbo.services;
public interface GreetService {
String doBusiness();
String doBusiness(String s);
}

View File

@ -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 + "'}";
}
}