parent
fab9ce53bd
commit
a5ccbca693
|
|
@ -98,6 +98,7 @@ jobs:
|
|||
- tomcat-thread-pool-scenario
|
||||
- guava-eventbus-scenario
|
||||
- shenyu-2.4.x-scenario
|
||||
- jdk-threadpool-scenario
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ Release Notes.
|
|||
* Make sure the parent endpoint in tracing context from existing first ENTRY span, rather than first span only.
|
||||
* Fix the bug that maybe causing memory leak and repeated traceId when use gateway-2.1.x-plugin or gateway-3.x-plugin.
|
||||
* Fix Grpc 1.x plugin could leak context due to gRPC cancelled.
|
||||
* Add JDK ThreadPoolExecutor Plugin.
|
||||
|
||||
#### Documentation
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import org.apache.skywalking.apm.agent.core.boot.AgentPackageNotFoundException;
|
|||
import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.conf.SnifferConfigInitializer;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.PluginFinder;
|
||||
import org.apache.skywalking.apm.util.StringUtil;
|
||||
|
||||
public class WriterFactory {
|
||||
|
|
@ -35,7 +36,9 @@ public class WriterFactory {
|
|||
if (WRITER != null) {
|
||||
return WRITER;
|
||||
}
|
||||
if (SnifferConfigInitializer.isInitCompleted() && AgentPackagePath.isPathFound()) {
|
||||
if (SnifferConfigInitializer.isInitCompleted()
|
||||
&& PluginFinder.isPluginInitCompleted()
|
||||
&& AgentPackagePath.isPathFound()) {
|
||||
if (StringUtil.isEmpty(Config.Logging.DIR)) {
|
||||
try {
|
||||
Config.Logging.DIR = AgentPackagePath.getPath() + "/logs";
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ public class PluginFinder {
|
|||
private final Map<String, LinkedList<AbstractClassEnhancePluginDefine>> nameMatchDefine = new HashMap<String, LinkedList<AbstractClassEnhancePluginDefine>>();
|
||||
private final List<AbstractClassEnhancePluginDefine> signatureMatchDefine = new ArrayList<AbstractClassEnhancePluginDefine>();
|
||||
private final List<AbstractClassEnhancePluginDefine> bootstrapClassMatchDefine = new ArrayList<AbstractClassEnhancePluginDefine>();
|
||||
private static boolean IS_PLUGIN_INIT_COMPLETED = false;
|
||||
|
||||
public PluginFinder(List<AbstractClassEnhancePluginDefine> plugins) {
|
||||
for (AbstractClassEnhancePluginDefine plugin : plugins) {
|
||||
|
|
@ -107,4 +108,12 @@ public class PluginFinder {
|
|||
public List<AbstractClassEnhancePluginDefine> getBootstrapClassMatchDefine() {
|
||||
return bootstrapClassMatchDefine;
|
||||
}
|
||||
|
||||
public static void pluginInitCompleted() {
|
||||
IS_PLUGIN_INIT_COMPLETED = true;
|
||||
}
|
||||
|
||||
public static boolean isPluginInitCompleted() {
|
||||
return IS_PLUGIN_INIT_COMPLETED;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ package org.apache.skywalking.apm.agent.core.logging.core;
|
|||
import org.apache.skywalking.apm.agent.core.boot.AgentPackagePath;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.conf.SnifferConfigInitializer;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.PluginFinder;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.BDDMockito;
|
||||
|
|
@ -33,6 +34,7 @@ import static org.junit.Assert.assertTrue;
|
|||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest(value = {
|
||||
SnifferConfigInitializer.class,
|
||||
PluginFinder.class,
|
||||
AgentPackagePath.class
|
||||
})
|
||||
public class WriterFactoryTest {
|
||||
|
|
@ -41,11 +43,14 @@ public class WriterFactoryTest {
|
|||
public void alwaysReturnSystemLogWriteWithSetLoggingDir() {
|
||||
Config.Logging.OUTPUT = LogOutput.CONSOLE;
|
||||
PowerMockito.mockStatic(SnifferConfigInitializer.class);
|
||||
PowerMockito.mockStatic(PluginFinder.class);
|
||||
PowerMockito.mockStatic(AgentPackagePath.class);
|
||||
BDDMockito.given(SnifferConfigInitializer.isInitCompleted()).willReturn(true);
|
||||
BDDMockito.given(PluginFinder.isPluginInitCompleted()).willReturn(true);
|
||||
BDDMockito.given(AgentPackagePath.isPathFound()).willReturn(true);
|
||||
|
||||
assertTrue(SnifferConfigInitializer.isInitCompleted());
|
||||
assertTrue(PluginFinder.isPluginInitCompleted());
|
||||
assertTrue(AgentPackagePath.isPathFound());
|
||||
|
||||
IWriter logWriter = WriterFactory.getLogWriter();
|
||||
|
|
@ -56,11 +61,14 @@ public class WriterFactoryTest {
|
|||
public void returnFileWriterWriteWithBlankLoggingDir() {
|
||||
Config.Logging.OUTPUT = LogOutput.FILE;
|
||||
PowerMockito.mockStatic(SnifferConfigInitializer.class);
|
||||
PowerMockito.mockStatic(PluginFinder.class);
|
||||
PowerMockito.mockStatic(AgentPackagePath.class);
|
||||
BDDMockito.given(SnifferConfigInitializer.isInitCompleted()).willReturn(true);
|
||||
BDDMockito.given(PluginFinder.isPluginInitCompleted()).willReturn(true);
|
||||
BDDMockito.given(AgentPackagePath.isPathFound()).willReturn(true);
|
||||
|
||||
assertTrue(SnifferConfigInitializer.isInitCompleted());
|
||||
assertTrue(PluginFinder.isPluginInitCompleted());
|
||||
assertTrue(AgentPackagePath.isPathFound());
|
||||
|
||||
IWriter logWriter = WriterFactory.getLogWriter();
|
||||
|
|
|
|||
|
|
@ -130,6 +130,8 @@ public class SkyWalkingAgent {
|
|||
.with(new Listener())
|
||||
.installOn(instrumentation);
|
||||
|
||||
PluginFinder.pluginInitCompleted();
|
||||
|
||||
try {
|
||||
ServiceManager.INSTANCE.boot();
|
||||
} catch (Exception e) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
|
||||
<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">
|
||||
<parent>
|
||||
<artifactId>bootstrap-plugins</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>8.10.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>apm-jdk-threadpool-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>apm-jdk-threadpool-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public abstract class AbstractThreadingPoolInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
if (!ContextManager.isActive()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (allArguments == null || allArguments.length < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
Object argument = allArguments[0];
|
||||
|
||||
Object wrappedObject = wrap(argument);
|
||||
if (wrappedObject != null) {
|
||||
allArguments[0] = wrappedObject;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wrap the Callable or Runnable object if needed
|
||||
* @param param Callable or Runnable object
|
||||
* @return Wrapped object or null if not needed to wrap
|
||||
*/
|
||||
public abstract Object wrap(Object param);
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Object ret) throws Throwable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
|
||||
ContextManager.activeSpan().log(t);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin;
|
||||
|
||||
import org.apache.skywalking.apm.plugin.wrapper.SwRunnableWrapper;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import java.util.concurrent.RunnableFuture;
|
||||
|
||||
public class ThreadPoolExecuteMethodInterceptor extends AbstractThreadingPoolInterceptor {
|
||||
|
||||
@Override
|
||||
public Object wrap(Object param) {
|
||||
if (param instanceof SwRunnableWrapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (param instanceof RunnableFuture) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!(param instanceof Runnable)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Runnable runnable = (Runnable) param;
|
||||
return new SwRunnableWrapper(runnable, ContextManager.capture());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.plugin.wrapper.SwCallableWrapper;
|
||||
import org.apache.skywalking.apm.plugin.wrapper.SwRunnableWrapper;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class ThreadPoolSubmitMethodInterceptor extends AbstractThreadingPoolInterceptor {
|
||||
|
||||
@Override
|
||||
public Object wrap(Object param) {
|
||||
if (param instanceof SwRunnableWrapper || param instanceof SwCallableWrapper) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (param instanceof Callable) {
|
||||
Callable callable = (Callable) param;
|
||||
return new SwCallableWrapper(callable, ContextManager.capture());
|
||||
}
|
||||
|
||||
if (param instanceof Runnable) {
|
||||
Runnable runnable = (Runnable) param;
|
||||
return new SwRunnableWrapper(runnable, ContextManager.capture());
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.define;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
|
||||
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.HierarchyMatch;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.logical.LogicalMatchOperation;
|
||||
|
||||
public class ThreadPoolExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String ENHANCE_CLASS = "java.util.concurrent.ThreadPoolExecutor";
|
||||
|
||||
private static final String INTERCEPT_EXECUTE_METHOD = "execute";
|
||||
|
||||
private static final String INTERCEPT_SUBMIT_METHOD = "submit";
|
||||
|
||||
private static final String INTERCEPT_EXECUTE_METHOD_HANDLE = "org.apache.skywalking.apm.plugin.ThreadPoolExecuteMethodInterceptor";
|
||||
|
||||
private static final String INTERCEPT_SUBMIT_METHOD_HANDLE = "org.apache.skywalking.apm.plugin.ThreadPoolSubmitMethodInterceptor";
|
||||
|
||||
@Override
|
||||
public boolean isBootstrapInstrumentation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return LogicalMatchOperation.or(HierarchyMatch.byHierarchyMatch(ENHANCE_CLASS), MultiClassNameMatch.byMultiClassMatch(ENHANCE_CLASS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return ElementMatchers.named(INTERCEPT_EXECUTE_METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_EXECUTE_METHOD_HANDLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return true;
|
||||
}
|
||||
},
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return ElementMatchers.named(INTERCEPT_SUBMIT_METHOD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPT_SUBMIT_METHOD_HANDLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.wrapper;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class SwCallableWrapper implements Callable {
|
||||
|
||||
private Callable callable;
|
||||
|
||||
private ContextSnapshot contextSnapshot;
|
||||
|
||||
public SwCallableWrapper(Callable callable, ContextSnapshot contextSnapshot) {
|
||||
this.callable = callable;
|
||||
this.contextSnapshot = contextSnapshot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object call() throws Exception {
|
||||
AbstractSpan span = ContextManager.createLocalSpan(getOperationName());
|
||||
span.setComponent(ComponentsDefine.JDK_THREADING);
|
||||
ContextManager.continued(contextSnapshot);
|
||||
try {
|
||||
return callable.call();
|
||||
} finally {
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
}
|
||||
|
||||
private String getOperationName() {
|
||||
return "SwCallableWrapper/" + Thread.currentThread().getName();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.wrapper;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
|
||||
public class SwRunnableWrapper implements Runnable {
|
||||
|
||||
private Runnable runnable;
|
||||
|
||||
private ContextSnapshot contextSnapshot;
|
||||
|
||||
public SwRunnableWrapper(Runnable runnable, ContextSnapshot contextSnapshot) {
|
||||
this.runnable = runnable;
|
||||
this.contextSnapshot = contextSnapshot;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AbstractSpan span = ContextManager.createLocalSpan(getOperationName());
|
||||
span.setComponent(ComponentsDefine.JDK_THREADING);
|
||||
ContextManager.continued(contextSnapshot);
|
||||
try {
|
||||
runnable.run();
|
||||
} finally {
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
}
|
||||
|
||||
private String getOperationName() {
|
||||
return "SwRunnableWrapper/" + Thread.currentThread().getName();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
jdk-threadpool-plugin=org.apache.skywalking.apm.plugin.define.ThreadPoolExecutorInstrumentation
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
<modules>
|
||||
<module>jdk-http-plugin</module>
|
||||
<module>jdk-threading-plugin</module>
|
||||
<module>jdk-threadpool-plugin</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
|||
|
|
@ -4,4 +4,5 @@ For using these plugins, you need to put the target plugin jar file into `/plugi
|
|||
|
||||
Now, we have the following known bootstrap plugins.
|
||||
* Plugin of JDK HttpURLConnection. Agent is compatible with JDK 1.8+
|
||||
* Plugin of JDK Callable and Runnable. Agent is compatible with JDK 1.8+
|
||||
* Plugin of JDK Callable and Runnable. Agent is compatible with JDK 1.8+
|
||||
* Plugin of JDK ThreadPoolExecutor. Agent is compatible with JDK 1.8+
|
||||
|
|
@ -137,3 +137,4 @@
|
|||
- tomcat-thread-pool
|
||||
- guava-eventbus
|
||||
- shenyu-2.4.x
|
||||
- jdk-threadpool-plugin
|
||||
|
|
|
|||
|
|
@ -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/jdk-threadpool-scenario.jar &
|
||||
|
|
@ -0,0 +1,372 @@
|
|||
# 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.
|
||||
segmentItems:
|
||||
- serviceName: jdk-threadpool-scenario
|
||||
segmentSize: ge 14
|
||||
segments:
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: GET:/threadpool
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
refs:
|
||||
- {parentEndpoint: SwRunnableWrapper/http-get-thread, networkAddress: 'localhost:8080',
|
||||
refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /threadpool
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 13
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: localhost:8080
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
- operationName: SwRunnableWrapper/http-get-thread
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Unknown
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 80
|
||||
isError: false
|
||||
spanType: Local
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
refs:
|
||||
- {parentEndpoint: 'GET:/greet/{username}', networkAddress: '', refType: CrossThread,
|
||||
parentSpanId: 0, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: GET:/threadpool
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
refs:
|
||||
- {parentEndpoint: SwCallableWrapper/http-get-thread, networkAddress: 'localhost:8080',
|
||||
refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /threadpool
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 13
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: localhost:8080
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
- operationName: SwCallableWrapper/http-get-thread
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Unknown
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 80
|
||||
isError: false
|
||||
spanType: Local
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
refs:
|
||||
- {parentEndpoint: 'GET:/greet/{username}', networkAddress: '', refType: CrossThread,
|
||||
parentSpanId: 0, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: GET:/threadpool
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
refs:
|
||||
- {parentEndpoint: SwRunnableWrapper/http-get-thread, networkAddress: 'localhost:8080',
|
||||
refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /threadpool
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 13
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: localhost:8080
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
- operationName: SwRunnableWrapper/http-get-thread
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Unknown
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 80
|
||||
isError: false
|
||||
spanType: Local
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
refs:
|
||||
- {parentEndpoint: 'GET:/greet/{username}', networkAddress: '', refType: CrossThread,
|
||||
parentSpanId: 0, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /threadpool
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 13
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: localhost:8080
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
- operationName: SwRunnableWrapper/http-get-thread
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Unknown
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 80
|
||||
isError: false
|
||||
spanType: Local
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
refs:
|
||||
- {parentEndpoint: 'GET:/greet/{username}', networkAddress: '', refType: CrossThread,
|
||||
parentSpanId: 0, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: GET:/threadpool
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
refs:
|
||||
- {parentEndpoint: SwCallableWrapper/http-get-thread, networkAddress: 'localhost:8080',
|
||||
refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: GET:/threadpool
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
refs:
|
||||
- {parentEndpoint: SwRunnableWrapper/http-get-thread, networkAddress: 'localhost:8080',
|
||||
refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /threadpool
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 13
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: localhost:8080
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
- operationName: SwCallableWrapper/http-get-thread
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Unknown
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 80
|
||||
isError: false
|
||||
spanType: Local
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
refs:
|
||||
- {parentEndpoint: 'GET:/greet/{username}', networkAddress: '', refType: CrossThread,
|
||||
parentSpanId: 0, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /threadpool
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 13
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: localhost:8080
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
- operationName: SwRunnableWrapper/http-get-thread
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Unknown
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 80
|
||||
isError: false
|
||||
spanType: Local
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
refs:
|
||||
- {parentEndpoint: 'GET:/greet/{username}', networkAddress: '', refType: CrossThread,
|
||||
parentSpanId: 0, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: GET:/greet/{username}
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/greet/skywalking'}
|
||||
- {key: http.method, value: GET}
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: GET:/threadpool
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
skipAnalysis: false
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/threadpool'}
|
||||
- {key: http.method, value: GET}
|
||||
refs:
|
||||
- {parentEndpoint: SwRunnableWrapper/http-get-thread, networkAddress: 'localhost:8080',
|
||||
refType: CrossProcess, parentSpanId: 1, parentTraceSegmentId: not null,
|
||||
parentServiceInstance: not null, parentService: jdk-threadpool-scenario,
|
||||
traceId: not null}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
# 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.
|
||||
|
||||
type: jvm
|
||||
entryService: http://localhost:8080/greet/skywalking
|
||||
healthCheck: http://localhost:8080/healthCheck
|
||||
runningMode: with_bootstrap
|
||||
withPlugins: apm-jdk-threadpool-plugin-*.jar
|
||||
startScript: ./bin/startup.sh
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
-->
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>jdk-threadpool-scenario</artifactId>
|
||||
<version>5.0.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
<spring.boot.version>2.1.6.RELEASE</spring.boot.version>
|
||||
</properties>
|
||||
|
||||
<name>skywalking-jdk-threadpool-scenario</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>jdk-threadpool-scenario</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.8.1</version>
|
||||
<configuration>
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>./target/</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>./bin</directory>
|
||||
<fileMode>0775</fileMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<files>
|
||||
<file>
|
||||
<source>./target/jdk-threadpool-scenario.jar</source>
|
||||
<outputDirectory>./libs</outputDirectory>
|
||||
<fileMode>0775</fileMode>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package test.apache.skywalking.apm.testcase.jdk.threading;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(Application.class, args);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
@RestController
|
||||
static class TestController {
|
||||
private final RestTemplate restTemplate;
|
||||
private final ExecutorService executorService;
|
||||
private final ExecutorService executorService2;
|
||||
|
||||
public TestController(final RestTemplate restTemplate) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.executorService = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r);
|
||||
thread.setName("http-get-thread");
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
this.executorService2 = Executors.newSingleThreadExecutor(new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread thread = new Thread(r);
|
||||
thread.setName("http-get-thread");
|
||||
return thread;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@GetMapping("/healthCheck")
|
||||
public String healthCheck() {
|
||||
return "Success";
|
||||
}
|
||||
|
||||
@GetMapping("/greet/{username}")
|
||||
public String testCase(@PathVariable final String username) throws ExecutionException, InterruptedException {
|
||||
Runnable runnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
restTemplate.getForEntity("http://localhost:8080/threadpool", String.class);
|
||||
}
|
||||
};
|
||||
|
||||
Callable callable = new Callable<String>() {
|
||||
@Override
|
||||
public String call() {
|
||||
return restTemplate.getForEntity("http://localhost:8080/threadpool", String.class).getBody();
|
||||
}
|
||||
};
|
||||
|
||||
executorService.execute(runnable);
|
||||
executorService.submit(runnable);
|
||||
executorService.submit(callable).get();
|
||||
|
||||
executorService2.execute(runnable);
|
||||
executorService2.submit(runnable);
|
||||
executorService2.submit(callable).get();
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
@GetMapping("/threadpool")
|
||||
public String threadpool() {
|
||||
return "threadpool";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# 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.
|
||||
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# 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.
|
||||
|
||||
all
|
||||
Loading…
Reference in New Issue