[Feature] Add Java agent plugin for Jdk Threading classes (#4067)
* Add Java agent plugin for Jdk Threading * Fix expected data according to changes in master * Update agent.config * Fix failed plugin test
This commit is contained in:
parent
a6d0366c22
commit
3f48790c36
|
|
@ -446,7 +446,7 @@ jobs:
|
|||
- name: Run elasticsearch-6.x-scenario 6.7.1-6.8.4 (7)
|
||||
run: bash test/plugin/run.sh elasticsearch-6.x-scenario
|
||||
|
||||
Oracle_Kafka_JdkHttp:
|
||||
Oracle_Kafka_JdkHttp_JdkThreading:
|
||||
runs-on: ubuntu-18.04
|
||||
timeout-minutes: 90
|
||||
strategy:
|
||||
|
|
@ -477,6 +477,8 @@ jobs:
|
|||
run: bash test/plugin/run.sh kafka-scenario
|
||||
- name: Run jdk http (1)
|
||||
run: bash test/plugin/run.sh jdk-http-scenario
|
||||
- name: Run jdk threading (1)
|
||||
run: bash test/plugin/run.sh jdk-threading-scenario
|
||||
|
||||
MySQL:
|
||||
runs-on: ubuntu-18.04
|
||||
|
|
|
|||
|
|
@ -149,4 +149,6 @@ public class ComponentsDefine {
|
|||
public static final OfficialComponent SPRING_TX = new OfficialComponent(78, "spring-tx");
|
||||
|
||||
public static final OfficialComponent ARMERIA = new OfficialComponent(79, "Armeria");
|
||||
|
||||
public static final OfficialComponent JDK_THREADING = new OfficialComponent(80, "JdkThreading");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -342,5 +342,16 @@ public class Config {
|
|||
*/
|
||||
public static boolean SIMPLIFY_TRANSACTION_DEFINITION_NAME = false;
|
||||
}
|
||||
|
||||
public static class JdkThreading {
|
||||
|
||||
/**
|
||||
* Threading classes ({@link java.lang.Runnable} and {@link java.util.concurrent.Callable}
|
||||
* and their subclasses, including anonymous inner classes)
|
||||
* whose name matches any one of the {@code THREADING_CLASS_PREFIXES} (splitted by ,)
|
||||
* will be instrumented
|
||||
*/
|
||||
public static String THREADING_CLASS_PREFIXES = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ package org.apache.skywalking.apm.agent.core.plugin.match;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.description.type.TypeList;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
|
@ -101,7 +102,7 @@ public class HierarchyMatch implements IndirectMatch {
|
|||
|
||||
}
|
||||
|
||||
public static ClassMatch byHierarchyMatch(String[] parentTypes) {
|
||||
public static IndirectMatch byHierarchyMatch(String... parentTypes) {
|
||||
return new HierarchyMatch(parentTypes);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.agent.core.plugin.match;
|
||||
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
|
||||
/**
|
||||
* Match classes by any one of the given {@link #prefixes}
|
||||
*
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class PrefixMatch implements IndirectMatch {
|
||||
private String[] prefixes;
|
||||
|
||||
private PrefixMatch(String... prefixes) {
|
||||
if (prefixes == null || prefixes.length == 0) {
|
||||
throw new IllegalArgumentException("prefixes argument is null or empty");
|
||||
}
|
||||
this.prefixes = prefixes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher.Junction buildJunction() {
|
||||
ElementMatcher.Junction junction = null;
|
||||
|
||||
for (String prefix : prefixes) {
|
||||
if (junction == null) {
|
||||
junction = ElementMatchers.nameStartsWith(prefix);
|
||||
} else {
|
||||
junction = junction.and(ElementMatchers.nameStartsWith(prefix));
|
||||
}
|
||||
}
|
||||
|
||||
return junction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatch(TypeDescription typeDescription) {
|
||||
for (final String prefix : prefixes) {
|
||||
if (typeDescription.getName().startsWith(prefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static PrefixMatch nameStartsWith(final String... prefixes) {
|
||||
return new PrefixMatch(prefixes);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.agent.core.plugin.match.logical;
|
||||
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.IndirectMatch;
|
||||
|
||||
/**
|
||||
* Match classes by multiple criteria with AND conjunction
|
||||
*
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class LogicalAndMatch implements IndirectMatch {
|
||||
private final IndirectMatch[] indirectMatches;
|
||||
|
||||
/**
|
||||
* Don't instantiate this class directly, use {@link LogicalMatchOperation} instead
|
||||
*
|
||||
* @param indirectMatches the matching criteria to conjunct with AND
|
||||
*/
|
||||
LogicalAndMatch(final IndirectMatch... indirectMatches) {
|
||||
this.indirectMatches = indirectMatches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher.Junction buildJunction() {
|
||||
ElementMatcher.Junction junction = null;
|
||||
|
||||
for (final IndirectMatch indirectMatch : indirectMatches) {
|
||||
if (junction == null) {
|
||||
junction = indirectMatch.buildJunction();
|
||||
} else {
|
||||
junction = junction.and(indirectMatch.buildJunction());
|
||||
}
|
||||
}
|
||||
|
||||
return junction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatch(final TypeDescription typeDescription) {
|
||||
for (final IndirectMatch indirectMatch : indirectMatches) {
|
||||
if (!indirectMatch.isMatch(typeDescription)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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.agent.core.plugin.match.logical;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.IndirectMatch;
|
||||
|
||||
/**
|
||||
* Util class to help to construct logical operations on {@link org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch}s
|
||||
*
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class LogicalMatchOperation {
|
||||
public static IndirectMatch and(final IndirectMatch... matches) {
|
||||
return new LogicalAndMatch(matches);
|
||||
}
|
||||
|
||||
public static IndirectMatch or(final IndirectMatch... matches) {
|
||||
return new LogicalOrMatch(matches);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.agent.core.plugin.match.logical;
|
||||
|
||||
import net.bytebuddy.description.type.TypeDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.IndirectMatch;
|
||||
|
||||
/**
|
||||
* Match classes by multiple criteria with OR conjunction
|
||||
*
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class LogicalOrMatch implements IndirectMatch {
|
||||
private final IndirectMatch[] indirectMatches;
|
||||
|
||||
/**
|
||||
* Don't instantiate this class directly, use {@link LogicalMatchOperation} instead
|
||||
*
|
||||
* @param indirectMatches the matching criteria to conjunct with OR
|
||||
*/
|
||||
LogicalOrMatch(final IndirectMatch... indirectMatches) {
|
||||
this.indirectMatches = indirectMatches;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementMatcher.Junction buildJunction() {
|
||||
ElementMatcher.Junction junction = null;
|
||||
|
||||
for (final IndirectMatch indirectMatch : indirectMatches) {
|
||||
if (junction == null) {
|
||||
junction = indirectMatch.buildJunction();
|
||||
} else {
|
||||
junction = junction.or(indirectMatch.buildJunction());
|
||||
}
|
||||
}
|
||||
|
||||
return junction;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isMatch(final TypeDescription typeDescription) {
|
||||
for (final IndirectMatch indirectMatch : indirectMatches) {
|
||||
if (indirectMatch.isMatch(typeDescription)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
<!--
|
||||
~ 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>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<artifactId>bootstrap-plugins</artifactId>
|
||||
<version>6.6.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>apm-jdk-threading-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>apm-jdk-threading-plugin</name>
|
||||
<description>SkyWalking Java Agent Plugin for JDK threading classes, (Runnable, Callable)</description>
|
||||
<url>https://github.com/apache/skywalking</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,64 @@
|
|||
/*
|
||||
* 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.jdk.threading;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.IndirectMatch;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.logical.LogicalMatchOperation;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.PrefixMatch;
|
||||
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.PrefixMatch.nameStartsWith;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class ThreadingConfig {
|
||||
private static final ILog LOGGER = LogManager.getLogger(ThreadingConfig.class);
|
||||
|
||||
public static IndirectMatch prefixesMatchesForJdkThreading() {
|
||||
final String jointPrefixes = Config.Plugin.JdkThreading.THREADING_CLASS_PREFIXES;
|
||||
|
||||
if (jointPrefixes == null || jointPrefixes.trim().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String[] prefixes = jointPrefixes.split(",");
|
||||
|
||||
final List<PrefixMatch> prefixMatches = new ArrayList<PrefixMatch>();
|
||||
|
||||
for (final String prefix : prefixes) {
|
||||
if (prefix.startsWith("java.") || prefix.startsWith("javax.")) {
|
||||
LOGGER.warn("prefix {} is ignored", prefix);
|
||||
continue;
|
||||
}
|
||||
prefixMatches.add(nameStartsWith(prefix));
|
||||
}
|
||||
|
||||
if (prefixMatches.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return LogicalMatchOperation.or(prefixMatches.toArray(new PrefixMatch[0]));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* 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.jdk.threading;
|
||||
|
||||
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.InstanceConstructorInterceptor;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class ThreadingConstructorInterceptor implements InstanceConstructorInterceptor {
|
||||
|
||||
@Override
|
||||
public void onConstruct(final EnhancedInstance objInst, final Object[] allArguments) {
|
||||
if (ContextManager.isActive()) {
|
||||
objInst.setSkyWalkingDynamicField(ContextManager.capture());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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.jdk.threading;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
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.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 org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class ThreadingMethodInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
@Override
|
||||
public void beforeMethod(
|
||||
final EnhancedInstance objInst,
|
||||
final Method method,
|
||||
final Object[] allArguments,
|
||||
final Class<?>[] argumentsTypes,
|
||||
final MethodInterceptResult result) {
|
||||
|
||||
AbstractSpan span = ContextManager.createLocalSpan(generateOperationName(objInst, method));
|
||||
span.setComponent(ComponentsDefine.JDK_THREADING);
|
||||
|
||||
final Object storedField = objInst.getSkyWalkingDynamicField();
|
||||
if (storedField != null) {
|
||||
final ContextSnapshot contextSnapshot = (ContextSnapshot) storedField;
|
||||
ContextManager.continued(contextSnapshot);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(
|
||||
final EnhancedInstance objInst,
|
||||
final Method method,
|
||||
final Object[] allArguments,
|
||||
final Class<?>[] argumentsTypes,
|
||||
final Object ret) {
|
||||
|
||||
final Object storedField = objInst.getSkyWalkingDynamicField();
|
||||
if (storedField != null) {
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(
|
||||
final EnhancedInstance objInst,
|
||||
final Method method,
|
||||
final Object[] allArguments,
|
||||
final Class<?>[] argumentsTypes,
|
||||
final Throwable t) {
|
||||
|
||||
if (ContextManager.isActive()) {
|
||||
ContextManager.activeSpan().errorOccurred().log(t);
|
||||
}
|
||||
}
|
||||
|
||||
private String generateOperationName(final EnhancedInstance objInst, final Method method) {
|
||||
return "Threading/" + objInst.getClass().getName() + "/" + method.getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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.jdk.threading.define;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
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.StaticMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.IndirectMatch;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.logical.LogicalMatchOperation;
|
||||
import org.apache.skywalking.apm.plugin.jdk.threading.ThreadingConfig;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.any;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch.byHierarchyMatch;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class CallableInstrumentation extends ClassEnhancePluginDefine {
|
||||
private static final String CALLABLE_CLASS = "java.util.concurrent.Callable";
|
||||
private static final String CALLABLE_CLASS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdk.threading.ThreadingConstructorInterceptor";
|
||||
|
||||
private static final String CALLABLE_CALL_METHOD = "call";
|
||||
private static final String CALLABLE_CALL_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdk.threading.ThreadingMethodInterceptor";
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
final IndirectMatch prefixMatches = ThreadingConfig.prefixesMatchesForJdkThreading();
|
||||
|
||||
if (prefixMatches == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return LogicalMatchOperation.and(prefixMatches, byHierarchyMatch(CALLABLE_CLASS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[]{
|
||||
new ConstructorInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return CALLABLE_CLASS_INTERCEPTOR;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(CALLABLE_CALL_METHOD).and(takesArguments(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return CALLABLE_CALL_METHOD_INTERCEPTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
|
||||
return new StaticMethodsInterceptPoint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBootstrapInstrumentation() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* 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.jdk.threading.define;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
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.StaticMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.IndirectMatch;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.logical.LogicalMatchOperation;
|
||||
import org.apache.skywalking.apm.plugin.jdk.threading.ThreadingConfig;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.any;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.HierarchyMatch.byHierarchyMatch;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
public class RunnableInstrumentation extends ClassEnhancePluginDefine {
|
||||
private static final String RUNNABLE_CLASS = "java.lang.Runnable";
|
||||
private static final String RUNNABLE_CLASS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdk.threading.ThreadingConstructorInterceptor";
|
||||
|
||||
private static final String RUNNABLE_RUN_METHOD = "run";
|
||||
private static final String RUNNABLE_RUN_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdk.threading.ThreadingMethodInterceptor";
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
final IndirectMatch prefixMatches = ThreadingConfig.prefixesMatchesForJdkThreading();
|
||||
|
||||
if (prefixMatches == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return LogicalMatchOperation.and(prefixMatches, byHierarchyMatch(RUNNABLE_CLASS));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[]{
|
||||
new ConstructorInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return RUNNABLE_CLASS_INTERCEPTOR;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named(RUNNABLE_RUN_METHOD).and(takesArguments(0));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return RUNNABLE_RUN_METHOD_INTERCEPTOR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() {
|
||||
return new StaticMethodsInterceptPoint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBootstrapInstrumentation() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# 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-threading-plugin=org.apache.skywalking.apm.plugin.jdk.threading.define.RunnableInstrumentation
|
||||
jdk-threading-plugin=org.apache.skywalking.apm.plugin.jdk.threading.define.CallableInstrumentation
|
||||
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
<modules>
|
||||
<module>jdk-http-plugin</module>
|
||||
<module>jdk-threading-plugin</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}
|
|||
# agent.authentication = ${SW_AGENT_AUTHENTICATION:xxxx}
|
||||
|
||||
# The max amount of spans in a single segment.
|
||||
# Through this config item, skywalking keep your application memory cost estimated.
|
||||
# Through this config item, SkyWalking keep your application memory cost estimated.
|
||||
# agent.span_limit_per_segment=${SW_AGENT_SPAN_LIMIT:300}
|
||||
|
||||
# Ignore the segments if their operation names end with these suffix.
|
||||
# agent.ignore_suffix=${SW_AGENT_IGNORE_SUFFIX:.jpg,.jpeg,.js,.css,.png,.bmp,.gif,.ico,.mp3,.mp4,.html,.svg}
|
||||
|
||||
# If true, skywalking agent will save all instrumented classes files in `/debugging` folder.
|
||||
# Skywalking team may ask for these files in order to resolve compatible problem.
|
||||
# If true, SkyWalking agent will save all instrumented classes files in `/debugging` folder.
|
||||
# SkyWalking team may ask for these files in order to resolve compatible problem.
|
||||
# agent.is_open_debugging_class = ${SW_AGENT_OPEN_DEBUG:true}
|
||||
|
||||
# The operationName max length
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ property key | Description | Default |
|
|||
`plugin.light4j.trace_handler_chain`|If true, trace all middleware/business handlers that are part of the Light4J handler chain for a request.|false|
|
||||
`plugin.opgroup.*`|Support operation name customize group rules in different plugins. Read [Group rule supported plugins](op_name_group_rule.md)|Not set|
|
||||
`plugin.springtransaction.simplify_transaction_definition_name`|If true, the transaction definition name will be simplified.|false|
|
||||
`plugin.jdkthreading.threading_class_prefixes` | Threading classes (`java.lang.Runnable` and `java.util.concurrent.Callable`) and their subclasses, including anonymous inner classes whose name match any one of the `THREADING_CLASS_PREFIXES` (splitted by `,`) will be instrumented, make sure to only specify as narrow prefixes as what you're expecting to instrument, (`java.` and `javax.` will be ignored due to safety issues) | Not set |
|
||||
|
||||
## Optional Plugins
|
||||
Java agent plugins are all pluggable. Optional plugins could be provided in `optional-plugins` folder under agent or 3rd party repositories.
|
||||
|
|
@ -140,6 +141,7 @@ 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.6+
|
||||
* Plugin of JDK Callable and Runnable. Agent is compatible with JDK 1.6+
|
||||
|
||||
## Advanced Features
|
||||
* Set the settings through system properties for config file override. Read [setting override](Setting-override.md).
|
||||
|
|
|
|||
|
|
@ -266,6 +266,9 @@ spring-tx:
|
|||
Armeria:
|
||||
id: 79
|
||||
languages: Java
|
||||
JdkThreading:
|
||||
id: 80
|
||||
languages: Java
|
||||
|
||||
# .NET/.NET Core components
|
||||
# [3000, 4000) for C#/.NET only
|
||||
|
|
|
|||
|
|
@ -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 -Dskywalking.plugin.jdkthreading.threading_class_prefixes=test.org.apache.skywalking. -jar ${agent_opts} ${home}/../libs/jdk-threading-scenario.jar &
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
# 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.
|
||||
|
||||
registryItems:
|
||||
applications:
|
||||
- {jdk-threading-scenario: 2}
|
||||
instances:
|
||||
- {jdk-threading-scenario: 1}
|
||||
operationNames:
|
||||
- jdk-threading-scenario: ['/greet/{username}']
|
||||
heartbeat: []
|
||||
|
||||
segmentItems:
|
||||
- applicationCode: jdk-threading-scenario
|
||||
segmentSize: ge 4
|
||||
segments:
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /greet/{username}
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 14
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
peerId: 0
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/greet/skywalking'}
|
||||
- {key: http.method, value: GET}
|
||||
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /apache/skywalking
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 13
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: github.com:443
|
||||
peerId: 0
|
||||
tags:
|
||||
- {key: url, value: 'https://github.com:-1/apache/skywalking'}
|
||||
- {key: http.method, value: GET}
|
||||
- operationName: Threading/test.org.apache.skywalking.apm.testcase.jdk.threading.Application$TestController$1/run
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Unknown
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 80
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Local
|
||||
peer: ''
|
||||
peerId: 0
|
||||
refs:
|
||||
- {parentEndpointId: 0, parentEndpoint: '/greet/{username}', networkAddressId: 0,
|
||||
entryEndpointId: 0, refType: CrossThread, parentSpanId: 0, parentTraceSegmentId: not null,
|
||||
parentServiceInstanceId: 1, networkAddress: '', entryEndpoint: '/greet/{username}',
|
||||
entryServiceInstanceId: 1}
|
||||
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: /apache/skywalking
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 13
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: github.com:443
|
||||
peerId: 0
|
||||
tags:
|
||||
- {key: url, value: 'https://github.com:-1/apache/skywalking'}
|
||||
- {key: http.method, value: GET}
|
||||
- operationName: Threading/test.org.apache.skywalking.apm.testcase.jdk.threading.Application$TestController$2/call
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Unknown
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 80
|
||||
componentName: ''
|
||||
isError: false
|
||||
spanType: Local
|
||||
peer: ''
|
||||
peerId: 0
|
||||
refs:
|
||||
- {parentEndpointId: 0, parentEndpoint: '/greet/{username}', networkAddressId: 0,
|
||||
entryEndpointId: 0, refType: CrossThread, parentSpanId: 0, parentTraceSegmentId: not null,
|
||||
parentServiceInstanceId: 1, networkAddress: '', entryEndpoint: '/greet/{username}',
|
||||
entryServiceInstanceId: 1}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# 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-threading-plugin-*.jar
|
||||
startScript: ./bin/startup.sh
|
||||
framework: jdk-threading-scenario
|
||||
|
|
@ -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-threading-scenario</artifactId>
|
||||
<version>5.0.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<compiler.version>1.6</compiler.version>
|
||||
<spring.boot.version>2.1.6.RELEASE</spring.boot.version>
|
||||
</properties>
|
||||
|
||||
<name>skywalking-jdk-threading-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-threading-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-threading-scenario.jar</source>
|
||||
<outputDirectory>./libs</outputDirectory>
|
||||
<fileMode>0775</fileMode>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* 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.org.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 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;
|
||||
|
||||
/**
|
||||
* @author kezhenxu94
|
||||
*/
|
||||
@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;
|
||||
|
||||
public TestController(final RestTemplate restTemplate) {
|
||||
this.restTemplate = restTemplate;
|
||||
this.executorService = Executors.newSingleThreadScheduledExecutor();
|
||||
}
|
||||
|
||||
@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("https://github.com/apache/skywalking", String.class);
|
||||
}
|
||||
};
|
||||
|
||||
executorService.execute(runnable);
|
||||
|
||||
executorService.submit(new Callable<String>() {
|
||||
@Override
|
||||
public String call() {
|
||||
return restTemplate.getForEntity("https://github.com/apache/skywalking", String.class).getBody();
|
||||
}
|
||||
}).get();
|
||||
|
||||
return username;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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