fix bugs with dubbo (#6640)

1. fix NullPointerException with dubbo getMetadata request

2. fix dubbo trace passing problem

the trace is third-demo -> consumer-demo -> provider-deme, but the
parent of provider-demo is third-demo.
wrong data like this
<img width="1994" alt="image"
src="https://user-images.githubusercontent.com/22729740/190597029-ea26569e-96b4-4e30-8ac3-46ead3871b92.png">

after fixed 
<img width="2015" alt="image"
src="https://user-images.githubusercontent.com/22729740/190596923-d65f8646-377d-47ab-9e65-6d75f1407ce0.png">

Co-authored-by: Mateusz Rzeszutek <mrzeszutek@splunk.com>
This commit is contained in:
yingziisme 2022-09-23 21:48:48 +08:00 committed by GitHub
parent 1fb878875a
commit d26e456d1b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 242 additions and 0 deletions

View File

@ -0,0 +1,11 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.apachedubbo.v2_7
import io.opentelemetry.instrumentation.test.AgentTestTrait
class DubboTraceChainTest extends AbstractDubboTraceChainTest implements AgentTestTrait {
}

View File

@ -13,5 +13,6 @@ enum DubboHeadersSetter implements TextMapSetter<DubboRequest> {
@Override
public void set(DubboRequest request, String key, String value) {
request.context().setAttachment(key, value);
request.invocation().setAttachment(key, value);
}
}

View File

@ -35,6 +35,10 @@ final class TracingFilter implements Filter {
}
RpcContext rpcContext = RpcContext.getContext();
if (rpcContext.getUrl() == null) {
return invoker.invoke(invocation);
}
boolean isServer = rpcContext.isProviderSide();
Instrumenter<DubboRequest, Result> instrumenter =
isServer ? serverInstrumenter : clientInstrumenter;

View File

@ -0,0 +1,11 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.apachedubbo.v2_7
import io.opentelemetry.instrumentation.test.LibraryTestTrait
class DubboTraceChainTest extends AbstractDubboTraceChainTest implements LibraryTestTrait {
}

View File

@ -0,0 +1,180 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.apachedubbo.v2_7
import io.opentelemetry.api.trace.SpanKind
import io.opentelemetry.instrumentation.apachedubbo.v2_7.api.HelloService
import io.opentelemetry.instrumentation.apachedubbo.v2_7.api.MiddleService
import io.opentelemetry.instrumentation.apachedubbo.v2_7.impl.HelloServiceImpl
import io.opentelemetry.instrumentation.apachedubbo.v2_7.impl.MiddleServiceImpl
import io.opentelemetry.instrumentation.test.InstrumentationSpecification
import io.opentelemetry.instrumentation.test.utils.PortUtils
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes
import org.apache.dubbo.common.utils.NetUtils
import org.apache.dubbo.config.ApplicationConfig
import org.apache.dubbo.config.ProtocolConfig
import org.apache.dubbo.config.ReferenceConfig
import org.apache.dubbo.config.RegistryConfig
import org.apache.dubbo.config.ServiceConfig
import org.apache.dubbo.config.bootstrap.DubboBootstrap
import org.apache.dubbo.rpc.service.GenericService
import spock.lang.Unroll
import static io.opentelemetry.api.trace.SpanKind.CLIENT
import static io.opentelemetry.api.trace.SpanKind.SERVER
@Unroll
abstract class AbstractDubboTraceChainTest extends InstrumentationSpecification {
def setupSpec() {
NetUtils.LOCAL_ADDRESS = InetAddress.getLoopbackAddress()
}
ReferenceConfig<HelloService> configureClient(int port) {
ReferenceConfig<HelloService> reference = new ReferenceConfig<>()
reference.setInterface(HelloService)
reference.setGeneric("true")
reference.setUrl("dubbo://localhost:" + port + "/?timeout=30000")
return reference
}
ReferenceConfig<HelloService> configureMiddleClient(int port) {
ReferenceConfig<MiddleService> reference = new ReferenceConfig<>()
reference.setInterface(MiddleService)
reference.setGeneric("true")
reference.setUrl("dubbo://localhost:" + port + "/?timeout=30000")
return reference
}
ServiceConfig configureServer() {
def registerConfig = new RegistryConfig()
registerConfig.setAddress("N/A")
ServiceConfig<HelloServiceImpl> service = new ServiceConfig<>()
service.setInterface(HelloService)
service.setRef(new HelloServiceImpl())
service.setRegistry(registerConfig)
return service
}
ServiceConfig configureMiddleServer(GenericService genericService) {
def registerConfig = new RegistryConfig()
registerConfig.setAddress("N/A")
ServiceConfig<MiddleServiceImpl> service = new ServiceConfig<>()
service.setInterface(MiddleService)
service.setRef(new MiddleServiceImpl(genericService))
service.setRegistry(registerConfig)
return service
}
def "test that context is propagated correctly in chained dubbo calls"() {
setup:
def port = PortUtils.findOpenPorts(2)
def middlePort = port + 1
def protocolConfig = new ProtocolConfig()
protocolConfig.setPort(port)
DubboBootstrap bootstrap = DubboBootstrap.newInstance()
bootstrap.application(new ApplicationConfig("dubbo-test-provider"))
.service(configureServer())
.protocol(protocolConfig)
.start()
def middleProtocolConfig = new ProtocolConfig()
middleProtocolConfig.setPort(middlePort)
def reference = configureClient(port)
DubboBootstrap middleBootstrap = DubboBootstrap.newInstance()
middleBootstrap.application(new ApplicationConfig("dubbo-demo-middle"))
.reference(reference)
.service(configureMiddleServer(reference.get()))
.protocol(middleProtocolConfig)
.start()
def consumerProtocolConfig = new ProtocolConfig()
consumerProtocolConfig.setRegister(false)
def middleReference = configureMiddleClient(middlePort)
DubboBootstrap consumerBootstrap = DubboBootstrap.newInstance()
consumerBootstrap.application(new ApplicationConfig("dubbo-demo-api-consumer"))
.reference(middleReference)
.protocol(consumerProtocolConfig)
.start()
when:
GenericService genericService = middleReference.get()
def response = runWithSpan("parent") {
genericService.$invoke("hello", [String.getName()] as String[], ["hello"] as Object[])
}
then:
response == "hello"
assertTraces(1) {
trace(0, 5) {
span(0) {
name "parent"
kind SpanKind.INTERNAL
hasNoParent()
}
span(1) {
name "org.apache.dubbo.rpc.service.GenericService/\$invoke"
kind CLIENT
childOf span(0)
attributes {
"$SemanticAttributes.RPC_SYSTEM" "apache_dubbo"
"$SemanticAttributes.RPC_SERVICE" "org.apache.dubbo.rpc.service.GenericService"
"$SemanticAttributes.RPC_METHOD" "\$invoke"
"$SemanticAttributes.NET_PEER_NAME" "localhost"
"$SemanticAttributes.NET_PEER_PORT" Long
}
}
span(2) {
name "io.opentelemetry.instrumentation.apachedubbo.v2_7.api.MiddleService/hello"
kind SERVER
childOf span(1)
attributes {
"$SemanticAttributes.RPC_SYSTEM" "apache_dubbo"
"$SemanticAttributes.RPC_SERVICE" "io.opentelemetry.instrumentation.apachedubbo.v2_7.api.MiddleService"
"$SemanticAttributes.RPC_METHOD" "hello"
"net.sock.peer.addr" String
"net.sock.peer.port" Long
"net.sock.family" { it == "inet6" || it == null }
}
}
span(3) {
name "org.apache.dubbo.rpc.service.GenericService/\$invoke"
kind CLIENT
childOf span(2)
attributes {
"$SemanticAttributes.RPC_SYSTEM" "apache_dubbo"
"$SemanticAttributes.RPC_SERVICE" "org.apache.dubbo.rpc.service.GenericService"
"$SemanticAttributes.RPC_METHOD" "\$invoke"
"$SemanticAttributes.NET_PEER_NAME" "localhost"
"$SemanticAttributes.NET_PEER_PORT" Long
}
}
span(4) {
name "io.opentelemetry.instrumentation.apachedubbo.v2_7.api.HelloService/hello"
kind SERVER
childOf span(3)
attributes {
"$SemanticAttributes.RPC_SYSTEM" "apache_dubbo"
"$SemanticAttributes.RPC_SERVICE" "io.opentelemetry.instrumentation.apachedubbo.v2_7.api.HelloService"
"$SemanticAttributes.RPC_METHOD" "hello"
"net.sock.peer.addr" String
"net.sock.peer.port" Long
"net.sock.family" { it == "inet6" || it == null }
}
}
}
}
cleanup:
bootstrap.destroy()
middleBootstrap.destroy()
consumerBootstrap.destroy()
}
}

View File

@ -0,0 +1,10 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.apachedubbo.v2_7.api;
public interface MiddleService {
String hello(String hello);
}

View File

@ -0,0 +1,25 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.apachedubbo.v2_7.impl;
import io.opentelemetry.instrumentation.apachedubbo.v2_7.api.MiddleService;
import org.apache.dubbo.rpc.service.GenericService;
public class MiddleServiceImpl implements MiddleService {
private final GenericService genericService;
public MiddleServiceImpl(GenericService genericService) {
this.genericService = genericService;
}
@Override
public String hello(String hello) {
return genericService
.$invoke("hello", new String[] {String.class.getName()}, new Object[] {hello})
.toString();
}
}