Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c54f287
Add support gRPC 1.60.x and 1.70.x server interceptor trace
huicunjun Jul 25, 2025
fe5cd51
Add support gRPC 1.60.x and 1.70.x server interceptor trace
huicunjun Jul 25, 2025
0c88fa9
Add case
huicunjun Jul 26, 2025
7288e2e
keep grpc old version
huicunjun Jul 26, 2025
89206ee
Update Docs
huicunjun Jul 26, 2025
956c9a5
Fix
huicunjun Jul 26, 2025
4551e27
Fix
huicunjun Jul 26, 2025
cd4bf58
Add case
huicunjun Jul 26, 2025
5a0b960
Update plugins-test.0.yaml
huicunjun Jul 26, 2025
fa3ff02
Update expectedData.yaml
huicunjun Jul 26, 2025
0f3dc3c
Update test case
huicunjun Jul 26, 2025
0653a43
Update test case
huicunjun Jul 26, 2025
9677d03
Update grpc test case 1.50.0 -> 1.73.0
huicunjun Jul 27, 2025
29a1f0a
Remove grpc-1.60.x-1.70.x-scenario
huicunjun Jul 27, 2025
303ffd4
Note enhancement points
huicunjun Jul 27, 2025
611071a
Fix Repeat Add trace interceptor
huicunjun Jul 28, 2025
3b5f02f
Add Field Cache
huicunjun Jul 28, 2025
bd35702
only support grpc 1.59-1.70.x
huicunjun Jul 28, 2025
22b38a6
only support grpc 1.59-1.70.x
huicunjun Jul 28, 2025
3e9fd79
Add grpc 1.26.0->1.58.0 test case
huicunjun Jul 28, 2025
797d850
fix code style
huicunjun Jul 28, 2025
d0ed0a7
fix code style 2
huicunjun Jul 28, 2025
5dd664e
reset old grpc case
huicunjun Jul 28, 2025
a6b609f
Add grpc 1.30.0 -> 1.58.0
huicunjun Jul 28, 2025
13fa3d4
Add grpc 1.30.0 -> 1.58.0
huicunjun Jul 28, 2025
0b3f5a0
Add grpc 1.30.0 -> 1.39.0
huicunjun Jul 28, 2025
1975779
Add grpc 1.30.0 -> 1.39.0
huicunjun Jul 28, 2025
fafe941
Update CHANGES.md
huicunjun Jul 28, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/plugins-test.0.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ jobs:
- gateway-2.1.x-scenario
- gateway-2.0.x-scenario
- grpc-scenario
- grpc-1.59.x-1.70.x-scenario
- grpc-1.30.x-1.39.x-scenario
- gson-scenario
- guava-cache-scenario
- elasticjob-3.x-scenario
Expand Down
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Release Notes.
* Fix RabbitMQ Consumer could not receive handleCancelOk callback.
* Support for tracking in lettuce versions 6.5.x and above.
* Upgrade byte-buddy version to 1.17.6.
* Support gRPC 1.59.x and 1.70.x server interceptor trace

All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/236?closed=1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
import org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch;

import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesNoArguments;
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;

public class AbstractServerImplBuilderInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

public static final String ENHANCE_CLASS = "io.grpc.internal.AbstractServerImplBuilder";
public static final String ENHANCE_METHOD = "build";
public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.grpc.v1.server.AbstractServerImplBuilderInterceptor";

Expand Down Expand Up @@ -64,6 +63,9 @@ public boolean isOverrideArgs() {

@Override
protected ClassMatch enhanceClass() {
return byName(ENHANCE_CLASS);
return MultiClassNameMatch.byMultiClassMatch(
"io.grpc.internal.AbstractServerImplBuilder", //grpc version <= 1.58.1
"io.grpc.internal.ServerImplBuilder" //grpc version >= 1.59.0
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@

import io.grpc.ServerBuilder;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
Expand All @@ -30,14 +34,26 @@
* {@link AbstractServerImplBuilderInterceptor} add the {@link ServerInterceptor} interceptor for every ServerService.
*/
public class AbstractServerImplBuilderInterceptor implements InstanceMethodsAroundInterceptor {
private final static Map<Class<?>, Field> FIELD_CACHE = new HashMap<>();

@Override
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
MethodInterceptResult result) {
MethodInterceptResult result) throws Throwable {
if (objInst.getSkyWalkingDynamicField() == null) {
ServerBuilder<?> builder = (ServerBuilder) objInst;
ServerInterceptor interceptor = new ServerInterceptor();
builder.intercept(interceptor);
objInst.setSkyWalkingDynamicField(interceptor);
Field field = findField(builder.getClass());
if (field != null) {
List<?> interceptors = (List<?>) field.get(builder);
boolean hasCustomInterceptor = interceptors.stream()
.anyMatch(i -> i.getClass() == ServerInterceptor.class);

if (!hasCustomInterceptor) {
ServerInterceptor interceptor = new ServerInterceptor();
builder.intercept(interceptor);
objInst.setSkyWalkingDynamicField(interceptor);
}

}
}
}

Expand All @@ -52,4 +68,31 @@ public void handleMethodException(EnhancedInstance objInst, Method method, Objec
Class<?>[] argumentsTypes, Throwable t) {

}

private static Field findField(Class<?> clazz) {
if (FIELD_CACHE.containsKey(clazz)) {
return FIELD_CACHE.get(clazz);
}
synchronized (AbstractServerImplBuilderInterceptor.class) {
if (FIELD_CACHE.containsKey(clazz)) {
return FIELD_CACHE.get(clazz);
}
Field field = doFindField(clazz);
FIELD_CACHE.put(clazz, field);
return field;
}
}

private static Field doFindField(Class<?> clazz) {
while (clazz != null) {
for (Field f : clazz.getDeclaredFields()) {
if (f.getName().equals("interceptors")) {
f.setAccessible(true);
return f;
}
}
clazz = clazz.getSuperclass();
}
return null;
}
}
21 changes: 21 additions & 0 deletions test/plugin/scenarios/grpc-1.30.x-1.39.x-scenario/bin/startup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
#
# 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.

home="$(cd "$(dirname $0)"; pwd)"

java -jar ${agent_opts} ${home}/../libs/grpc-1.30.x-1.39.x-scenario.jar &
Loading
Loading