diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextSnapshot.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextSnapshot.java index e2a589e9e..cedac2421 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextSnapshot.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextSnapshot.java @@ -113,4 +113,8 @@ public class ContextSnapshot { public int getEntryApplicationInstanceId() { return entryApplicationInstanceId; } + + public boolean fromCurrent() { + return traceSegmentId.equals(ContextManager.capture().getTraceSegmentId()); + } } diff --git a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/pom.xml index 0ece48390..33f6cb7b8 100644 --- a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/pom.xml @@ -1,4 +1,22 @@ + + diff --git a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/ExecuteEventListener.java b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/ExecuteEventListener.java index d187d6f36..5bb6ecbbe 100644 --- a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/ExecuteEventListener.java +++ b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/ExecuteEventListener.java @@ -1,3 +1,21 @@ +/* + * Copyright 2017, OpenSkywalking Organization All rights reserved. + * + * Licensed 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 repository: https://github.com/OpenSkywalking/skywalking + */ + package org.skywalking.apm.plugin.sjdbc; import com.dangdang.ddframe.rdb.sharding.executor.event.AbstractExecutionEvent; @@ -17,7 +35,7 @@ import org.skywalking.apm.network.trace.component.ComponentsDefine; import org.skywalking.apm.plugin.sjdbc.define.AsyncExecuteInterceptor; /** - * Sharding-jdbc provides {@link EventBusInstance} to help external systems get events about sql execution. + * Sharding-jdbc provides {@link EventBusInstance} to help external systems get events of sql execution. * {@link ExecuteEventListener} can get sql statement start and end events, resulting in db span. * * @author gaohongtao @@ -45,7 +63,10 @@ public class ExecuteEventListener { case BEFORE_EXECUTE: AbstractSpan span = ContextManager.createExitSpan("/SJDBC/BRANCH/" + operation, event.getDataSource()); if (ExecutorDataMap.getDataMap().containsKey(AsyncExecuteInterceptor.SNAPSHOT_DATA_KEY)) { - ContextManager.continued((ContextSnapshot)ExecutorDataMap.getDataMap().get(AsyncExecuteInterceptor.SNAPSHOT_DATA_KEY)); + ContextSnapshot contextSnapshot = (ContextSnapshot)ExecutorDataMap.getDataMap().get(AsyncExecuteInterceptor.SNAPSHOT_DATA_KEY); + if (!contextSnapshot.fromCurrent()) { + ContextManager.continued(contextSnapshot); + } } Tags.DB_TYPE.set(span, "sql"); Tags.DB_INSTANCE.set(span, event.getDataSource()); diff --git a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/AsyncExecuteInterceptor.java b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/AsyncExecuteInterceptor.java index a7ce9dcd8..d301e6c87 100644 --- a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/AsyncExecuteInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/AsyncExecuteInterceptor.java @@ -1,12 +1,28 @@ +/* + * Copyright 2017, OpenSkywalking Organization All rights reserved. + * + * Licensed 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 repository: https://github.com/OpenSkywalking/skywalking + */ + package org.skywalking.apm.plugin.sjdbc.define; import com.dangdang.ddframe.rdb.sharding.constant.SQLType; import com.dangdang.ddframe.rdb.sharding.executor.ExecuteCallback; import com.dangdang.ddframe.rdb.sharding.executor.threadlocal.ExecutorDataMap; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import org.skywalking.apm.agent.core.context.ContextManager; import org.skywalking.apm.agent.core.context.ContextSnapshot; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; @@ -34,14 +50,6 @@ public class AsyncExecuteInterceptor implements InstanceMethodsAroundInterceptor @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { - Map oldMap = ExecutorDataMap.getDataMap(); - Map newMap = new HashMap<>(oldMap.size() - 1); - for (Map.Entry each : oldMap.entrySet()) { - if (!each.getKey().equals(SNAPSHOT_DATA_KEY)) { - newMap.put(each.getKey(), each.getValue()); - } - } - ExecutorDataMap.setDataMap(newMap); return ret; } diff --git a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecuteInterceptor.java b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecuteInterceptor.java index f7d7c4c07..bae42df9d 100644 --- a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecuteInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecuteInterceptor.java @@ -1,3 +1,21 @@ +/* + * Copyright 2017, OpenSkywalking Organization All rights reserved. + * + * Licensed 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 repository: https://github.com/OpenSkywalking/skywalking + */ + package org.skywalking.apm.plugin.sjdbc.define; import com.dangdang.ddframe.rdb.sharding.constant.SQLType; diff --git a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecutorEngineConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecutorEngineConstructorInterceptor.java new file mode 100644 index 000000000..7cee3480e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecutorEngineConstructorInterceptor.java @@ -0,0 +1,36 @@ +/* + * Copyright 2017, OpenSkywalking Organization All rights reserved. + * + * Licensed 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 repository: https://github.com/OpenSkywalking/skywalking + */ + +package org.skywalking.apm.plugin.sjdbc.define; + +import com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; +import org.skywalking.apm.plugin.sjdbc.ExecuteEventListener; + +/** + * {@link ExecutorEngineConstructorInterceptor} enhances {@link ExecutorEngine#}'s constructor, initializing {@link ExecuteEventListener} + * + * @author gaohongtao + */ +public class ExecutorEngineConstructorInterceptor implements InstanceConstructorInterceptor { + + @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + ExecuteEventListener.init(); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecutorInstrumentation.java b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecutorInstrumentation.java index a9d89a0f5..6c44444a3 100644 --- a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecutorInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/main/java/org/skywalking/apm/plugin/sjdbc/define/ExecutorInstrumentation.java @@ -1,3 +1,21 @@ +/* + * Copyright 2017, OpenSkywalking Organization All rights reserved. + * + * Licensed 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 repository: https://github.com/OpenSkywalking/skywalking + */ + package org.skywalking.apm.plugin.sjdbc.define; import net.bytebuddy.description.method.MethodDescription; @@ -6,8 +24,8 @@ import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoin import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; import org.skywalking.apm.agent.core.plugin.match.ClassMatch; -import org.skywalking.apm.plugin.sjdbc.ExecuteEventListener; +import static net.bytebuddy.matcher.ElementMatchers.any; import static net.bytebuddy.matcher.ElementMatchers.named; import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; @@ -19,6 +37,8 @@ import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; public class ExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine"; + + private static final String EXECUTOR_ENGINE_CONSTRUCTOR_INTERCEPTOR_CLASS = "org.skywalking.apm.plugin.sjdbc.define.ExecutorEngineConstructorInterceptor"; private static final String EXECUTE_INTERCEPTOR_CLASS = "org.skywalking.apm.plugin.sjdbc.define.ExecuteInterceptor"; @@ -26,7 +46,19 @@ public class ExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDe @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return null; + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override + public String getConstructorInterceptor() { + return EXECUTOR_ENGINE_CONSTRUCTOR_INTERCEPTOR_CLASS; + } + } + }; } @Override @@ -69,7 +101,6 @@ public class ExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDe @Override protected ClassMatch enhanceClass() { - ExecuteEventListener.init(); return byName(ENHANCE_CLASS); } } diff --git a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/test/java/org/skywalking/apm/plugin/sjdbc/InterceptorTest.java b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/test/java/org/skywalking/apm/plugin/sjdbc/InterceptorTest.java index 35228ca60..925174676 100644 --- a/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/test/java/org/skywalking/apm/plugin/sjdbc/InterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/sharding-jdbc-1.5.x-plugin/src/test/java/org/skywalking/apm/plugin/sjdbc/InterceptorTest.java @@ -1,3 +1,21 @@ +/* + * Copyright 2017, OpenSkywalking Organization All rights reserved. + * + * Licensed 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 repository: https://github.com/OpenSkywalking/skywalking + */ + package org.skywalking.apm.plugin.sjdbc; import com.dangdang.ddframe.rdb.sharding.constant.SQLType; @@ -14,7 +32,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.hamcrest.core.Is; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; @@ -34,9 +51,11 @@ import org.skywalking.apm.agent.test.tools.TracingSegmentRunner; import org.skywalking.apm.network.trace.component.ComponentsDefine; import org.skywalking.apm.plugin.sjdbc.define.AsyncExecuteInterceptor; import org.skywalking.apm.plugin.sjdbc.define.ExecuteInterceptor; +import org.skywalking.apm.plugin.sjdbc.define.ExecutorEngineConstructorInterceptor; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThat; import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLayer; @@ -64,6 +83,7 @@ public class InterceptorTest { @BeforeClass public static void init() { ExecuteEventListener.init(); + new ExecutorEngineConstructorInterceptor().onConstruct(null, null); ES = Executors.newSingleThreadExecutor(); } @@ -109,6 +129,7 @@ public class InterceptorTest { TraceSegment segment0 = segmentStorage.getTraceSegments().get(0); TraceSegment segment1 = segmentStorage.getTraceSegments().get(1); assertThat(segment0.getRefs().size(), is(1)); + assertNull(segment1.getRefs()); List spans0 = SegmentHelper.getSpans(segment0); assertNotNull(spans0); assertThat(spans0.size(), is(1)); @@ -120,22 +141,6 @@ public class InterceptorTest { assertThat(spans1.get(1).getOperationName(), is("/SJDBC/TRUNK/DQL")); } - @Test - public void assertAsyncContextHold() throws Throwable { - ExecutorDataMap.getDataMap().put("FOO_KEY", "FOO_VALUE"); - executeInterceptor.beforeMethod(null, null, allArguments, null, null); - asyncExecuteInterceptor.beforeMethod(null, null, null, null, null); - final Map dataMap = ExecutorDataMap.getDataMap(); - ES.submit(() -> { - ExecutorDataMap.setDataMap(dataMap); - sendEvent("ds_1", "select * from t_order_1"); - }).get(); - asyncExecuteInterceptor.afterMethod(null, null, null, null, null); - executeInterceptor.afterMethod(null, null, allArguments, null, null); - assertThat(ExecutorDataMap.getDataMap().size(), is(1)); - assertThat(ExecutorDataMap.getDataMap().get("FOO_KEY"), Is.is("FOO_VALUE")); - } - @Test public void assertExecuteError() throws Throwable { executeInterceptor.beforeMethod(null, null, allArguments, null, null);