From c15d1a5676816ab600156138c37de11dc0cf3284 Mon Sep 17 00:00:00 2001 From: gaohongtao Date: Mon, 20 Nov 2017 10:18:37 +0800 Subject: [PATCH 1/4] Fix #603 Elastic-Job plugin --- .../trace/component/ComponentsDefine.java | 5 +- .../elastic-job-2.x-plugin/pom.xml | 54 +++++++++ .../plugin/esjob/JobExecutorInterceptor.java | 65 +++++++++++ .../define/JobExecutorInstrumentation.java | 68 +++++++++++ .../src/main/resources/skywalking-plugin.def | 1 + .../esjob/JobExecutorInterceptorTest.java | 107 ++++++++++++++++++ apm-sniffer/apm-sdk-plugin/pom.xml | 1 + 7 files changed, 300 insertions(+), 1 deletion(-) create mode 100644 apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml create mode 100644 apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/java/org/skywalking/apm/plugin/esjob/define/JobExecutorInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/resources/skywalking-plugin.def create mode 100644 apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/test/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptorTest.java diff --git a/apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java index 0151346e8..8d411d847 100644 --- a/apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -71,6 +71,8 @@ public class ComponentsDefine { public static final OfficialComponent GRPC = new OfficialComponent(23, "GRPC"); + public static final OfficialComponent ELASTIC_JOB = new OfficialComponent(24, "ElasticJob"); + private static ComponentsDefine instance = new ComponentsDefine(); private String[] components; @@ -80,7 +82,7 @@ public class ComponentsDefine { } public ComponentsDefine() { - components = new String[24]; + components = new String[25]; addComponent(TOMCAT); addComponent(HTTPCLIENT); addComponent(DUBBO); @@ -104,6 +106,7 @@ public class ComponentsDefine { addComponent(SHARDING_JDBC); addComponent(POSTGRESQL); addComponent(GRPC); + addComponent(ELASTIC_JOB); } private void addComponent(OfficialComponent component) { diff --git a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml new file mode 100644 index 000000000..ae6e051b4 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml @@ -0,0 +1,54 @@ + + + + apm-sdk-plugin + org.skywalking + 3.2.4-2017 + + 4.0.0 + + apm-elastic-job-2.x-plugin + jar + + elastic-job-2.x-plugin + http://maven.apache.org + + + UTF-8 + + + + + com.dangdang + elastic-job-common-core + [2.0.0,3.0.0) + provided + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + + + + org.apache.maven.plugins + maven-source-plugin + + + + attach-sources + + jar + + + + + + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptor.java b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptor.java new file mode 100644 index 000000000..735dbd56d --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptor.java @@ -0,0 +1,65 @@ +/* + * 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.esjob; + +import com.dangdang.ddframe.job.api.ShardingContext; +import com.dangdang.ddframe.job.executor.ShardingContexts; +import com.google.common.base.Strings; +import java.lang.reflect.Method; +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.network.trace.component.ComponentsDefine; + +/** + * {@link JobExecutorInterceptor} enhances {@link com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor#process(ShardingContext)} + * ,creating a local span that records job execution. + * + * @author gaohongtao + */ +public class JobExecutorInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + ShardingContexts shardingContexts = (ShardingContexts)allArguments[0]; + Integer item = (Integer)allArguments[1]; + ShardingContext shardingContext = new ShardingContext(shardingContexts, item); + String operateName = shardingContext.getJobName(); + if (!Strings.isNullOrEmpty(shardingContext.getShardingParameter())) { + operateName += "-" + shardingContext.getShardingParameter(); + } + AbstractSpan span = ContextManager.createLocalSpan(operateName); + span.setComponent(ComponentsDefine.ELASTIC_JOB); + span.tag("sharding_context", shardingContext.toString()); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + ContextManager.stopSpan(); + return ret; + } + + @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + ContextManager.activeSpan().errorOccurred().log(t); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/java/org/skywalking/apm/plugin/esjob/define/JobExecutorInstrumentation.java b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/java/org/skywalking/apm/plugin/esjob/define/JobExecutorInstrumentation.java new file mode 100644 index 000000000..eb29a9e3e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/java/org/skywalking/apm/plugin/esjob/define/JobExecutorInstrumentation.java @@ -0,0 +1,68 @@ +/* + * 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.esjob.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +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 static org.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * {@link JobExecutorInstrumentation} presents that skywalking intercepts {@link com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor}. + * + * @author gaohongtao + */ +public class JobExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "com.dangdang.ddframe.job.executor.AbstractElasticJobExecutor"; + + private static final String JOB_EXECUTOR_INTERCEPTOR_CLASS = "org.skywalking.apm.plugin.esjob.JobExecutorInterceptor"; + + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + + @Override public ElementMatcher getMethodsMatcher() { + return takesArgumentWithType(2, "com.dangdang.ddframe.job.event.type.JobExecutionEvent"); + } + + @Override public String getMethodsInterceptor() { + return JOB_EXECUTOR_INTERCEPTOR_CLASS; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..7e8a4d707 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1 @@ +elastic-job-2.x=org.skywalking.apm.plugin.esjob.define.JobExecutorInstrumentation \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/test/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/test/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptorTest.java new file mode 100644 index 000000000..25d955639 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/test/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptorTest.java @@ -0,0 +1,107 @@ +/* + * 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.esjob; + +import com.dangdang.ddframe.job.executor.ShardingContexts; +import java.sql.SQLException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.skywalking.apm.agent.test.tools.SegmentStorage; +import org.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.skywalking.apm.agent.test.tools.TracingSegmentRunner; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertThat; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class JobExecutorInterceptorTest { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private JobExecutorInterceptor jobExecutorInterceptor; + + @Before + public void setUp() throws SQLException { + jobExecutorInterceptor = new JobExecutorInterceptor(); + } + + @Test + public void assertSuccess() throws Throwable { + jobExecutorInterceptor.beforeMethod(null, null, new Object[]{mockShardingContext("fooJob", 1), 1}, null, null); + jobExecutorInterceptor.afterMethod(null, null, null, null, null); + TraceSegment segment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(segment); + assertNotNull(spans); + assertThat(spans.size(), is(1)); + assertThat(spans.get(0).transform().getOperationName(), is("fooJob-test")); + assertThat(spans.get(0).transform().getComponentId(), is(23)); + assertThat(spans.get(0).transform().getTags(0).getKey(), is("sharding_context")); + assertThat(spans.get(0).transform().getTags(0).getValue(), is("ShardingContext(jobName=fooJob, taskId=fooJob1, shardingTotalCount=2, jobParameter=, shardingItem=1, shardingParameter=test)")); + } + + @Test + public void assertSuccessWithoutSharding() throws Throwable { + jobExecutorInterceptor.beforeMethod(null, null, new Object[]{mockShardingContext("fooJob", 0), 0}, null, null); + jobExecutorInterceptor.afterMethod(null, null, null, null, null); + TraceSegment segment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(segment); + assertNotNull(spans); + assertThat(spans.size(), is(1)); + assertThat(spans.get(0).transform().getOperationName(), is("fooJob")); + assertThat(spans.get(0).transform().getTags(0).getValue(), is("ShardingContext(jobName=fooJob, taskId=fooJob0, shardingTotalCount=1, jobParameter=, shardingItem=0, shardingParameter=null)")); + } + + @Test + public void assertError() throws Throwable { + jobExecutorInterceptor.beforeMethod(null, null, new Object[]{mockShardingContext("fooJob", 0), 0}, null, null); + jobExecutorInterceptor.handleMethodException(null, null, null, null, new Exception("fooError")); + jobExecutorInterceptor.afterMethod(null, null, null, null, null); + TraceSegment segment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(segment); + assertNotNull(spans); + assertThat(spans.size(), is(1)); + assertThat(spans.get(0).transform().getIsError(), is(true)); + assertThat(spans.get(0).transform().getLogs(0).getDataList().size(), is(4)); + } + + private ShardingContexts mockShardingContext(String jobName, int shardingItem) { + Map shardingMap = new HashMap(1); + if (shardingItem >= 1) { + shardingMap.put(shardingItem, "test"); + } + return new ShardingContexts(jobName + shardingItem, jobName, shardingItem + 1, "", shardingMap); + } +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index c513de7cd..b4587d7a1 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -52,6 +52,7 @@ h2-1.x-plugin postgresql-8.x-plugin oracle-10.x-plugin + elastic-job-2.x-plugin pom From c0c21f9e26b6977a119e3bfe5f75916fd67dd2db Mon Sep 17 00:00:00 2001 From: gaohongtao Date: Mon, 20 Nov 2017 10:26:15 +0800 Subject: [PATCH 2/4] Fix version number --- apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml index ae6e051b4..efcc30e36 100644 --- a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml @@ -5,7 +5,7 @@ apm-sdk-plugin org.skywalking - 3.2.4-2017 + 3.2.5-2017 4.0.0 From c87039a828fc97d5e0e0a4f15582bb901c90c11a Mon Sep 17 00:00:00 2001 From: gaohongtao Date: Mon, 20 Nov 2017 10:43:37 +0800 Subject: [PATCH 3/4] Fix test case --- .../skywalking/apm/plugin/esjob/JobExecutorInterceptorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/test/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/test/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptorTest.java index 25d955639..6e946a709 100644 --- a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/test/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/src/test/java/org/skywalking/apm/plugin/esjob/JobExecutorInterceptorTest.java @@ -67,7 +67,7 @@ public class JobExecutorInterceptorTest { assertNotNull(spans); assertThat(spans.size(), is(1)); assertThat(spans.get(0).transform().getOperationName(), is("fooJob-test")); - assertThat(spans.get(0).transform().getComponentId(), is(23)); + assertThat(spans.get(0).transform().getComponentId(), is(24)); assertThat(spans.get(0).transform().getTags(0).getKey(), is("sharding_context")); assertThat(spans.get(0).transform().getTags(0).getValue(), is("ShardingContext(jobName=fooJob, taskId=fooJob1, shardingTotalCount=2, jobParameter=, shardingItem=1, shardingParameter=test)")); } From 31970312d1333c0e72e7cacd9eb44b10b8655593 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=90=B4=E6=99=9F=20Wu=20Sheng?= Date: Mon, 4 Dec 2017 10:07:27 +0800 Subject: [PATCH 4/4] Update pom.xml --- apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml index efcc30e36..929d4ff0b 100644 --- a/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/elastic-job-2.x-plugin/pom.xml @@ -5,7 +5,7 @@ apm-sdk-plugin org.skywalking - 3.2.5-2017 + 3.3.0-2017 4.0.0 @@ -51,4 +51,4 @@ - \ No newline at end of file +