Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for Nacos Client (#9961) #12849

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
3 changes: 3 additions & 0 deletions .fossa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ targets:
- type: gradle
path: ./
target: ':instrumentation:mybatis-3.2:javaagent'
- type: gradle
path: ./
target: ':instrumentation:nacos-client-2.0.0:javaagent'
- type: gradle
path: ./
target: ':instrumentation:opentelemetry-extension-annotations-1.0:javaagent'
Expand Down
1 change: 1 addition & 0 deletions docs/supported-libraries.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ These are the supported libraries and frameworks:
| [Micrometer](https://micrometer.io/) | 1.5+ (disabled by default) | [opentelemetry-micrometer-1.5](../instrumentation/micrometer/micrometer-1.5/library) | none |
| [MongoDB Driver](https://mongodb.github.io/mongo-java-driver/) | 3.1+ | [opentelemetry-mongo-3.1](../instrumentation/mongo/mongo-3.1/library) | [Database Client Spans], [Database Client Metrics] [6] |
| [MyBatis](https://mybatis.org/mybatis-3/) | 3.2+ | N/A | none |
| [Nacos Client](https://nacos.io/) | 2.0.0+ | N/A | none |
| [Netty HTTP codec [5]](https://github.com/netty/netty) | 3.8+ | [opentelemetry-netty-4.1](../instrumentation/netty/netty-4.1/library) | [HTTP Client Spans], [HTTP Client Metrics], [HTTP Server Spans], [HTTP Server Metrics] |
| [OpenSearch Rest Client](https://github.com/opensearch-project/opensearch-java) | 1.0+ | | [Database Client Spans], [Database Client Metrics] [6] |
| [OkHttp](https://github.com/square/okhttp/) | 2.2+ | [opentelemetry-okhttp-3.0](../instrumentation/okhttp/okhttp-3.0/library) | [HTTP Client Spans], [HTTP Client Metrics] |
Expand Down
61 changes: 61 additions & 0 deletions instrumentation/nacos-client-2.0.0/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
## Enhancement Methods
- `com.alibaba.nacos.common.remote.client.grpc.GrpcConnection#request`
- `com.alibaba.nacos.common.remote.client.RpcClient#handleServerRequest`

## Enable Configuration

| Configuration Items | Default Value |
|:---------------------------------------------|:---------------|
| `otel.instrumentation.nacos-client.enabled` | `false` |

## Span Info Details
<table border="1">
<thead>
<tr>
<th>Request Child Class</th>
<th>SpanName</th>
<th>Additional Tags</th>
</tr>
</thead>
<tbody>
<tr>
<td>InstanceRequest</td>
<td>Nacos/{$(lnstanceRequest.getType()}</td>
<td rowspan="5">nacos.namespace <br> nacos.group <br> nacos.service.name</td>
</tr>
<tr>
<td>ServiceQueryRequest</td>
<td>Nacos/queryService</td>
</tr>
<tr>
<td>SubscribeServiceRequest</td>
<td>Nacos/subscribeService <br> Nacos/unsubscribeService</td>
</tr>
<tr>
<td>ServicelistRequest</td>
<td>Nacos/getServicelist</td>
</tr>
<tr>
<td>ConfigQueryRequest</td>
<td>Nacos/queryConfig</td>
</tr>
<tr>
<td>ConfigPublishRequest</td>
<td>Nacos/publishConfig</td>
<td rowspan="3">nacos.data.id <br> nacos.group <br> nacos.tenant</td>
</tr>
<tr>
<td>ConfigRemoveRequest</td>
<td>Nacos/removeConfig</td>
</tr>
<tr>
<td>ConfigChangeNotifyRequest</td>
<td>Nacos/notifyConfigChange</td>
</tr>
<tr>
<td>NotifySubscriberRequest</td>
<td>Nacos/notifySubscribeChange</td>
<td>nacos.group <br> nacos.service.name</td>
</tr>
</tbody>
</table>
24 changes: 24 additions & 0 deletions instrumentation/nacos-client-2.0.0/javaagent/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
plugins {
id("otel.javaagent-instrumentation")
}

muzzle {
pass {
group.set("com.alibaba.nacos")
module.set("nacos-client")
versions.set("[2.0.0,)")
skip("0.5.0", "0.6.1", "1.1.2", "1.1.4", "1.4.7")
assertInverse.set(true)
}
}

dependencies {
library("com.alibaba.nacos:nacos-client:2.0.0")
testImplementation("javax.annotation:javax.annotation-api:1.3.2")

latestDepTestLibrary("com.alibaba.nacos:nacos-client:2.0.4+") // documented limitation
}

tasks.withType<Test>().configureEach {
jvmArgs("-Dotel.instrumentation.nacos-client.enabled=true")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.nacos.client.v2_0_0;

import io.opentelemetry.api.common.AttributeKey;

public class NacosClientConstants {
private NacosClientConstants() {}

public static final String NACOS_PREFIX = "Nacos/";

public static final String SERVER_CHECK = "serverCheck";

public static final String QUERY_SERVICE = "queryService";

public static final String SUBSCRIBE_SERVICE = "subscribeService";

public static final String UNSUBSCRIBE_SERVICE = "unsubscribeService";

public static final String QUERY_CONFIG = "queryConfig";

public static final String PUBLISH_CONFIG = "publishConfig";

public static final String REMOVE_CONFIG = "removeConfig";

public static final String GET_SERVICE_LIST = "getServiceList";

public static final String NOTIFY_SUBSCRIBE_CHANGE = "notifySubscribeChange";

public static final String NOTIFY_CONFIG_CHANGE = "notifyConfigChange";

public static final AttributeKey<String> NACOS_NAME_SPACE_ATTR =
AttributeKey.stringKey("nacos.namespace");

public static final AttributeKey<String> NACOS_GROUP_NAME_ATTR =
AttributeKey.stringKey("nacos.group.name");

public static final AttributeKey<String> NACOS_SERVICE_NAME_ATTR =
AttributeKey.stringKey("nacos.service.name");

public static final AttributeKey<String> NACOS_DATA_ID_ATTR =
AttributeKey.stringKey("nacos.data.id");

public static final AttributeKey<String> NACOS_GROUP_ATTR = AttributeKey.stringKey("nacos.group");

public static final AttributeKey<String> NACOS_TENANT_ATTR =
AttributeKey.stringKey("nacos.tenant");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.nacos.client.v2_0_0;

import com.alibaba.nacos.api.config.remote.request.ConfigChangeNotifyRequest;
import com.alibaba.nacos.api.config.remote.request.ConfigPublishRequest;
import com.alibaba.nacos.api.config.remote.request.ConfigQueryRequest;
import com.alibaba.nacos.api.config.remote.request.ConfigRemoveRequest;
import com.alibaba.nacos.api.naming.remote.request.InstanceRequest;
import com.alibaba.nacos.api.naming.remote.request.NotifySubscriberRequest;
import com.alibaba.nacos.api.naming.remote.request.ServiceListRequest;
import com.alibaba.nacos.api.naming.remote.request.ServiceQueryRequest;
import com.alibaba.nacos.api.naming.remote.request.SubscribeServiceRequest;
import com.alibaba.nacos.api.remote.request.Request;
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Nonnull;

public class NacosClientHelper {
private static final NacosClientRequestOperator UNKNOWN_OPERATOR =
new NacosClientRequestOperator(request -> request.getClass().getSimpleName(), null);
private static final Map<Class<? extends Request>, NacosClientRequestOperator>
KNOWN_OPERATOR_MAP = new HashMap<>();

private NacosClientHelper() {}

static {
KNOWN_OPERATOR_MAP.put(
InstanceRequest.class,
new NacosClientRequestOperator(
request -> ((InstanceRequest) request).getType(),
(attributesBuilder, request) -> {
InstanceRequest instanceRequest = (InstanceRequest) request;
attributesBuilder.put(
NacosClientConstants.NACOS_NAME_SPACE_ATTR, instanceRequest.getNamespace());
attributesBuilder.put(
NacosClientConstants.NACOS_GROUP_NAME_ATTR, instanceRequest.getGroupName());
attributesBuilder.put(
NacosClientConstants.NACOS_SERVICE_NAME_ATTR, instanceRequest.getServiceName());
}));

KNOWN_OPERATOR_MAP.put(
ServiceQueryRequest.class,
new NacosClientRequestOperator(
request -> NacosClientConstants.QUERY_SERVICE,
(attributesBuilder, request) -> {
ServiceQueryRequest serviceQueryRequest = (ServiceQueryRequest) request;
attributesBuilder.put(
NacosClientConstants.NACOS_NAME_SPACE_ATTR, serviceQueryRequest.getNamespace());
attributesBuilder.put(
NacosClientConstants.NACOS_GROUP_NAME_ATTR, serviceQueryRequest.getGroupName());
attributesBuilder.put(
NacosClientConstants.NACOS_SERVICE_NAME_ATTR,
serviceQueryRequest.getServiceName());
}));

KNOWN_OPERATOR_MAP.put(
SubscribeServiceRequest.class,
new NacosClientRequestOperator(
request ->
((SubscribeServiceRequest) request).isSubscribe()
? NacosClientConstants.SUBSCRIBE_SERVICE
: NacosClientConstants.UNSUBSCRIBE_SERVICE,
(attributesBuilder, request) -> {
SubscribeServiceRequest subscribeServiceRequest = (SubscribeServiceRequest) request;
attributesBuilder.put(
NacosClientConstants.NACOS_NAME_SPACE_ATTR,
subscribeServiceRequest.getNamespace());
attributesBuilder.put(
NacosClientConstants.NACOS_GROUP_NAME_ATTR,
subscribeServiceRequest.getGroupName());
attributesBuilder.put(
NacosClientConstants.NACOS_SERVICE_NAME_ATTR,
subscribeServiceRequest.getServiceName());
}));

KNOWN_OPERATOR_MAP.put(
ServiceListRequest.class,
new NacosClientRequestOperator(
request -> NacosClientConstants.GET_SERVICE_LIST,
(attributesBuilder, request) -> {
ServiceListRequest serviceListRequest = (ServiceListRequest) request;
attributesBuilder.put(
NacosClientConstants.NACOS_NAME_SPACE_ATTR, serviceListRequest.getNamespace());
attributesBuilder.put(
NacosClientConstants.NACOS_GROUP_NAME_ATTR, serviceListRequest.getGroupName());
attributesBuilder.put(
NacosClientConstants.NACOS_SERVICE_NAME_ATTR,
serviceListRequest.getServiceName());
}));

KNOWN_OPERATOR_MAP.put(
ConfigQueryRequest.class,
new NacosClientRequestOperator(
request -> NacosClientConstants.QUERY_CONFIG,
(attributesBuilder, request) -> {
ConfigQueryRequest configQueryRequest = (ConfigQueryRequest) request;
attributesBuilder.put(
NacosClientConstants.NACOS_DATA_ID_ATTR, configQueryRequest.getDataId());
attributesBuilder.put(
NacosClientConstants.NACOS_GROUP_ATTR, configQueryRequest.getGroup());
attributesBuilder.put(
NacosClientConstants.NACOS_TENANT_ATTR, configQueryRequest.getTenant());
}));

KNOWN_OPERATOR_MAP.put(
ConfigPublishRequest.class,
new NacosClientRequestOperator(
request -> NacosClientConstants.PUBLISH_CONFIG,
(attributesBuilder, request) -> {
ConfigPublishRequest configPublishRequest = (ConfigPublishRequest) request;
attributesBuilder.put(
NacosClientConstants.NACOS_DATA_ID_ATTR, configPublishRequest.getDataId());
attributesBuilder.put(
NacosClientConstants.NACOS_GROUP_ATTR, configPublishRequest.getGroup());
attributesBuilder.put(
NacosClientConstants.NACOS_TENANT_ATTR, configPublishRequest.getTenant());
}));

KNOWN_OPERATOR_MAP.put(
ConfigRemoveRequest.class,
new NacosClientRequestOperator(
request -> NacosClientConstants.REMOVE_CONFIG,
(attributesBuilder, request) -> {
ConfigRemoveRequest configRemoveRequest = (ConfigRemoveRequest) request;
attributesBuilder.put(
NacosClientConstants.NACOS_DATA_ID_ATTR, configRemoveRequest.getDataId());
attributesBuilder.put(
NacosClientConstants.NACOS_GROUP_ATTR, configRemoveRequest.getGroup());
attributesBuilder.put(
NacosClientConstants.NACOS_TENANT_ATTR, configRemoveRequest.getTenant());
}));

KNOWN_OPERATOR_MAP.put(
NotifySubscriberRequest.class,
new NacosClientRequestOperator(
request -> NacosClientConstants.NOTIFY_SUBSCRIBE_CHANGE,
(attributesBuilder, request) -> {
NotifySubscriberRequest notifySubscriberRequest = (NotifySubscriberRequest) request;
attributesBuilder.put(
NacosClientConstants.NACOS_NAME_SPACE_ATTR,
notifySubscriberRequest.getNamespace());
attributesBuilder.put(
NacosClientConstants.NACOS_GROUP_NAME_ATTR,
notifySubscriberRequest.getGroupName());
attributesBuilder.put(
NacosClientConstants.NACOS_SERVICE_NAME_ATTR,
notifySubscriberRequest.getServiceName());
}));

KNOWN_OPERATOR_MAP.put(
ConfigChangeNotifyRequest.class,
new NacosClientRequestOperator(
request -> NacosClientConstants.NOTIFY_CONFIG_CHANGE,
(attributesBuilder, request) -> {
ConfigChangeNotifyRequest configChangeNotifyRequest =
(ConfigChangeNotifyRequest) request;
attributesBuilder.put(
NacosClientConstants.NACOS_DATA_ID_ATTR, configChangeNotifyRequest.getDataId());
attributesBuilder.put(
NacosClientConstants.NACOS_GROUP_ATTR, configChangeNotifyRequest.getGroup());
attributesBuilder.put(
NacosClientConstants.NACOS_TENANT_ATTR, configChangeNotifyRequest.getTenant());
}));
}

@Nonnull
public static NacosClientRequestOperator getOperator(@Nonnull Request request) {
NacosClientRequestOperator nacosClientRequestOperator =
KNOWN_OPERATOR_MAP.get(request.getClass());
if (nacosClientRequestOperator != null) {
return nacosClientRequestOperator;
}
return UNKNOWN_OPERATOR;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.instrumentation.nacos.client.v2_0_0;

import static java.util.Arrays.asList;

import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.instrumentation.nacos.client.v2_0_0.instrumentations.GrpcConnectionInstrumentation;
import io.opentelemetry.javaagent.instrumentation.nacos.client.v2_0_0.instrumentations.RpcClientInstrumentation;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.util.List;

@AutoService(InstrumentationModule.class)
public class NacosClientInstrumentationModule extends InstrumentationModule {
public NacosClientInstrumentationModule() {
super("nacos-client", "nacos-client-2.0.0");
}

@Override
public List<TypeInstrumentation> typeInstrumentations() {
return asList(new GrpcConnectionInstrumentation(), new RpcClientInstrumentation());
}

@Override
public boolean defaultEnabled(ConfigProperties config) {
return false;
}
}
Loading
Loading