Skip to content

Commit 7859038

Browse files
fangxiu-wfCopilotsteveraotrasklaurit
authored
feat: Add support for SOFARPC framework (#15589)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Steve Rao <raozihao.rzh@alibaba-inc.com> Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com> Co-authored-by: Lauri Tulmin <ltulmin@splunk.com>
1 parent 24e3507 commit 7859038

41 files changed

Lines changed: 2845 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.fossa.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,15 @@ targets:
277277
- type: gradle
278278
path: ./
279279
target: ':instrumentation:scala-forkjoin-2.8:javaagent'
280+
- type: gradle
281+
path: ./
282+
target: ':instrumentation:sofa-rpc-5.4:javaagent'
283+
- type: gradle
284+
path: ./
285+
target: ':instrumentation:sofa-rpc-5.4:library'
286+
- type: gradle
287+
path: ./
288+
target: ':instrumentation:sofa-rpc-5.4:library-autoconfigure'
280289
- type: gradle
281290
path: ./
282291
target: ':instrumentation:spark-2.3:javaagent'

.github/config/latest-dep-versions.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
"co.elastic.clients:elasticsearch-java#+": "9.4.2",
66
"co.elastic.clients:elasticsearch-java#8.9.+": "8.9.2",
77
"com.alibaba:druid#+": "1.2.28",
8+
"com.alipay.sofa:sofa-rpc-all#+": "5.13.5",
89
"com.amazonaws:aws-java-sdk-core#+": "1.12.797",
910
"com.amazonaws:aws-java-sdk-dynamodb#+": "1.12.797",
1011
"com.amazonaws:aws-java-sdk-ec2#+": "1.12.797",

.github/scripts/instrumentations.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,7 @@ readonly INSTRUMENTATIONS=(
257257
"servlet:servlet-2.2:javaagent:test"
258258
"servlet:servlet-3.0:javaagent-testing:test"
259259
"servlet:servlet-5.0:jetty12-testing:test"
260+
"sofa-rpc-5.4:javaagent:testSofaRpc"
260261
"spring:spring-batch-3.0:javaagent:test"
261262
"spring:spring-batch-3.0:javaagent:testExperimental"
262263
"spring:spring-data:spring-data-1.8:javaagent:test"

docs/supported-libraries.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ These are the supported libraries and frameworks:
139139
| [RxJava](https://github.com/ReactiveX/RxJava) | 1.0+ | [opentelemetry-rxjava-1.0](../instrumentation/rxjava/rxjava-1.0/library),<br>[opentelemetry-rxjava-2.0](../instrumentation/rxjava/rxjava-2.0/library),<br>[opentelemetry-rxjava-3.0](../instrumentation/rxjava/rxjava-3.0/library),<br>[opentelemetry-rxjava-3.1.1](../instrumentation/rxjava/rxjava-3.1.1/library) | Context propagation |
140140
| [Scala ForkJoinPool](https://www.scala-lang.org/api/2.12.0/scala/concurrent/forkjoin/package$$ForkJoinPool$.html) | 2.8+ | N/A | Context propagation |
141141
| [Servlet](https://javaee.github.io/javaee-spec/javadocs/javax/servlet/package-summary.html) | 2.2+ | [opentelemetry-servlet-3.0](../instrumentation/servlet/servlet-3.0/library),<br>[opentelemetry-servlet-5.0](../instrumentation/servlet/servlet-5.0/library) | [HTTP Server Spans], [HTTP Server Metrics] |
142+
| [SOFARPC](https://github.com/sofastack/sofa-rpc/) | 5.4+ | [opentelemetry-sofa-rpc-5.4](../instrumentation/sofa-rpc-5.4/library),<br>[opentelemetry-sofa-rpc-5.4-autoconfigure](../instrumentation/sofa-rpc-5.4/library-autoconfigure) | [RPC Client Spans], [RPC Client Metrics], [RPC Server Spans], [RPC Server Metrics] |
142143
| [Spark Web Framework](https://github.com/perwendel/spark) | 2.3+ | N/A | Provides `http.route` [2] |
143144
| [Spring Batch](https://spring.io/projects/spring-batch) | 3.0+ (not including 5.0+ yet) | N/A | none |
144145
| [Spring Boot](https://spring.io/projects/spring-boot) | | [opentelemetry-spring-boot-resources](https://opentelemetry.io/docs/zero-code/java/spring-boot/) | none |
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
plugins {
2+
id("otel.javaagent-instrumentation")
3+
}
4+
5+
muzzle {
6+
pass {
7+
group.set("com.alipay.sofa")
8+
module.set("sofa-rpc-all")
9+
versions.set("[5.4.0,)")
10+
assertInverse.set(true)
11+
}
12+
}
13+
14+
dependencies {
15+
implementation(project(":instrumentation:sofa-rpc-5.4:library"))
16+
17+
library("com.alipay.sofa:sofa-rpc-all:5.4.0")
18+
}
19+
20+
testing {
21+
suites {
22+
val testSofaRpc by registering(JvmTestSuite::class) {
23+
dependencies {
24+
implementation(project(":instrumentation:sofa-rpc-5.4:testing"))
25+
implementation("com.alipay.sofa:sofa-rpc-all:${baseVersion("5.4.0").orLatest()}")
26+
}
27+
}
28+
}
29+
}
30+
31+
tasks.withType<Test>().configureEach {
32+
systemProperty("testLatestDeps", otelProps.testLatestDeps)
33+
jvmArgs("-XX:+IgnoreUnrecognizedVMOptions")
34+
// required on jdk17
35+
jvmArgs("--add-opens=java.base/java.lang=ALL-UNNAMED")
36+
37+
systemProperty("collectMetadata", otelProps.collectMetadata)
38+
}
39+
40+
val stableSemconvSuites = testing.suites.withType(JvmTestSuite::class).map { suite ->
41+
tasks.register<Test>("${suite.name}StableSemconv") {
42+
testClassesDirs = suite.sources.output.classesDirs
43+
classpath = suite.sources.runtimeClasspath
44+
45+
jvmArgs("-Dotel.semconv-stability.opt-in=rpc,service.peer")
46+
systemProperty("metadataConfig", "otel.semconv-stability.opt-in=rpc,service.peer")
47+
}
48+
}
49+
50+
val bothSemconvSuites = testing.suites.withType(JvmTestSuite::class).map { suite ->
51+
tasks.register<Test>("${suite.name}BothSemconv") {
52+
testClassesDirs = suite.sources.output.classesDirs
53+
classpath = suite.sources.runtimeClasspath
54+
55+
jvmArgs("-Dotel.semconv-stability.opt-in=rpc/dup,service.peer")
56+
systemProperty("metadataConfig", "otel.semconv-stability.opt-in=rpc/dup,service.peer")
57+
}
58+
}
59+
60+
tasks {
61+
check {
62+
dependsOn(testing.suites, stableSemconvSuites, bothSemconvSuites)
63+
}
64+
}
65+
66+
configurations.named("testSofaRpcRuntimeClasspath") {
67+
resolutionStrategy {
68+
// requires old logback (and therefore also old slf4j)
69+
force("ch.qos.logback:logback-classic:1.2.13")
70+
force("ch.qos.logback:logback-core:1.2.13")
71+
force("org.slf4j:slf4j-api:1.7.21")
72+
}
73+
}
74+
75+
if (otelProps.denyUnsafe) {
76+
tasks.withType<Test>().configureEach {
77+
enabled = false
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.sofarpc.v5_4;
7+
8+
import com.alipay.sofa.rpc.config.ConsumerConfig;
9+
import com.alipay.sofa.rpc.core.request.SofaRequest;
10+
import com.alipay.sofa.rpc.core.response.SofaResponse;
11+
import com.alipay.sofa.rpc.ext.Extension;
12+
import com.alipay.sofa.rpc.filter.AutoActive;
13+
import com.alipay.sofa.rpc.filter.Filter;
14+
import com.alipay.sofa.rpc.filter.FilterInvoker;
15+
16+
@Extension(value = "openTelemetryClient", order = -25000)
17+
@AutoActive(consumerSide = true)
18+
public class OpenTelemetryClientFilter extends Filter {
19+
20+
private final Filter delegate;
21+
22+
public OpenTelemetryClientFilter() {
23+
delegate = SofaRpcSingletons.clientFilter();
24+
}
25+
26+
@Override
27+
public SofaResponse invoke(FilterInvoker invoker, SofaRequest request) {
28+
return delegate.invoke(invoker, request);
29+
}
30+
31+
@Override
32+
// Suppress rawtypes warning: SOFARPC Filter interface uses raw ConsumerConfig type
33+
@SuppressWarnings("rawtypes")
34+
public void onAsyncResponse(
35+
ConsumerConfig config, SofaRequest request, SofaResponse response, Throwable exception) {
36+
delegate.onAsyncResponse(config, request, response, exception);
37+
}
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.sofarpc.v5_4;
7+
8+
import com.alipay.sofa.rpc.core.request.SofaRequest;
9+
import com.alipay.sofa.rpc.core.response.SofaResponse;
10+
import com.alipay.sofa.rpc.ext.Extension;
11+
import com.alipay.sofa.rpc.filter.AutoActive;
12+
import com.alipay.sofa.rpc.filter.Filter;
13+
import com.alipay.sofa.rpc.filter.FilterInvoker;
14+
15+
@Extension(value = "openTelemetryServer", order = -25000)
16+
@AutoActive(providerSide = true)
17+
public class OpenTelemetryServerFilter extends Filter {
18+
19+
private final Filter delegate;
20+
21+
public OpenTelemetryServerFilter() {
22+
delegate = SofaRpcSingletons.serverFilter();
23+
}
24+
25+
@Override
26+
public SofaResponse invoke(FilterInvoker invoker, SofaRequest request) {
27+
return delegate.invoke(invoker, request);
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.sofarpc.v5_4;
7+
8+
import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed;
9+
import static java.util.Arrays.asList;
10+
import static java.util.Collections.singletonList;
11+
import static net.bytebuddy.matcher.ElementMatchers.named;
12+
13+
import com.google.auto.service.AutoService;
14+
import io.opentelemetry.javaagent.extension.instrumentation.HelperResourceBuilder;
15+
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
16+
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
17+
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
18+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
19+
import java.util.List;
20+
import net.bytebuddy.description.type.TypeDescription;
21+
import net.bytebuddy.matcher.ElementMatcher;
22+
23+
@AutoService(InstrumentationModule.class)
24+
public class SofaRpcInstrumentationModule extends InstrumentationModule
25+
implements ExperimentalInstrumentationModule {
26+
public SofaRpcInstrumentationModule() {
27+
super("sofa-rpc", "sofa-rpc-5.4");
28+
}
29+
30+
@Override
31+
public void registerHelperResources(HelperResourceBuilder helperResourceBuilder) {
32+
helperResourceBuilder.register(
33+
"META-INF/services/com.alipay.sofa.rpc.filter.Filter",
34+
"sofa-rpc-5.4/META-INF/com.alipay.sofa.rpc.filter.Filter");
35+
}
36+
37+
@Override
38+
public ElementMatcher.Junction<ClassLoader> classLoaderMatcher() {
39+
// added in 5.4.0
40+
return hasClassesNamed("com.alipay.sofa.rpc.transport.ClientHandler");
41+
}
42+
43+
@Override
44+
public List<String> exposedClassNames() {
45+
return asList(
46+
"io.opentelemetry.javaagent.instrumentation.sofarpc.v5_4.OpenTelemetryClientFilter",
47+
"io.opentelemetry.javaagent.instrumentation.sofarpc.v5_4.OpenTelemetryServerFilter");
48+
}
49+
50+
@Override
51+
public List<TypeInstrumentation> typeInstrumentations() {
52+
return singletonList(new ResourceInjectingTypeInstrumentation());
53+
}
54+
55+
// A type instrumentation is needed to trigger resource injection.
56+
private static class ResourceInjectingTypeInstrumentation implements TypeInstrumentation {
57+
@Override
58+
public ElementMatcher<TypeDescription> typeMatcher() {
59+
return named("com.alipay.sofa.rpc.ext.ExtensionLoader");
60+
}
61+
62+
@Override
63+
public void transform(TypeTransformer transformer) {
64+
// Nothing to transform, this type instrumentation is only used for injecting resources.
65+
}
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.instrumentation.sofarpc.v5_4;
7+
8+
import com.alipay.sofa.rpc.filter.Filter;
9+
import io.opentelemetry.api.GlobalOpenTelemetry;
10+
import io.opentelemetry.instrumentation.api.incubator.semconv.service.peer.ServicePeerAttributesExtractor;
11+
import io.opentelemetry.instrumentation.sofarpc.v5_4.SofaRpcTelemetry;
12+
import io.opentelemetry.instrumentation.sofarpc.v5_4.internal.SofaRpcClientNetworkAttributesGetter;
13+
14+
class SofaRpcSingletons {
15+
private static final Filter clientFilter;
16+
private static final Filter serverFilter;
17+
18+
static {
19+
SofaRpcTelemetry telemetry =
20+
SofaRpcTelemetry.builder(GlobalOpenTelemetry.get())
21+
.addAttributesExtractor(
22+
ServicePeerAttributesExtractor.create(
23+
new SofaRpcClientNetworkAttributesGetter(), GlobalOpenTelemetry.get()))
24+
.build();
25+
clientFilter = telemetry.newClientFilter();
26+
serverFilter = telemetry.newServerFilter();
27+
}
28+
29+
static Filter clientFilter() {
30+
return clientFilter;
31+
}
32+
33+
static Filter serverFilter() {
34+
return serverFilter;
35+
}
36+
37+
private SofaRpcSingletons() {}
38+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
io.opentelemetry.javaagent.instrumentation.sofarpc.v5_4.OpenTelemetryClientFilter
2+
io.opentelemetry.javaagent.instrumentation.sofarpc.v5_4.OpenTelemetryServerFilter
3+

0 commit comments

Comments
 (0)