The Dubbo plugin can collect more information by custom (#5209)
This commit is contained in:
parent
df397228f1
commit
4149ac59fe
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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` |
|
||||
|
|
|
|||
|
|
@ -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 &
|
||||
|
|
@ -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'
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,5 +19,5 @@
|
|||
package org.apache.skywalking.apm.testcase.dubbo.services;
|
||||
|
||||
public interface GreetService {
|
||||
String doBusiness();
|
||||
String doBusiness(String s);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 + "'}";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue