From 0f62d9289f6ea97ecdba91e5ea0f2c04de646161 Mon Sep 17 00:00:00 2001 From: liqiangz Date: Sat, 3 Jul 2021 00:20:14 +0800 Subject: [PATCH] Add agent plugin to support Sentinel (#7190) --- .github/workflows/plugins-test.1.yaml | 1 + CHANGES.md | 1 + .../trace/component/ComponentsDefine.java | 2 + apm-sniffer/optional-plugins/pom.xml | 1 + .../sentinel-1.x-plugin/pom.xml | 44 +++++++ .../apm/plugin/sentinel/v1/Constants.java | 26 ++++ .../sentinel/v1/EntryMethodInterceptor.java | 74 +++++++++++ ...tinelAsyncEntryConstructorInterceptor.java | 53 ++++++++ .../v1/SentinelAsyncExitInterceptor.java | 54 ++++++++ ...SentinelCtEntryConstructorInterceptor.java | 52 ++++++++ .../sentinel/v1/SentinelExitInterceptor.java | 55 ++++++++ .../SentinelAsyncEntryInstrumentation.java | 81 ++++++++++++ .../SentinelCtEntryInstrumentation.java | 80 ++++++++++++ .../define/SentinelCtSphInstrumentation.java | 80 ++++++++++++ .../src/main/resources/skywalking-plugin.def | 19 +++ .../service-agent/java-agent/Plugin-list.md | 1 + .../setup/service-agent/java-agent/README.md | 1 + .../java-agent/Supported-list.md | 1 + .../main/resources/component-libraries.yml | 3 + .../sentinel-scenario/bin/startup.sh | 21 +++ .../config/expectedData.yaml | 90 +++++++++++++ .../sentinel-scenario/configuration.yml | 24 ++++ .../scenarios/sentinel-scenario/pom.xml | 121 ++++++++++++++++++ .../src/main/assembly/assembly.xml | 41 ++++++ .../apm/testcase/sentinel/Application.java | 34 +++++ .../sentinel/controller/CaseController.java | 111 ++++++++++++++++ .../src/main/resources/application.yaml | 23 ++++ .../src/main/resources/log4j2.xml | 30 +++++ .../sentinel-scenario/support-version.list | 21 +++ 29 files changed, 1145 insertions(+) create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/pom.xml create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/Constants.java create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/EntryMethodInterceptor.java create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelAsyncEntryConstructorInterceptor.java create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelAsyncExitInterceptor.java create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelCtEntryConstructorInterceptor.java create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelExitInterceptor.java create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelAsyncEntryInstrumentation.java create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelCtEntryInstrumentation.java create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelCtSphInstrumentation.java create mode 100644 apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/resources/skywalking-plugin.def create mode 100644 test/plugin/scenarios/sentinel-scenario/bin/startup.sh create mode 100644 test/plugin/scenarios/sentinel-scenario/config/expectedData.yaml create mode 100644 test/plugin/scenarios/sentinel-scenario/configuration.yml create mode 100644 test/plugin/scenarios/sentinel-scenario/pom.xml create mode 100644 test/plugin/scenarios/sentinel-scenario/src/main/assembly/assembly.xml create mode 100644 test/plugin/scenarios/sentinel-scenario/src/main/java/test/apache/skywalking/apm/testcase/sentinel/Application.java create mode 100644 test/plugin/scenarios/sentinel-scenario/src/main/java/test/apache/skywalking/apm/testcase/sentinel/controller/CaseController.java create mode 100644 test/plugin/scenarios/sentinel-scenario/src/main/resources/application.yaml create mode 100644 test/plugin/scenarios/sentinel-scenario/src/main/resources/log4j2.xml create mode 100644 test/plugin/scenarios/sentinel-scenario/support-version.list diff --git a/.github/workflows/plugins-test.1.yaml b/.github/workflows/plugins-test.1.yaml index 30e43e429..67cfb5263 100644 --- a/.github/workflows/plugins-test.1.yaml +++ b/.github/workflows/plugins-test.1.yaml @@ -51,6 +51,7 @@ jobs: - httpclient-3.x-scenario - httpclient-4.3.x-scenario - hystrix-scenario + - sentinel-scenario - influxdb-scenario - jdk-http-scenario - jdk-threading-scenario diff --git a/CHANGES.md b/CHANGES.md index 74d4be869..9f674d509 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -27,6 +27,7 @@ Release Notes. * Add `ShardingSphere-5.0.0-beta` plugin. * Fix some method exception error. * Fix async finish repeatedly in `spring-webflux-5.x-webclient` plugin. +* Add agent plugin to support Sentinel. #### OAP-Backend diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java index e3fb4f9c6..2fc8cb538 100755 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -202,4 +202,6 @@ public class ComponentsDefine { public static final OfficialComponent MYBATIS = new OfficialComponent(109, "MyBatis"); public static final OfficialComponent NEO4J = new OfficialComponent(112, "Neo4j"); + + public static final OfficialComponent SENTINEL = new OfficialComponent(113, "Sentinel"); } diff --git a/apm-sniffer/optional-plugins/pom.xml b/apm-sniffer/optional-plugins/pom.xml index aa4204015..1abe6081b 100644 --- a/apm-sniffer/optional-plugins/pom.xml +++ b/apm-sniffer/optional-plugins/pom.xml @@ -50,6 +50,7 @@ kotlin-coroutine-plugin quartz-scheduler-2.x-plugin mybatis-3.x-plugin + sentinel-1.x-plugin diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/pom.xml b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/pom.xml new file mode 100644 index 000000000..bf1e037fc --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/pom.xml @@ -0,0 +1,44 @@ + + + + + + org.apache.skywalking + optional-plugins + 8.7.0-SNAPSHOT + + 4.0.0 + + apm-sentinel-1.x-plugin + sentinel-1.x-plugin + http://maven.apache.org + + 1.7.2 + + + + + com.alibaba.csp + sentinel-core + ${sentinel-core.version} + provided + + + \ No newline at end of file diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/Constants.java b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/Constants.java new file mode 100644 index 000000000..aeec07ab3 --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/Constants.java @@ -0,0 +1,26 @@ +/* + * 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.sentinel.v1; + +/** + * Interceptor class name constant variables + */ +public class Constants { + public static final String SENTINEL_SPAN = "SW_SENTINEL_SPAN"; +} diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/EntryMethodInterceptor.java b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/EntryMethodInterceptor.java new file mode 100644 index 000000000..0967dcf2a --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/EntryMethodInterceptor.java @@ -0,0 +1,74 @@ +/* + * 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.sentinel.v1; + +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException; +import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException; +import com.alibaba.csp.sentinel.slots.block.flow.FlowException; +import com.alibaba.csp.sentinel.slots.system.SystemBlockException; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +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 java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; + +import static org.apache.skywalking.apm.plugin.sentinel.v1.Constants.SENTINEL_SPAN; + +public class EntryMethodInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + } + + @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) { + Object span = ContextManager.getRuntimeContext().get(SENTINEL_SPAN); + if (span != null) { + if (t instanceof BlockException) { + Map eventMap = new HashMap(); + eventMap.put("blocked", "true"); + if (t instanceof FlowException) { + eventMap.put("block_type", "flow"); + } else if (t instanceof DegradeException) { + eventMap.put("block_type", "degrade"); + } else if (t instanceof SystemBlockException) { + eventMap.put("block_type", "system"); + } else if (t instanceof AuthorityException) { + eventMap.put("block_type", "authority"); + } + ((AbstractSpan) span).log(System.currentTimeMillis(), eventMap); + } else { + ((AbstractSpan) span).log(t); + } + ContextManager.getRuntimeContext().remove(SENTINEL_SPAN); + } + } +} diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelAsyncEntryConstructorInterceptor.java b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelAsyncEntryConstructorInterceptor.java new file mode 100644 index 000000000..4d5d40aeb --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelAsyncEntryConstructorInterceptor.java @@ -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.sentinel.v1; + +import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +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.InstanceConstructorInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import static org.apache.skywalking.apm.plugin.sentinel.v1.Constants.SENTINEL_SPAN; + +/** + * {@link SentinelAsyncEntryConstructorInterceptor} get CommandKey or CollapserKey as the + * operation name prefix of span when the constructor that the class hierarchy com.netflix.hystrix.HystrixCommand + * invoked. + */ +public class SentinelAsyncEntryConstructorInterceptor implements InstanceConstructorInterceptor { + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + ResourceWrapper resourceWrapper = (ResourceWrapper) allArguments[0]; + AbstractSpan activeSpan = ContextManager.createLocalSpan("Sentinel/" + resourceWrapper.getName()); + activeSpan.setComponent(ComponentsDefine.SENTINEL); + + AbstractSpan span = activeSpan.prepareForAsync(); + objInst.setSkyWalkingDynamicField(span); + ContextManager.getRuntimeContext().put( + SENTINEL_SPAN, + span + ); + + ContextManager.stopSpan(activeSpan); + } + +} diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelAsyncExitInterceptor.java b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelAsyncExitInterceptor.java new file mode 100644 index 000000000..9b6455562 --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelAsyncExitInterceptor.java @@ -0,0 +1,54 @@ +/* + * 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.sentinel.v1; + +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 java.lang.reflect.Method; + +public class SentinelAsyncExitInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + if (objInst.getSkyWalkingDynamicField() != null) { + final AbstractSpan span = (AbstractSpan) objInst.getSkyWalkingDynamicField(); + span.asyncFinish(); + objInst.setSkyWalkingDynamicField(null); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + if (objInst.getSkyWalkingDynamicField() != null) { + final AbstractSpan span = (AbstractSpan) objInst.getSkyWalkingDynamicField(); + span.log(t); + } + } +} diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelCtEntryConstructorInterceptor.java b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelCtEntryConstructorInterceptor.java new file mode 100644 index 000000000..b008afe68 --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelCtEntryConstructorInterceptor.java @@ -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.sentinel.v1; + +import com.alibaba.csp.sentinel.AsyncEntry; +import com.alibaba.csp.sentinel.slotchain.ResourceWrapper; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +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.InstanceConstructorInterceptor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import static org.apache.skywalking.apm.plugin.sentinel.v1.Constants.SENTINEL_SPAN; + +/** + * {@link SentinelCtEntryConstructorInterceptor} get CommandKey or CollapserKey as the + * operation name prefix of span when the constructor that the class hierarchy com.netflix.hystrix.HystrixCommand + * invoked. + */ +public class SentinelCtEntryConstructorInterceptor implements InstanceConstructorInterceptor { + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + if (!(objInst instanceof AsyncEntry)) { + ResourceWrapper resourceWrapper = (ResourceWrapper) allArguments[0]; + AbstractSpan activeSpan = ContextManager.createLocalSpan("Sentinel/" + resourceWrapper.getName()); + activeSpan.setComponent(ComponentsDefine.SENTINEL); + objInst.setSkyWalkingDynamicField(activeSpan); + + ContextManager.getRuntimeContext().put( + SENTINEL_SPAN, + activeSpan + ); + } + } +} diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelExitInterceptor.java b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelExitInterceptor.java new file mode 100644 index 000000000..e3a7d0bd0 --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/SentinelExitInterceptor.java @@ -0,0 +1,55 @@ +/* + * 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.sentinel.v1; + +import org.apache.skywalking.apm.agent.core.context.ContextManager; +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 java.lang.reflect.Method; + +public class SentinelExitInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + if (objInst.getSkyWalkingDynamicField() != null) { + final AbstractSpan span = (AbstractSpan) objInst.getSkyWalkingDynamicField(); + ContextManager.stopSpan(span); + objInst.setSkyWalkingDynamicField(null); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + if (objInst.getSkyWalkingDynamicField() != null) { + final AbstractSpan span = (AbstractSpan) objInst.getSkyWalkingDynamicField(); + span.log(t); + } + } +} diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelAsyncEntryInstrumentation.java b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelAsyncEntryInstrumentation.java new file mode 100644 index 000000000..54c7423aa --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelAsyncEntryInstrumentation.java @@ -0,0 +1,81 @@ +/* + * 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.sentinel.v1.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.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.isProtected; +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class SentinelAsyncEntryInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "com.alibaba.csp.sentinel.AsyncEntry"; + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override + public String getConstructorInterceptor() { + return "org.apache.skywalking.apm.plugin.sentinel.v1.SentinelAsyncEntryConstructorInterceptor"; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return isProtected().and(named("exitForContext")); + } + + @Override + public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.sentinel.v1.SentinelAsyncExitInterceptor"; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + +} diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelCtEntryInstrumentation.java b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelCtEntryInstrumentation.java new file mode 100644 index 000000000..9e509c7f6 --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelCtEntryInstrumentation.java @@ -0,0 +1,80 @@ +/* + * 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.sentinel.v1.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.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class SentinelCtEntryInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "com.alibaba.csp.sentinel.CtEntry"; + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override + public String getConstructorInterceptor() { + return "org.apache.skywalking.apm.plugin.sentinel.v1.SentinelCtEntryConstructorInterceptor"; + } + } + }; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("trueExit"); + } + + @Override + public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.sentinel.v1.SentinelExitInterceptor"; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } + +} diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelCtSphInstrumentation.java b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelCtSphInstrumentation.java new file mode 100644 index 000000000..b40b83558 --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/sentinel/v1/define/SentinelCtSphInstrumentation.java @@ -0,0 +1,80 @@ +/* + * 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.sentinel.v1.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.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.isPrivate; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +public class SentinelCtSphInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return isPrivate().and(named("entryWithPriority")); + } + + @Override + public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.sentinel.v1.EntryMethodInterceptor"; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return isPrivate().and(named("asyncEntryWithPriorityInternal")); + } + + @Override + public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.sentinel.v1.EntryMethodInterceptor"; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return byName("com.alibaba.csp.sentinel.CtSph"); + } +} diff --git a/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..1fcb19f57 --- /dev/null +++ b/apm-sniffer/optional-plugins/sentinel-1.x-plugin/src/main/resources/skywalking-plugin.def @@ -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. + +sentinel-1.x=org.apache.skywalking.apm.plugin.sentinel.v1.define.SentinelCtEntryInstrumentation +sentinel-1.x=org.apache.skywalking.apm.plugin.sentinel.v1.define.SentinelAsyncEntryInstrumentation +sentinel-1.x=org.apache.skywalking.apm.plugin.sentinel.v1.define.SentinelCtSphInstrumentation \ No newline at end of file diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md index 6acd1687c..1d46c7431 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -65,6 +65,7 @@ - resteasy-server-3.x - rocketMQ-3.x - rocketMQ-4.x +- sentinel-1.x - servicecomb-0.x - servicecomb-1.x - sharding-jdbc-1.5.x diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md index ff2e79b81..6f3db6b26 100755 --- a/docs/en/setup/service-agent/java-agent/README.md +++ b/docs/en/setup/service-agent/java-agent/README.md @@ -193,6 +193,7 @@ Now, we have the following known optional plugins. * Plugin of quartz-scheduler-2.x in the optional plugin folder. The reason for being an optional plugin is, many task scheduling systems are based on quartz-scheduler, this will cause duplicate tracing and link different sub-tasks as they share the same quartz level trigger, such as ElasticJob. * Plugin of spring-webflux-5.x in the optional plugin folder. Please only activate this plugin when you use webflux alone as a web container. If you are using SpringMVC 5 or Spring Gateway, you don't need this plugin. * Plugin of mybatis-3.x in optional plugin folder. The reason of being optional plugin is, many local span are generated, which also spend more CPU, memory and network. +* Plugin of sentinel-1.x in the optional plugin folder. The reason for being an optional plugin is, the sentinel plugin generates a large number of local spans, which have a potential performance impact. ## Bootstrap class plugins All bootstrap plugins are optional, due to unexpected risk. Bootstrap plugins are provided in `bootstrap-plugins` folder. diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index 0ec7b25ec..a5fd41e4d 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -96,6 +96,7 @@ metrics based on the tracing data. * Spring Core Async SuccessCallback/FailureCallback/ListenableFutureCallback 4.x * Spring Transaction 4.x and 5.x (Optional²) * [Hystrix: Latency and Fault Tolerance for Distributed Systems](https://github.com/Netflix/Hystrix) 1.4.20 -> 1.5.18 +* [Sentinel: The Sentinel of Your Microservices](https://github.com/alibaba/Sentinel) 1.7.0 -> 1.8.1 * Scheduler * [Elastic Job](https://github.com/elasticjob/elastic-job) 2.x * [Apache ShardingSphere-Elasticjob](https://github.com/apache/shardingsphere-elasticjob) 3.0.0-alpha diff --git a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml index 8096b168e..5e6e1588c 100755 --- a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml +++ b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml @@ -368,6 +368,9 @@ AzureHttpTrigger: Neo4j: id: 112 languages: Java +Sentinel: + id: 113 + languages: Java # .NET/.NET Core components # [3000, 4000) for C#/.NET only diff --git a/test/plugin/scenarios/sentinel-scenario/bin/startup.sh b/test/plugin/scenarios/sentinel-scenario/bin/startup.sh new file mode 100644 index 000000000..f36c96671 --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/bin/startup.sh @@ -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/sentinel-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/sentinel-scenario/config/expectedData.yaml b/test/plugin/scenarios/sentinel-scenario/config/expectedData.yaml new file mode 100644 index 000000000..002f0a7cf --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/config/expectedData.yaml @@ -0,0 +1,90 @@ +# 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: sentinel-scenario + segmentSize: nq 0 + segments: + - segmentId: not null + spans: + - operationName: /case/healthCheck + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: not null + endTime: not null + componentId: 14 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/sentinel-scenario/case/healthCheck'} + - {key: http.method, value: HEAD} + - segmentId: not null + spans: + - operationName: Sentinel/test_SphO_entry + operationId: 0 + parentSpanId: 1 + spanId: 2 + spanLayer: Unknown + startTime: not null + endTime: not null + componentId: 113 + isError: false + spanType: Local + peer: '' + skipAnalysis: false + logs: + - logEvent: + - {key: block_type, value: flow} + - {key: blocked, value: 'true'} + - {operationName: Sentinel/test_SphU_entry, operationId: 0, parentSpanId: 0, spanId: 1, + spanLayer: Unknown, startTime: not null, endTime: not null, componentId: 113, + isError: false, spanType: Local, peer: '', skipAnalysis: false} + - operationName: Sentinel/test_SphU_asyncEntry + operationId: 0 + parentSpanId: 0 + spanId: 3 + spanLayer: Unknown + startTime: not null + endTime: not null + componentId: 113 + isError: false + spanType: Local + peer: '' + skipAnalysis: false + logs: + - logEvent: + - {key: block_type, value: flow} + - {key: blocked, value: 'true'} + - operationName: /case/sentinel-scenario + operationId: 0 + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: not null + endTime: not null + componentId: 14 + isError: false + spanType: Entry + peer: '' + skipAnalysis: false + tags: + - {key: url, value: 'http://localhost:8080/sentinel-scenario/case/sentinel-scenario'} + - {key: http.method, value: GET} +meterItems: [] diff --git a/test/plugin/scenarios/sentinel-scenario/configuration.yml b/test/plugin/scenarios/sentinel-scenario/configuration.yml new file mode 100644 index 000000000..c6ee9afd5 --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/configuration.yml @@ -0,0 +1,24 @@ +# 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/sentinel-scenario/case/sentinel-scenario +healthCheck: http://localhost:8080/sentinel-scenario/case/healthCheck +startScript: ./bin/startup.sh +runningMode: with_optional +withPlugins: apm-sentinel-1.x-plugin-*.jar +environment: +dependencies: diff --git a/test/plugin/scenarios/sentinel-scenario/pom.xml b/test/plugin/scenarios/sentinel-scenario/pom.xml new file mode 100644 index 000000000..48fc07cbe --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/pom.xml @@ -0,0 +1,121 @@ + + + + + org.apache.skywalking.apm.testcase + sentinel-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 1.7.2 + 2.1.18.RELEASE + + + skywalking-sentinel-scenario + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot-version} + pom + import + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + jul-to-slf4j + org.slf4j + + + + + com.alibaba.csp + sentinel-core + ${test.framework.version} + + + + + sentinel-scenario + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + maven-compiler-plugin + + 1.8 + 1.8 + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + diff --git a/test/plugin/scenarios/sentinel-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/sentinel-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..f96367ae5 --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/sentinel-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/sentinel-scenario/src/main/java/test/apache/skywalking/apm/testcase/sentinel/Application.java b/test/plugin/scenarios/sentinel-scenario/src/main/java/test/apache/skywalking/apm/testcase/sentinel/Application.java new file mode 100644 index 000000000..874f0adc4 --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/src/main/java/test/apache/skywalking/apm/testcase/sentinel/Application.java @@ -0,0 +1,34 @@ +/* + * 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.sentinel; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + try { + SpringApplication.run(Application.class, args); + } catch (Exception e) { + // Never do this + } + } +} diff --git a/test/plugin/scenarios/sentinel-scenario/src/main/java/test/apache/skywalking/apm/testcase/sentinel/controller/CaseController.java b/test/plugin/scenarios/sentinel-scenario/src/main/java/test/apache/skywalking/apm/testcase/sentinel/controller/CaseController.java new file mode 100644 index 000000000..a3ef3d438 --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/src/main/java/test/apache/skywalking/apm/testcase/sentinel/controller/CaseController.java @@ -0,0 +1,111 @@ +/* + * 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.sentinel.controller; + +import com.alibaba.csp.sentinel.Entry; +import com.alibaba.csp.sentinel.SphU; +import com.alibaba.csp.sentinel.AsyncEntry; +import com.alibaba.csp.sentinel.Tracer; +import com.alibaba.csp.sentinel.SphO; +import com.alibaba.csp.sentinel.slots.block.BlockException; +import com.alibaba.csp.sentinel.slots.block.RuleConstant; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRule; +import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.annotation.PostConstruct; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutionException; + +@Controller +@RequestMapping("/case") +public class CaseController { + + private static final Logger LOGGER = LogManager.getLogger(CaseController.class); + + private static final String SUCCESS = "Success"; + + @PostConstruct + public void setUp() { + List rules = new ArrayList<>(); + FlowRule rule = new FlowRule("test_SphO_entry"); + // set limit qps to 0 + rule.setCount(0); + rule.setGrade(RuleConstant.FLOW_GRADE_QPS); + rule.setLimitApp("default"); + rules.add(rule); + + FlowRule rule2 = new FlowRule("test_SphU_asyncEntry"); + // set limit qps to 0 + rule2.setCount(0); + rule2.setGrade(RuleConstant.FLOW_GRADE_QPS); + rule2.setLimitApp("default"); + rules.add(rule2); + FlowRuleManager.loadRules(rules); + } + + @RequestMapping("/sentinel-scenario") + @ResponseBody + public String testcase() throws InterruptedException, ExecutionException { + Entry entry = null; + try { + entry = SphU.entry("test_SphU_entry"); + if (SphO.entry("test_SphO_entry")) { + Thread.sleep(1000L); + SphO.exit(); + } + Thread.sleep(1000L); + } catch (BlockException ex) { + + } catch (Exception ex) { + Tracer.traceEntry(ex, entry); + } finally { + if (entry != null) { + entry.exit(); + } + } + + try { + AsyncEntry asyncEntry = SphU.asyncEntry("test_SphU_asyncEntry"); + new Thread(() -> { + try { + Thread.sleep(2000L); + } catch (InterruptedException e) { + e.printStackTrace(); + } finally { + asyncEntry.exit(); + } + }).start(); + } catch (BlockException ex) { + } + return SUCCESS; + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() { + return SUCCESS; + } + +} diff --git a/test/plugin/scenarios/sentinel-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/sentinel-scenario/src/main/resources/application.yaml new file mode 100644 index 000000000..0a7c83636 --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/src/main/resources/application.yaml @@ -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. +# +# +server: + port: 8080 + servlet: + context-path: /sentinel-scenario +logging: + config: classpath:log4j2.xml diff --git a/test/plugin/scenarios/sentinel-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/sentinel-scenario/src/main/resources/log4j2.xml new file mode 100644 index 000000000..b5cda5ae8 --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + diff --git a/test/plugin/scenarios/sentinel-scenario/support-version.list b/test/plugin/scenarios/sentinel-scenario/support-version.list new file mode 100644 index 000000000..d7d45586d --- /dev/null +++ b/test/plugin/scenarios/sentinel-scenario/support-version.list @@ -0,0 +1,21 @@ +# 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. + +1.7.0 +1.7.1 +1.7.2 +1.8.0 +1.8.1