Skip to content

Commit 02dad13

Browse files
authored
Support forkjoinpool plugin (#505)
1 parent e08c458 commit 02dad13

22 files changed

Lines changed: 804 additions & 0 deletions

File tree

.github/workflows/plugins-test.3.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ jobs:
101101
- guava-eventbus-scenario
102102
- shenyu-2.4.x-scenario
103103
- jdk-threadpool-scenario
104+
- jdk-forkjoinpool-scenario
104105
- shenyu-2.4.x-dubbo-scenario
105106
- grpc-generic-call-scenario
106107
- shenyu-2.4.x-grpc-scenario

CHANGES.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Release Notes.
66
------------------
77

88
* Exclude `synthetic` methods for the WitnessMethod mechanism
9+
* Support ForkJoinPool trace
910

1011
#### Documentation
1112

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<!--
2+
~ Licensed to the Apache Software Foundation (ASF) under one or more
3+
~ contributor license agreements. See the NOTICE file distributed with
4+
~ this work for additional information regarding copyright ownership.
5+
~ The ASF licenses this file to You under the Apache License, Version 2.0
6+
~ (the "License"); you may not use this file except in compliance with
7+
~ the License. You may obtain a copy of the License at
8+
~
9+
~ http://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
~
17+
-->
18+
19+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
20+
<parent>
21+
<groupId>org.apache.skywalking</groupId>
22+
<artifactId>bootstrap-plugins</artifactId>
23+
<version>8.16.0-SNAPSHOT</version>
24+
</parent>
25+
<modelVersion>4.0.0</modelVersion>
26+
27+
<artifactId>apm-jdk-forkjoinpool-plugin</artifactId>
28+
<packaging>jar</packaging>
29+
30+
<name>apm-jdk-forkjoinpool-plugin</name>
31+
<url>http://maven.apache.org</url>
32+
33+
<properties>
34+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
35+
</properties>
36+
37+
38+
<build>
39+
<plugins>
40+
<plugin>
41+
<artifactId>maven-deploy-plugin</artifactId>
42+
</plugin>
43+
<!-- Ignore the error of javadoc build -->
44+
<plugin>
45+
<groupId>org.apache.maven.plugins</groupId>
46+
<artifactId>maven-javadoc-plugin</artifactId>
47+
<executions>
48+
<execution>
49+
<id>attach-javadocs</id>
50+
<goals>
51+
<goal>jar</goal>
52+
</goals>
53+
</execution>
54+
</executions>
55+
<configuration>
56+
<failOnError>false</failOnError>
57+
</configuration>
58+
</plugin>
59+
<!-- Build a dummy(empty) javadoc to satisfy maven central requirements -->
60+
<plugin>
61+
<groupId>org.apache.maven.plugins</groupId>
62+
<artifactId>maven-jar-plugin</artifactId>
63+
<executions>
64+
<execution>
65+
<id>empty-javadoc-jar</id>
66+
<phase>package</phase>
67+
<goals>
68+
<goal>jar</goal>
69+
</goals>
70+
<configuration>
71+
<classifier>javadoc</classifier>
72+
<classesDirectory>${basedir}/javadoc</classesDirectory>
73+
</configuration>
74+
</execution>
75+
</executions>
76+
</plugin>
77+
</plugins>
78+
</build>
79+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.jdk.forkjoinpool;
20+
21+
import org.apache.skywalking.apm.agent.core.context.ContextManager;
22+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
23+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
24+
25+
public class ForkJoinTaskConstructorInterceptor implements InstanceConstructorInterceptor {
26+
27+
@Override
28+
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable {
29+
if (ContextManager.isActive()) {
30+
objInst.setSkyWalkingDynamicField(ContextManager.capture());
31+
}
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.jdk.forkjoinpool;
20+
21+
import java.lang.reflect.Method;
22+
import org.apache.skywalking.apm.agent.core.context.ContextManager;
23+
import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
24+
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
25+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
26+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.InstanceMethodsAroundInterceptorV2;
27+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.MethodInvocationContext;
28+
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
29+
30+
public class ForkJoinWorkerQueueMethodInterceptor implements InstanceMethodsAroundInterceptorV2 {
31+
32+
@Override
33+
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
34+
MethodInvocationContext context) throws Throwable {
35+
AbstractSpan span = ContextManager.createLocalSpan(generateOperationName(objInst, method));
36+
span.setComponent(ComponentsDefine.JDK_THREADING);
37+
context.setContext(span);
38+
EnhancedInstance forkJoinTask = (EnhancedInstance) allArguments[0];
39+
if (forkJoinTask != null) {
40+
final Object storedField = forkJoinTask.getSkyWalkingDynamicField();
41+
if (storedField != null) {
42+
final ContextSnapshot contextSnapshot = (ContextSnapshot) storedField;
43+
ContextManager.continued(contextSnapshot);
44+
}
45+
}
46+
}
47+
48+
@Override
49+
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
50+
Object ret, MethodInvocationContext context) throws Throwable {
51+
AbstractSpan span = (AbstractSpan) context.getContext();
52+
if (span != null) {
53+
ContextManager.stopSpan(span);
54+
}
55+
return ret;
56+
}
57+
58+
@Override
59+
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
60+
Class<?>[] argumentsTypes, Throwable t, MethodInvocationContext context) {
61+
AbstractSpan span = (AbstractSpan) context.getContext();
62+
if (span != null) {
63+
span.log(t);
64+
}
65+
}
66+
67+
private String generateOperationName(final EnhancedInstance objInst, final Method method) {
68+
return "ForkJoinPool/" + objInst.getClass().getName() + "/" + method.getName();
69+
}
70+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.jdk.forkjoinpool.define;
20+
21+
import static net.bytebuddy.matcher.ElementMatchers.any;
22+
23+
import net.bytebuddy.description.method.MethodDescription;
24+
import net.bytebuddy.matcher.ElementMatcher;
25+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
26+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
27+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
28+
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
29+
import org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch;
30+
31+
public class ForkJoinTaskInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
32+
33+
private static final String FORK_JOIN_TASK_CLASS = "java.util.concurrent.ForkJoinTask";
34+
private static final String FORK_JOIN_TASK_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdk.forkjoinpool.ForkJoinTaskConstructorInterceptor";
35+
36+
@Override
37+
protected ClassMatch enhanceClass() {
38+
return HierarchyMatch.byHierarchyMatch(FORK_JOIN_TASK_CLASS);
39+
}
40+
41+
@Override
42+
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
43+
return new ConstructorInterceptPoint[]{
44+
new ConstructorInterceptPoint() {
45+
@Override
46+
public ElementMatcher<MethodDescription> getConstructorMatcher() {
47+
return any();
48+
}
49+
50+
@Override
51+
public String getConstructorInterceptor() {
52+
return FORK_JOIN_TASK_INTERCEPTOR;
53+
}
54+
}
55+
};
56+
}
57+
58+
@Override
59+
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
60+
return new InstanceMethodsInterceptPoint[0];
61+
}
62+
63+
@Override
64+
public boolean isBootstrapInstrumentation() {
65+
return true;
66+
}
67+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.jdk.forkjoinpool.define;
20+
21+
import static net.bytebuddy.matcher.ElementMatchers.named;
22+
23+
import net.bytebuddy.description.method.MethodDescription;
24+
import net.bytebuddy.matcher.ElementMatcher;
25+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
26+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.v2.ClassInstanceMethodsEnhancePluginDefineV2;
27+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.v2.InstanceMethodsInterceptV2Point;
28+
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
29+
import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch;
30+
31+
public class ForkJoinWorkerQueueInstrumentation extends ClassInstanceMethodsEnhancePluginDefineV2 {
32+
33+
private static final String FORK_JOIN_WORKER_QUEUE_CLASS = "java.util.concurrent.ForkJoinPool$WorkQueue";
34+
35+
private static final String FORK_JOIN_WORKER_QUEUE_RUN_TASK_METHOD = "runTask";
36+
private static final String FORK_JOIN_WORKER_QUEUE_RUN_TASK_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdk.forkjoinpool.ForkJoinWorkerQueueMethodInterceptor";
37+
38+
@Override
39+
protected ClassMatch enhanceClass() {
40+
return NameMatch.byName(FORK_JOIN_WORKER_QUEUE_CLASS);
41+
}
42+
43+
@Override
44+
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
45+
return new ConstructorInterceptPoint[0];
46+
}
47+
48+
@Override
49+
public InstanceMethodsInterceptV2Point[] getInstanceMethodsInterceptV2Points() {
50+
return new InstanceMethodsInterceptV2Point[]{
51+
new InstanceMethodsInterceptV2Point() {
52+
@Override
53+
public ElementMatcher<MethodDescription> getMethodsMatcher() {
54+
return named(FORK_JOIN_WORKER_QUEUE_RUN_TASK_METHOD);
55+
}
56+
57+
@Override
58+
public String getMethodsInterceptorV2() {
59+
return FORK_JOIN_WORKER_QUEUE_RUN_TASK_METHOD_INTERCEPTOR;
60+
}
61+
62+
@Override
63+
public boolean isOverrideArgs() {
64+
return false;
65+
}
66+
}
67+
};
68+
}
69+
70+
@Override
71+
public boolean isBootstrapInstrumentation() {
72+
return true;
73+
}
74+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
jdk-forkjoinpool-plugin=org.apache.skywalking.apm.plugin.jdk.forkjoinpool.define.ForkJoinTaskInstrumentation
18+
jdk-forkjoinpool-plugin=org.apache.skywalking.apm.plugin.jdk.forkjoinpool.define.ForkJoinWorkerQueueInstrumentation
19+

apm-sniffer/bootstrap-plugins/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
<module>jdk-http-plugin</module>
4646
<module>jdk-threading-plugin</module>
4747
<module>jdk-threadpool-plugin</module>
48+
<module>jdk-forkjoinpool-plugin</module>
4849
</modules>
4950

5051
<dependencies>

docs/en/setup/service-agent/java-agent/Bootstrap-plugins.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Now, we have the following known bootstrap plugins.
66
* Plugin of JDK HttpURLConnection. Agent is compatible with JDK 1.8+
77
* Plugin of JDK Callable and Runnable. Agent is compatible with JDK 1.8+
88
* Plugin of JDK ThreadPoolExecutor. Agent is compatible with JDK 1.8+
9+
* Plugin of JDK ForkJoinPool. Agent is compatible with JDK 1.8+
910

1011
### HttpURLConnection Plugin Notice
1112
The plugin of JDK HttpURLConnection depended on `sun.net.*`. When using Java 9+, You should add some JVM options as follows:

0 commit comments

Comments
 (0)