From b3c263fd1fdb6c9a22b01f1428a85496aa8b2140 Mon Sep 17 00:00:00 2001 From: ascrutae Date: Thu, 11 Jan 2018 11:36:51 +0800 Subject: [PATCH 1/4] [Agent] Support the version 9.4.x of postgresql jdbc driver --- ...redStatementExecuteMethodsInterceptor.java | 76 +++++++++++++++++++ .../StatementExecuteMethodsInterceptor.java | 5 +- .../apm/plugin/jdbc/postgresql/Variables.java | 25 ++++++ ...AbstractJdbc2StatementInstrumentation.java | 5 +- .../PgCallableStatementInstrumentation.java | 60 +++++++++++++++ .../PgPreparedStatementInstrumentation.java | 65 ++++++++++++++++ .../define/PgStatementInstrumentation.java | 68 +++++++++++++++++ .../src/main/resources/skywalking-plugin.def | 3 + 8 files changed, 302 insertions(+), 5 deletions(-) create mode 100644 apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/PreparedStatementExecuteMethodsInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/Variables.java create mode 100644 apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgCallableStatementInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgPreparedStatementInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgStatementInstrumentation.java diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/PreparedStatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/PreparedStatementExecuteMethodsInterceptor.java new file mode 100644 index 000000000..6ad648c24 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/PreparedStatementExecuteMethodsInterceptor.java @@ -0,0 +1,76 @@ +/* + * 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.jdbc.postgresql; + +import java.lang.reflect.Method; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; +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.plugin.jdbc.define.StatementEnhanceInfos; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; + +/** + * {@link PreparedStatementExecuteMethodsInterceptor} create the exit span when the client call the interceptor methods. + * + * @author zhangxin + */ +public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + StatementEnhanceInfos cacheObject = (StatementEnhanceInfos)objInst.getSkyWalkingDynamicField(); + ConnectionInfo connectInfo = cacheObject.getConnectionInfo(); + AbstractSpan span = ContextManager.createExitSpan(buildOperationName(connectInfo, method.getName(), cacheObject.getStatementName()), connectInfo.getDatabasePeer()); + Tags.DB_TYPE.set(span, "sql"); + Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); + Tags.DB_STATEMENT.set(span, cacheObject.getSql()); + span.setComponent(connectInfo.getComponent()); + + SpanLayer.asDB(span); + } + + @Override + public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, + Object ret) throws Throwable { + StatementEnhanceInfos cacheObject = (StatementEnhanceInfos)objInst.getSkyWalkingDynamicField(); + if (cacheObject.getConnectionInfo() != null) { + ContextManager.stopSpan(); + } + return ret; + } + + @Override public final void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + StatementEnhanceInfos cacheObject = (StatementEnhanceInfos)objInst.getSkyWalkingDynamicField(); + if (cacheObject.getConnectionInfo() != null) { + ContextManager.activeSpan().errorOccurred().log(t); + } + } + + private String buildOperationName(ConnectionInfo connectionInfo, String methodName, String statementName) { + return connectionInfo.getDBType() + "/JDBI/" + statementName + "/" + methodName; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/StatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/StatementExecuteMethodsInterceptor.java index ed198b3ed..fd7562656 100644 --- a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/StatementExecuteMethodsInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/StatementExecuteMethodsInterceptor.java @@ -16,7 +16,6 @@ * */ - package org.apache.skywalking.apm.plugin.jdbc.postgresql; import java.lang.reflect.Method; @@ -26,8 +25,8 @@ import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; 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.plugin.jdbc.define.StatementEnhanceInfos; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; /** @@ -45,7 +44,7 @@ public class StatementExecuteMethodsInterceptor implements InstanceMethodsAround AbstractSpan span = ContextManager.createExitSpan(buildOperationName(connectInfo, method.getName(), cacheObject.getStatementName()), connectInfo.getDatabasePeer()); Tags.DB_TYPE.set(span, "sql"); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); - Tags.DB_STATEMENT.set(span, cacheObject.getSql()); + Tags.DB_STATEMENT.set(span, (String)allArguments[0]); span.setComponent(connectInfo.getComponent()); SpanLayer.asDB(span); diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/Variables.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/Variables.java new file mode 100644 index 000000000..d92d9658e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/Variables.java @@ -0,0 +1,25 @@ +/* + * 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.jdbc.postgresql; + +public final class Variables { + public static final String PG_PREPARED_STATEMENT_EXECUTE_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.postgresql.PreparedStatementExecuteMethodsInterceptor"; + + public static final String PG_STATEMENT_EXECUTE_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.postgresql.StatementExecuteMethodsInterceptor"; +} diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/AbstractJdbc2StatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/AbstractJdbc2StatementInstrumentation.java index 662428aa9..ebea4068f 100644 --- a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/AbstractJdbc2StatementInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/AbstractJdbc2StatementInstrumentation.java @@ -30,6 +30,7 @@ import org.apache.skywalking.apm.plugin.jdbc.postgresql.StatementExecuteMethodsI import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; +import static org.apache.skywalking.apm.plugin.jdbc.postgresql.Variables.PG_PREPARED_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; /** * {@link AbstractJdbc2StatementInstrumentation} intercept the following methods that the class which extend {@link @@ -49,7 +50,7 @@ import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName public class AbstractJdbc2StatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String ENHANCE_CLASS = "org.postgresql.jdbc2.AbstractJdbc2Statement"; - private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.postgresql.StatementExecuteMethodsInterceptor"; + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[0]; @@ -69,7 +70,7 @@ public class AbstractJdbc2StatementInstrumentation extends ClassInstanceMethodsE } @Override public String getMethodsInterceptor() { - return INTERCEPTOR_CLASS; + return PG_PREPARED_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; } @Override public boolean isOverrideArgs() { diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgCallableStatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgCallableStatementInstrumentation.java new file mode 100644 index 000000000..32ecb2500 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgCallableStatementInstrumentation.java @@ -0,0 +1,60 @@ +/* + * 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.jdbc.postgresql.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.named; +import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; +import static org.apache.skywalking.apm.plugin.jdbc.postgresql.Variables.PG_PREPARED_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; + +public class PgCallableStatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("executeWithFlags").and(takesArgumentWithType(0, "int")) + .or(named("executeUpdate")); + } + + @Override public String getMethodsInterceptor() { + return PG_PREPARED_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName("org.postgresql.jdbc.PgCallableStatement"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgPreparedStatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgPreparedStatementInstrumentation.java new file mode 100644 index 000000000..5ca582fe3 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgPreparedStatementInstrumentation.java @@ -0,0 +1,65 @@ +/* + * 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.jdbc.postgresql.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.named; +import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; +import static org.apache.skywalking.apm.plugin.jdbc.postgresql.Variables.PG_PREPARED_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; + +/** + * @author zhang xin + */ +public class PgPreparedStatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("execute").and(takesArgumentWithType(0, "java.lang.String")) + .or(named("executeWithFlags").and(takesArgumentWithType(0, "int"))) + .or(named("executeQuery")) + .or(named("executeUpdate")); + } + + @Override public String getMethodsInterceptor() { + return PG_PREPARED_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName("org.postgresql.jdbc.PgPreparedStatement"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgStatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgStatementInstrumentation.java new file mode 100644 index 000000000..8fe16747c --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/PgStatementInstrumentation.java @@ -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.plugin.jdbc.postgresql.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.named; +import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; +import static org.apache.skywalking.apm.plugin.jdbc.postgresql.Variables.PG_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; + +/** + * @author zhang xin + */ +public class PgStatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("execute").and(takesArgumentWithType(0, "java.lang.String")) + .or(named("execute").and(takesArgumentWithType(0, "java.lang.String[]"))) + .or(named("executeQuery")) + .or(named("executeUpdate").and(takesArgumentWithType(0, "java.lang.String[]"))) + .or(named("executeUpdate").and(takesArgumentWithType(0, "java.lang.String"))) + .or(named("executeLargeUpdate")); + } + + @Override public String getMethodsInterceptor() { + return PG_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName("org.postgresql.jdbc.PgStatement"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/resources/skywalking-plugin.def index 77839a7d8..549f50d30 100644 --- a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/resources/skywalking-plugin.def @@ -3,3 +3,6 @@ postgresql-8.x=org.apache.skywalking.apm.plugin.jdbc.postgresql.define.Jdbc3Conn postgresql-8.x=org.apache.skywalking.apm.plugin.jdbc.postgresql.define.Jdbc4ConnectionInstrumentation postgresql-8.x=org.apache.skywalking.apm.plugin.jdbc.postgresql.define.ConnectionInstrumentation postgresql-8.x=org.apache.skywalking.apm.plugin.jdbc.postgresql.define.AbstractJdbc2StatementInstrumentation +postgresql-8.x=org.apache.skywalking.apm.plugin.jdbc.postgresql.define.PgCallableStatementInstrumentation +postgresql-8.x=org.apache.skywalking.apm.plugin.jdbc.postgresql.define.PgPreparedStatementInstrumentation +postgresql-8.x=org.apache.skywalking.apm.plugin.jdbc.postgresql.define.PgStatementInstrumentation From 8f49c973bea9477a2609b6dd4cb94d328322307d Mon Sep 17 00:00:00 2001 From: wusheng Date: Thu, 11 Jan 2018 15:53:40 +0800 Subject: [PATCH 2/4] Protect the background processes. --- .../parser/provider/buffer/OffsetManager.java | 6 ++- .../provider/buffer/SegmentBufferReader.java | 5 ++- .../SegmentStandardizationWorker.java | 7 ++- .../worker/timer/PersistenceTimer.java | 5 ++- .../storage/es/DataTTLKeeperTimer.java | 8 +++- apm-collector/pom.xml | 5 +++ .../util/RunnableWithExceptionProtection.java | 45 +++++++++++++++++++ .../apm/agent/core/jvm/JVMService.java | 16 +++++-- .../remote/AppAndServiceRegisterClient.java | 7 ++- .../remote/CollectorDiscoveryService.java | 12 ++++- .../agent/core/remote/GRPCChannelManager.java | 7 ++- .../agent/core/sampling/SamplingService.java | 9 +++- 12 files changed, 117 insertions(+), 15 deletions(-) create mode 100644 apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/RunnableWithExceptionProtection.java diff --git a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/buffer/OffsetManager.java b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/buffer/OffsetManager.java index 12899710e..fbd3d0251 100644 --- a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/buffer/OffsetManager.java +++ b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/buffer/OffsetManager.java @@ -28,6 +28,7 @@ import org.apache.skywalking.apm.collector.core.util.CollectionUtils; import org.apache.skywalking.apm.collector.core.util.Const; import org.apache.skywalking.apm.collector.core.util.FileUtils; import org.apache.skywalking.apm.collector.core.util.TimeBucketUtils; +import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,7 +71,10 @@ public enum OffsetManager { offset.deserialize(offsetRecord); initialized = true; - Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(this::flush, 10, 3, TimeUnit.SECONDS); + Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate( + new RunnableWithExceptionProtection(this::flush, + t -> logger.error("flush offset file in background failure.", t) + ), 10, 3, TimeUnit.SECONDS); } } diff --git a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/buffer/SegmentBufferReader.java b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/buffer/SegmentBufferReader.java index d2e41f4e5..11005ea97 100644 --- a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/buffer/SegmentBufferReader.java +++ b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/buffer/SegmentBufferReader.java @@ -34,6 +34,7 @@ import org.apache.skywalking.apm.collector.core.util.CollectionUtils; import org.apache.skywalking.apm.collector.core.util.Const; import org.apache.skywalking.apm.collector.core.util.StringUtils; import org.apache.skywalking.apm.network.proto.UpstreamSegment; +import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -50,7 +51,9 @@ public enum SegmentBufferReader { public void initialize(ModuleManager moduleManager) { this.moduleManager = moduleManager; - Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(this::preRead, 3, 3, TimeUnit.SECONDS); + Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate( + new RunnableWithExceptionProtection(this::preRead, + t -> logger.error("Segment buffer pre read failure.", t)), 3, 3, TimeUnit.SECONDS); } public void setSegmentParserListenerManager(SegmentParserListenerManager listenerManager) { diff --git a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/standardization/SegmentStandardizationWorker.java b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/standardization/SegmentStandardizationWorker.java index 93d0c2ef0..518a90430 100644 --- a/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/standardization/SegmentStandardizationWorker.java +++ b/apm-collector/apm-collector-analysis/analysis-segment-parser/segment-parser-provider/src/main/java/org/apache/skywalking/apm/collector/analysis/segment/parser/provider/parser/standardization/SegmentStandardizationWorker.java @@ -26,6 +26,7 @@ import org.apache.skywalking.apm.collector.analysis.worker.model.base.AbstractLo import org.apache.skywalking.apm.collector.analysis.worker.model.base.AbstractLocalAsyncWorkerProvider; import org.apache.skywalking.apm.collector.analysis.worker.model.base.WorkerException; import org.apache.skywalking.apm.collector.core.module.ModuleManager; +import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -34,7 +35,7 @@ import org.slf4j.LoggerFactory; */ public class SegmentStandardizationWorker extends AbstractLocalAsyncWorker { - private final Logger logger = LoggerFactory.getLogger(SegmentStandardizationWorker.class); + private static final Logger logger = LoggerFactory.getLogger(SegmentStandardizationWorker.class); public SegmentStandardizationWorker(ModuleManager moduleManager) { super(moduleManager); @@ -70,7 +71,9 @@ public class SegmentStandardizationWorker extends AbstractLocalAsyncWorker logger.error("Segment standardization failure.", t)), 10, 3, TimeUnit.SECONDS); } } } diff --git a/apm-collector/apm-collector-analysis/analysis-worker-model/src/main/java/org/apache/skywalking/apm/collector/analysis/worker/timer/PersistenceTimer.java b/apm-collector/apm-collector-analysis/analysis-worker-model/src/main/java/org/apache/skywalking/apm/collector/analysis/worker/timer/PersistenceTimer.java index dd3a26719..dd7a34252 100644 --- a/apm-collector/apm-collector-analysis/analysis-worker-model/src/main/java/org/apache/skywalking/apm/collector/analysis/worker/timer/PersistenceTimer.java +++ b/apm-collector/apm-collector-analysis/analysis-worker-model/src/main/java/org/apache/skywalking/apm/collector/analysis/worker/timer/PersistenceTimer.java @@ -27,6 +27,7 @@ import org.apache.skywalking.apm.collector.analysis.worker.model.impl.Persistenc import org.apache.skywalking.apm.collector.core.module.ModuleManager; import org.apache.skywalking.apm.collector.storage.StorageModule; import org.apache.skywalking.apm.collector.storage.base.dao.IBatchDAO; +import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -49,7 +50,9 @@ public class PersistenceTimer { // final long timeInterval = EsConfig.Es.Persistence.Timer.VALUE * 1000; final long timeInterval = 3; IBatchDAO batchDAO = moduleManager.find(StorageModule.NAME).getService(IBatchDAO.class); - Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(() -> extractDataAndSave(batchDAO, persistenceWorkers), 1, timeInterval, TimeUnit.SECONDS); + Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate( + new RunnableWithExceptionProtection(() -> extractDataAndSave(batchDAO, persistenceWorkers), + t -> logger.error("Extract data and save failure.", t)), 1, timeInterval, TimeUnit.SECONDS); } private void extractDataAndSave(IBatchDAO batchDAO, List persistenceWorkers) { diff --git a/apm-collector/apm-collector-storage/collector-storage-es-provider/src/main/java/org/apache/skywalking/apm/collector/storage/es/DataTTLKeeperTimer.java b/apm-collector/apm-collector-storage/collector-storage-es-provider/src/main/java/org/apache/skywalking/apm/collector/storage/es/DataTTLKeeperTimer.java index 13f354843..ca152a492 100644 --- a/apm-collector/apm-collector-storage/collector-storage-es-provider/src/main/java/org/apache/skywalking/apm/collector/storage/es/DataTTLKeeperTimer.java +++ b/apm-collector/apm-collector-storage/collector-storage-es-provider/src/main/java/org/apache/skywalking/apm/collector/storage/es/DataTTLKeeperTimer.java @@ -35,11 +35,15 @@ import org.apache.skywalking.apm.collector.storage.dao.imp.IInstanceMinuteMetric import org.apache.skywalking.apm.collector.storage.dao.memorymp.IMemorySecondMetricPersistenceDAO; import org.apache.skywalking.apm.collector.storage.dao.mpoolmp.IMemoryPoolSecondMetricPersistenceDAO; import org.apache.skywalking.apm.collector.storage.dao.srmp.IServiceReferenceMinuteMetricPersistenceDAO; +import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; /** * @author peng-yongsheng */ public class DataTTLKeeperTimer { + private final Logger logger = LoggerFactory.getLogger(StorageModuleEsProvider.class); private final ModuleManager moduleManager; private final StorageModuleEsNamingListener namingListener; @@ -55,7 +59,9 @@ public class DataTTLKeeperTimer { } public void start() { - Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(this::delete, 1, 8, TimeUnit.HOURS); + Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate( + new RunnableWithExceptionProtection(this::delete, + t -> logger.error("Remove data in background failure.", t)), 1, 8, TimeUnit.HOURS); } private void delete() { diff --git a/apm-collector/pom.xml b/apm-collector/pom.xml index 2389168c7..70699a1dd 100644 --- a/apm-collector/pom.xml +++ b/apm-collector/pom.xml @@ -49,6 +49,11 @@ + + org.apache.skywalking + apm-util + ${project.version} + org.slf4j slf4j-api diff --git a/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/RunnableWithExceptionProtection.java b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/RunnableWithExceptionProtection.java new file mode 100644 index 000000000..d03e83258 --- /dev/null +++ b/apm-commons/apm-util/src/main/java/org/apache/skywalking/apm/util/RunnableWithExceptionProtection.java @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.util; + +/** + * @author wusheng + */ +public class RunnableWithExceptionProtection implements Runnable { + private Runnable run; + private CallbackWhenException callback; + + public RunnableWithExceptionProtection(Runnable run, CallbackWhenException callback) { + this.run = run; + this.callback = callback; + } + + @Override + public void run() { + try { + run.run(); + } catch (Throwable t) { + callback.handle(t); + } + } + + public interface CallbackWhenException { + void handle(Throwable t); + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/JVMService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/JVMService.java index 15d185526..8d47590e1 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/JVMService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/jvm/JVMService.java @@ -16,7 +16,6 @@ * */ - package org.apache.skywalking.apm.agent.core.jvm; import io.grpc.ManagedChannel; @@ -43,6 +42,7 @@ import org.apache.skywalking.apm.agent.core.remote.GRPCChannelStatus; import org.apache.skywalking.apm.network.proto.JVMMetric; import org.apache.skywalking.apm.network.proto.JVMMetrics; import org.apache.skywalking.apm.network.proto.JVMMetricsServiceGrpc; +import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; /** * The JVMService represents a timer, @@ -57,6 +57,7 @@ public class JVMService implements BootService, Runnable { private volatile ScheduledFuture collectMetricFuture; private volatile ScheduledFuture sendMetricFuture; private Sender sender; + @Override public void beforeBoot() throws Throwable { queue = new LinkedBlockingQueue(Config.Jvm.BUFFER_SIZE); @@ -68,10 +69,19 @@ public class JVMService implements BootService, Runnable { public void boot() throws Throwable { collectMetricFuture = Executors .newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("JVMService-produce")) - .scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS); + .scheduleAtFixedRate(new RunnableWithExceptionProtection(this, new RunnableWithExceptionProtection.CallbackWhenException() { + @Override public void handle(Throwable t) { + logger.error("JVMService produces metrics failure.", t); + } + }), 0, 1, TimeUnit.SECONDS); sendMetricFuture = Executors .newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("JVMService-consume")) - .scheduleAtFixedRate(sender, 0, 1, TimeUnit.SECONDS); + .scheduleAtFixedRate(new RunnableWithExceptionProtection(sender, new RunnableWithExceptionProtection.CallbackWhenException() { + @Override public void handle(Throwable t) { + logger.error("JVMService consumes and upload failure.", t); + } + } + ), 0, 1, TimeUnit.SECONDS); } @Override diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/AppAndServiceRegisterClient.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/AppAndServiceRegisterClient.java index db5b3d992..6a223d61e 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/AppAndServiceRegisterClient.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/AppAndServiceRegisterClient.java @@ -46,6 +46,7 @@ import org.apache.skywalking.apm.network.proto.ApplicationRegisterServiceGrpc; import org.apache.skywalking.apm.network.proto.InstanceDiscoveryServiceGrpc; import org.apache.skywalking.apm.network.proto.NetworkAddressRegisterServiceGrpc; import org.apache.skywalking.apm.network.proto.ServiceNameDiscoveryServiceGrpc; +import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; /** * @author wusheng @@ -87,7 +88,11 @@ public class AppAndServiceRegisterClient implements BootService, GRPCChannelList public void boot() throws Throwable { applicationRegisterFuture = Executors .newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("AppAndServiceRegisterClient")) - .scheduleAtFixedRate(this, 0, Config.Collector.APP_AND_SERVICE_REGISTER_CHECK_INTERVAL, TimeUnit.SECONDS); + .scheduleAtFixedRate(new RunnableWithExceptionProtection(this, new RunnableWithExceptionProtection.CallbackWhenException() { + @Override public void handle(Throwable t) { + logger.error("unexpected exception.", t); + } + }), 0, Config.Collector.APP_AND_SERVICE_REGISTER_CHECK_INTERVAL, TimeUnit.SECONDS); } @Override diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/CollectorDiscoveryService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/CollectorDiscoveryService.java index 8850ba9fd..f7910f71d 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/CollectorDiscoveryService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/CollectorDiscoveryService.java @@ -16,7 +16,6 @@ * */ - package org.apache.skywalking.apm.agent.core.remote; import java.util.concurrent.Executors; @@ -25,6 +24,9 @@ import java.util.concurrent.TimeUnit; import org.apache.skywalking.apm.agent.core.boot.BootService; import org.apache.skywalking.apm.agent.core.boot.DefaultNamedThreadFactory; 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.util.RunnableWithExceptionProtection; /** * The CollectorDiscoveryService is responsible for start {@link DiscoveryRestServiceClient}. @@ -32,6 +34,7 @@ import org.apache.skywalking.apm.agent.core.conf.Config; * @author wusheng */ public class CollectorDiscoveryService implements BootService { + private static final ILog logger = LogManager.getLogger(CollectorDiscoveryService.class); private ScheduledFuture future; @Override @@ -42,7 +45,12 @@ public class CollectorDiscoveryService implements BootService { @Override public void boot() throws Throwable { future = Executors.newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("CollectorDiscoveryService")) - .scheduleAtFixedRate(new DiscoveryRestServiceClient(), 0, + .scheduleAtFixedRate(new RunnableWithExceptionProtection(new DiscoveryRestServiceClient(), + new RunnableWithExceptionProtection.CallbackWhenException() { + @Override public void handle(Throwable t) { + logger.error("unexpected exception.", t); + } + }), 0, Config.Collector.DISCOVERY_CHECK_INTERVAL, TimeUnit.SECONDS); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java index 8cfca0b7b..2f522f0fc 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/remote/GRPCChannelManager.java @@ -38,6 +38,7 @@ import org.apache.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; 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.conf.Config; +import org.apache.skywalking.apm.util.RunnableWithExceptionProtection; /** * @author wusheng @@ -60,7 +61,11 @@ public class GRPCChannelManager implements BootService, Runnable { public void boot() throws Throwable { connectCheckFuture = Executors .newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("GRPCChannelManager")) - .scheduleAtFixedRate(this, 0, Config.Collector.GRPC_CHANNEL_CHECK_INTERVAL, TimeUnit.SECONDS); + .scheduleAtFixedRate(new RunnableWithExceptionProtection(this, new RunnableWithExceptionProtection.CallbackWhenException() { + @Override public void handle(Throwable t) { + logger.error("unexpected exception.", t); + } + }), 0, Config.Collector.GRPC_CHANNEL_CHECK_INTERVAL, TimeUnit.SECONDS); } @Override diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/sampling/SamplingService.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/sampling/SamplingService.java index e2910bba6..c902e90fd 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/sampling/SamplingService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/sampling/SamplingService.java @@ -30,6 +30,7 @@ import org.apache.skywalking.apm.agent.core.conf.Config; import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; 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.util.RunnableWithExceptionProtection; /** * The SamplingService take charge of how to sample the {@link TraceSegment}. Every {@link TraceSegment}s @@ -66,12 +67,16 @@ public class SamplingService implements BootService { this.resetSamplingFactor(); ScheduledExecutorService service = Executors .newSingleThreadScheduledExecutor(new DefaultNamedThreadFactory("SamplingService")); - scheduledFuture = service.scheduleAtFixedRate(new Runnable() { + scheduledFuture = service.scheduleAtFixedRate(new RunnableWithExceptionProtection(new Runnable() { @Override public void run() { resetSamplingFactor(); } - }, 0, 3, TimeUnit.SECONDS); + }, new RunnableWithExceptionProtection.CallbackWhenException() { + @Override public void handle(Throwable t) { + logger.error("unexpected exception.", t); + } + }), 0, 3, TimeUnit.SECONDS); logger.debug("Agent sampling mechanism started. Sample {} traces in 10 seconds.", Config.Agent.SAMPLE_N_PER_3_SECS); } } From 97b577864f3145046b791ab41feeba009a22eab3 Mon Sep 17 00:00:00 2001 From: ascrutae Date: Thu, 11 Jan 2018 16:08:48 +0800 Subject: [PATCH 3/4] [Agent] Support jdbc4, jdbc3 and jdbc42 of postgresql driver --- .../define/ConnectionInstrumentation.java | 9 ++- .../define/MultiClassNameMatch.java | 68 +++++++++++++++++++ 2 files changed, 74 insertions(+), 3 deletions(-) create mode 100644 apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/MultiClassNameMatch.java diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/ConnectionInstrumentation.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/ConnectionInstrumentation.java index 24cc182e0..bb0d70ee4 100644 --- a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/ConnectionInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/ConnectionInstrumentation.java @@ -29,7 +29,7 @@ import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; -import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; +import static org.apache.skywalking.apm.plugin.jdbc.postgresql.define.MultiClassNameMatch.byMultiClassMatch; /** * {@link ConnectionInstrumentation} intercept the following methods that the class which extend {@link @@ -49,8 +49,11 @@ import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { private static final String PREPARE_STATEMENT_METHOD_WITH_STRING_ARRAY_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.postgresql.JDBCPrepareStatementWithStringArrayInterceptor"; - public static final String ENHANCE_CLASS = "org.postgresql.jdbc.PgConnection"; + public static final String PG_CONNECTION_ENHANCE_CLASS = "org.postgresql.jdbc.PgConnection"; public static final String STRING_ARRAY_ARGUMENT_TYPE = "java.lang.String[]"; + public static final String PG_JDBC42_CONNECTION_ENHANCE_CLASS = "org.postgresql.jdbc42.Jdbc42Connection"; + public static final String PG_JDBC3_CONNECTION_ENHANCE_CLASS = "org.postgresql.jdbc3g.Jdbc3gConnection"; + public static final String PG_JDBC4_CONNECTION_ENHANCE_CLASS = "org.postgresql.jdbc4.Jdbc4Connection"; @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { return new ConstructorInterceptPoint[0]; @@ -127,6 +130,6 @@ public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePlugin } @Override protected ClassMatch enhanceClass() { - return byName(ENHANCE_CLASS); + return byMultiClassMatch(PG_CONNECTION_ENHANCE_CLASS, PG_JDBC42_CONNECTION_ENHANCE_CLASS, PG_JDBC3_CONNECTION_ENHANCE_CLASS, PG_JDBC4_CONNECTION_ENHANCE_CLASS); } } diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/MultiClassNameMatch.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/MultiClassNameMatch.java new file mode 100644 index 000000000..e36e27a1f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/MultiClassNameMatch.java @@ -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.plugin.jdbc.postgresql.define; + +import java.util.Arrays; +import java.util.List; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.IndirectMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +/** + * Match class with a given set of classes. + * + * @author zhangxin + */ +public class MultiClassNameMatch implements IndirectMatch { + + private List matchClassNames; + + private MultiClassNameMatch(String[] classNames) { + if (classNames == null || classNames.length == 0) { + throw new IllegalArgumentException("match class names is null"); + } + this.matchClassNames = Arrays.asList(classNames); + } + + @Override + public ElementMatcher.Junction buildJunction() { + ElementMatcher.Junction junction = null; + for (String name : matchClassNames) { + if (junction == null) { + junction = named(name); + } else { + junction = junction.or(named(name)); + } + } + return junction; + } + + @Override + public boolean isMatch(TypeDescription typeDescription) { + return matchClassNames.contains(typeDescription.getTypeName()); + } + + public static ClassMatch byMultiClassMatch(String... classNames) { + return new MultiClassNameMatch(classNames); + } +} From c6e593f6f40fee4501675893c7102361c2e64f39 Mon Sep 17 00:00:00 2001 From: ascrutae Date: Thu, 11 Jan 2018 16:45:10 +0800 Subject: [PATCH 4/4] refactory MultiClassNameMatch code --- .../plugin/match}/MultiClassNameMatch.java | 4 +- .../mysql/define/CallableInstrumentation.java | 2 +- .../mysql/define/DriverInstrumentation.java | 2 +- .../Mysql5xConnectionInstrumentation.java | 2 +- .../PreparedStatementInstrumentation.java | 2 +- .../define/StatementInstrumentation.java | 2 +- ...AbstractJdbc2StatementInstrumentation.java | 22 ++++-- .../define/ConnectionInstrumentation.java | 2 +- .../define/MultiClassNameMatch.java | 68 ------------------- 9 files changed, 24 insertions(+), 82 deletions(-) rename apm-sniffer/{apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define => apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match}/MultiClassNameMatch.java (91%) delete mode 100644 apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/MultiClassNameMatch.java diff --git a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/MultiClassNameMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/MultiClassNameMatch.java similarity index 91% rename from apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/MultiClassNameMatch.java rename to apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/MultiClassNameMatch.java index 66b2e8840..6453facdf 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/MultiClassNameMatch.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/plugin/match/MultiClassNameMatch.java @@ -17,14 +17,12 @@ */ -package org.apache.skywalking.apm.plugin.jdbc.mysql.define; +package org.apache.skywalking.apm.agent.core.plugin.match; import java.util.Arrays; import java.util.List; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; -import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; -import org.apache.skywalking.apm.agent.core.plugin.match.IndirectMatch; import static net.bytebuddy.matcher.ElementMatchers.named; diff --git a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/CallableInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/CallableInstrumentation.java index e8605a35d..4afeb7f0c 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/CallableInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/CallableInstrumentation.java @@ -27,7 +27,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInst import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; -import static org.apache.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMatch; +import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch.byMultiClassMatch; /** * {@link CallableInstrumentation} define that the mysql-2.x plugin intercepts the following methods in the {@link diff --git a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/DriverInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/DriverInstrumentation.java index 27b38e174..f17d3da04 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/DriverInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/DriverInstrumentation.java @@ -22,7 +22,7 @@ package org.apache.skywalking.apm.plugin.jdbc.mysql.define; import org.apache.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation; import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; -import static org.apache.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMatch; +import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch.byMultiClassMatch; /** * {@link DriverInstrumentation} presents that skywalking intercepts {@link com.mysql.jdbc.Driver}. diff --git a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/Mysql5xConnectionInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/Mysql5xConnectionInstrumentation.java index 512b0c8ee..6c4860176 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/Mysql5xConnectionInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/Mysql5xConnectionInstrumentation.java @@ -21,7 +21,7 @@ package org.apache.skywalking.apm.plugin.jdbc.mysql.define; import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; -import static org.apache.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMatch; +import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch.byMultiClassMatch; /** * {@link Mysql5xConnectionInstrumentation } interceptor {@link com.mysql.cj.jdbc.ConnectionImpl} and diff --git a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/PreparedStatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/PreparedStatementInstrumentation.java index 6997cb7a5..dc268942a 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/PreparedStatementInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/PreparedStatementInstrumentation.java @@ -27,7 +27,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterc import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; -import static org.apache.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMatch; +import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch.byMultiClassMatch; /** * {@link PreparedStatementInstrumentation} define that the mysql-2.x plugin intercepts the following methods in the diff --git a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/StatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/StatementInstrumentation.java index 947e6b12c..a5078cad3 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/StatementInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/mysql-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/define/StatementInstrumentation.java @@ -27,7 +27,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterc import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; -import static org.apache.skywalking.apm.plugin.jdbc.mysql.define.MultiClassNameMatch.byMultiClassMatch; +import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch.byMultiClassMatch; /** * {@link StatementInstrumentation} intercepts the following methods in the {@link diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/AbstractJdbc2StatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/AbstractJdbc2StatementInstrumentation.java index ebea4068f..1e4e6107b 100644 --- a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/AbstractJdbc2StatementInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/AbstractJdbc2StatementInstrumentation.java @@ -31,6 +31,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; import static org.apache.skywalking.apm.plugin.jdbc.postgresql.Variables.PG_PREPARED_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; +import static org.apache.skywalking.apm.plugin.jdbc.postgresql.Variables.PG_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; /** * {@link AbstractJdbc2StatementInstrumentation} intercept the following methods that the class which extend {@link @@ -61,18 +62,29 @@ public class AbstractJdbc2StatementInstrumentation extends ClassInstanceMethodsE new InstanceMethodsInterceptPoint() { @Override public ElementMatcher getMethodsMatcher() { return named("execute").and(takesArguments(0)) - .or(named("execute").and(takesArguments(1))) - .or(named("executeBatch")) .or(named("executeQuery").and(takesArguments(0))) - .or(named("executeQuery").and(takesArguments(1))) - .or(named("executeUpdate").and(takesArguments(0))) - .or(named("executeUpdate").and(takesArguments(1))); + .or(named("executeUpdate").and(takesArguments(0))); } @Override public String getMethodsInterceptor() { return PG_PREPARED_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; } + @Override public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("execute").and(takesArguments(1)) + .or(named("executeQuery").and(takesArguments(1))) + .or(named("executeUpdate").and(takesArguments(1))); + } + + @Override public String getMethodsInterceptor() { + return PG_STATEMENT_EXECUTE_METHOD_INTERCEPTOR; + } + @Override public boolean isOverrideArgs() { return false; } diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/ConnectionInstrumentation.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/ConnectionInstrumentation.java index bb0d70ee4..64250bc0e 100644 --- a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/ConnectionInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/ConnectionInstrumentation.java @@ -29,7 +29,7 @@ import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; -import static org.apache.skywalking.apm.plugin.jdbc.postgresql.define.MultiClassNameMatch.byMultiClassMatch; +import static org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch.byMultiClassMatch; /** * {@link ConnectionInstrumentation} intercept the following methods that the class which extend {@link diff --git a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/MultiClassNameMatch.java b/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/MultiClassNameMatch.java deleted file mode 100644 index e36e27a1f..000000000 --- a/apm-sniffer/apm-sdk-plugin/postgresql-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/postgresql/define/MultiClassNameMatch.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.jdbc.postgresql.define; - -import java.util.Arrays; -import java.util.List; -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.matcher.ElementMatcher; -import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; -import org.apache.skywalking.apm.agent.core.plugin.match.IndirectMatch; - -import static net.bytebuddy.matcher.ElementMatchers.named; - -/** - * Match class with a given set of classes. - * - * @author zhangxin - */ -public class MultiClassNameMatch implements IndirectMatch { - - private List matchClassNames; - - private MultiClassNameMatch(String[] classNames) { - if (classNames == null || classNames.length == 0) { - throw new IllegalArgumentException("match class names is null"); - } - this.matchClassNames = Arrays.asList(classNames); - } - - @Override - public ElementMatcher.Junction buildJunction() { - ElementMatcher.Junction junction = null; - for (String name : matchClassNames) { - if (junction == null) { - junction = named(name); - } else { - junction = junction.or(named(name)); - } - } - return junction; - } - - @Override - public boolean isMatch(TypeDescription typeDescription) { - return matchClassNames.contains(typeDescription.getTypeName()); - } - - public static ClassMatch byMultiClassMatch(String... classNames) { - return new MultiClassNameMatch(classNames); - } -}