diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml index 96204abd1..b6b70ba2a 100644 --- a/.github/workflows/plugins-test.3.yaml +++ b/.github/workflows/plugins-test.3.yaml @@ -106,6 +106,7 @@ jobs: - grpc-generic-call-scenario - shenyu-2.4.x-grpc-scenario - shenyu-2.4.x-sofarpc-scenario + - impala-jdbc-2.6.x-scenario steps: - uses: actions/checkout@v2 with: diff --git a/CHANGES.md b/CHANGES.md index 49c45c229..8081c686b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -9,6 +9,7 @@ Release Notes. * Optimize ConfigInitializer to output warning messages when the config value is truncated. * Fix the default value of the Map field would merge rather than override by new values in the config. * Support to set the value of Map/List field to an empty map/list. +* Add plugin to support [Impala JDBC](https://www.cloudera.com/downloads/connectors/impala/jdbc/2-6-29.html) 2.6.x. #### Documentation diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java index 52930e987..f8a578466 100755 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -229,4 +229,6 @@ public class ComponentsDefine { public static final OfficialComponent NATS = new OfficialComponent(132, "Nats"); + public static final OfficialComponent IMPALA_JDBC_DRIVER = new OfficialComponent(133, "Impala-jdbc-driver"); + } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/tag/Tags.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/tag/Tags.java index 50d20d0ab..9b6c80961 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/tag/Tags.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/tag/Tags.java @@ -110,6 +110,8 @@ public final class Tags { public static final String VAL_LOCAL_SPAN_AS_LOGIC_ENDPOINT = "{\"logic-span\":true}"; + public static final StringTag SQL_PARAMETERS = new StringTag(19, "db.sql.parameters"); + /** * Creates a {@code StringTag} with the given key and cache it, if it's created before, simply return it without * creating a new one. diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/pom.xml new file mode 100644 index 000000000..aa37f023c --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/pom.xml @@ -0,0 +1,56 @@ + + + + + + 4.0.0 + + + org.apache.skywalking + apm-sdk-plugin + 8.13.0-SNAPSHOT + + + apm-impala-jdbc-2.6.x-plugin + impala-jdbc-2.6.x-plugin + jar + + + UTF-8 + + + + + org.apache.skywalking + apm-jdbc-commons + ${project.version} + provided + + + + + + + maven-deploy-plugin + + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateCallableStatementInterceptor.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateCallableStatementInterceptor.java new file mode 100644 index 000000000..d9cba567b --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateCallableStatementInterceptor.java @@ -0,0 +1,49 @@ +/* + * 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.impala; + +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; + +import java.lang.reflect.Method; + +public class CreateCallableStatementInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) { + if (ret instanceof EnhancedInstance) { + ((EnhancedInstance) ret).setSkyWalkingDynamicField(new StatementEnhanceInfos((ConnectionInfo) objInst.getSkyWalkingDynamicField(), (String) allArguments[0], "CallableStatement")); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreatePreparedStatementInterceptor.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreatePreparedStatementInterceptor.java new file mode 100644 index 000000000..75012b068 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreatePreparedStatementInterceptor.java @@ -0,0 +1,50 @@ +/* + * 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.impala; + +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; + +import java.lang.reflect.Method; + +public class CreatePreparedStatementInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) { + if (ret instanceof EnhancedInstance) { + ((EnhancedInstance) ret).setSkyWalkingDynamicField(new StatementEnhanceInfos((ConnectionInfo) objInst.getSkyWalkingDynamicField(), (String) allArguments[0], "PreparedStatement")); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateStatementInterceptor.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateStatementInterceptor.java new file mode 100644 index 000000000..38a5cf8f5 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateStatementInterceptor.java @@ -0,0 +1,50 @@ +/* + * 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.impala; + +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; + +import java.lang.reflect.Method; + +public class CreateStatementInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) { + if (ret instanceof EnhancedInstance) { + ((EnhancedInstance) ret).setSkyWalkingDynamicField(new StatementEnhanceInfos((ConnectionInfo) objInst.getSkyWalkingDynamicField(), "", "Statement")); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/PreparedStatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/PreparedStatementExecuteMethodsInterceptor.java new file mode 100644 index 000000000..8fee1f177 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/PreparedStatementExecuteMethodsInterceptor.java @@ -0,0 +1,93 @@ +/* + * 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.impala; + +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.JDBCPluginConfig; +import org.apache.skywalking.apm.plugin.jdbc.PreparedStatementParameterBuilder; +import org.apache.skywalking.apm.plugin.jdbc.SqlBodyUtil; +import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; + +import java.lang.reflect.Method; + +public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) { + StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField(); + ConnectionInfo connectInfo = cacheObject.getConnectionInfo(); + if (connectInfo == null) { + return; + } + 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, SqlBodyUtil.limitSqlBodySize(cacheObject.getSql())); + span.setComponent(connectInfo.getComponent()); + + if (JDBCPluginConfig.Plugin.JDBC.TRACE_SQL_PARAMETERS) { + final Object[] parameters = cacheObject.getParameters(); + if (parameters != null && parameters.length > 0) { + int maxIndex = cacheObject.getMaxIndex(); + Tags.SQL_PARAMETERS.set(span, getParameterString(parameters, maxIndex)); + } + } + + SpanLayer.asDB(span); + } + + @Override + public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Object ret) { + 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().log(t); + } + } + + private String buildOperationName(ConnectionInfo connectionInfo, String methodName, String statementName) { + return connectionInfo.getDBType() + "/JDBI/" + statementName + "/" + methodName; + } + + private String getParameterString(Object[] parameters, int maxIndex) { + return new PreparedStatementParameterBuilder() + .setParameters(parameters) + .setMaxIndex(maxIndex) + .build(); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/SetCatalogInterceptor.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/SetCatalogInterceptor.java new file mode 100644 index 000000000..9c55de827 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/SetCatalogInterceptor.java @@ -0,0 +1,48 @@ +/* + * 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.impala; + +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.trace.ConnectionInfo; + +import java.lang.reflect.Method; + +public class SetCatalogInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) { + Object dynamicField = objInst.getSkyWalkingDynamicField(); + if (dynamicField instanceof ConnectionInfo) { + ((ConnectionInfo) dynamicField).setDatabaseName(String.valueOf(allArguments[0])); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) { + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/StatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/StatementExecuteMethodsInterceptor.java new file mode 100644 index 000000000..8cc875400 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/StatementExecuteMethodsInterceptor.java @@ -0,0 +1,75 @@ +/* + * 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.impala; + +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.SqlBodyUtil; +import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; + +import java.lang.reflect.Method; + +public class StatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) { + StatementEnhanceInfos cacheObject = (StatementEnhanceInfos) objInst.getSkyWalkingDynamicField(); + ConnectionInfo connectInfo = cacheObject.getConnectionInfo(); + if (connectInfo != null) { + 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()); + String sql = allArguments.length > 0 ? (String) allArguments[0] : ""; + sql = SqlBodyUtil.limitSqlBodySize(sql); + Tags.DB_STATEMENT.set(span, sql); + span.setComponent(connectInfo.getComponent()); + SpanLayer.asDB(span); + } + } + + @Override + public final Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Object ret) { + 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().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/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/ConnectionInstrumentation.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/ConnectionInstrumentation.java new file mode 100644 index 000000000..8f18bad37 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/ConnectionInstrumentation.java @@ -0,0 +1,139 @@ +/* + * 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.impala.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.plugin.jdbc.define.Constants; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "com.cloudera.impala.jdbc.jdbc42.S42Connection"; + private static final String CREATE_STATEMENT_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.impala.CreateStatementInterceptor"; + private static final String CREATE_PREPARED_STATEMENT_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.impala.CreatePreparedStatementInterceptor"; + private static final String CREATE_CALLABLE_STATEMENT_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.impala.CreateCallableStatementInterceptor"; + private static final String SET_CATALOG_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.impala.SetCatalogInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.CREATE_STATEMENT_METHOD_NAME); + } + + @Override + public String getMethodsInterceptor() { + return CREATE_STATEMENT_INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.PREPARE_STATEMENT_METHOD_NAME); + } + + @Override + public String getMethodsInterceptor() { + return CREATE_PREPARED_STATEMENT_INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.PREPARE_CALL_METHOD_NAME); + } + + @Override + public String getMethodsInterceptor() { + return CREATE_CALLABLE_STATEMENT_INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named(Constants.COMMIT_METHOD_NAME) + .or(named(Constants.ROLLBACK_METHOD_NAME)) + .or(named(Constants.CLOSE_METHOD_NAME)) + .or(named(Constants.RELEASE_SAVE_POINT_METHOD_NAME)); + } + + @Override + public String getMethodsInterceptor() { + return Constants.SERVICE_METHOD_INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("setCatalog"); + } + + @Override + public String getMethodsInterceptor() { + return SET_CATALOG_INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/DriverInstrumentation.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/DriverInstrumentation.java new file mode 100644 index 000000000..faee59075 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/DriverInstrumentation.java @@ -0,0 +1,37 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.jdbc.impala.define; + +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.plugin.jdbc.define.AbstractDriverInstrumentation; + +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * {@link DriverInstrumentation} presents that skywalking intercepts. + */ +public class DriverInstrumentation extends AbstractDriverInstrumentation { + + private static final String ENHANCE_CLASS = "com.cloudera.impala.jdbc.Driver"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementIgnoredSetterInstrumentation.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementIgnoredSetterInstrumentation.java new file mode 100644 index 000000000..671ed2193 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementIgnoredSetterInstrumentation.java @@ -0,0 +1,34 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.jdbc.impala.define; + +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation; + +public class PreparedStatementIgnoredSetterInstrumentation extends + PreparedStatementInstrumentation { + + @Override + public final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new PSSetterDefinitionOfJDBCInstrumentation(true) + }; + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementInstrumentation.java new file mode 100644 index 000000000..a61dc51b8 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementInstrumentation.java @@ -0,0 +1,72 @@ +/* + * 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.impala.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.match.MultiClassNameMatch.byMultiClassMatch; + +public class PreparedStatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String IMPALA_PREPARED_STATEMENT_CLASS = "com.cloudera.impala.jdbc.jdbc42.S42PreparedStatement"; + private static final String PREPARED_STATEMENT_EXECUTE_METHODS_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.impala.PreparedStatementExecuteMethodsInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byMultiClassMatch( + IMPALA_PREPARED_STATEMENT_CLASS + ); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("execute") + .or(named("executeQuery")) + .or(named("executeUpdate")); + } + + @Override + public String getMethodsInterceptor() { + return PREPARED_STATEMENT_EXECUTE_METHODS_INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementNullSetterInstrumentation.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementNullSetterInstrumentation.java new file mode 100644 index 000000000..f61847c2e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementNullSetterInstrumentation.java @@ -0,0 +1,33 @@ +/* + * 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.impala.define; + +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint; + +public class PreparedStatementNullSetterInstrumentation extends PreparedStatementInstrumentation { + + @Override + public final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new JDBCPreparedStatementNullSetterInstanceMethodsInterceptPoint() + }; + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/Constants.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementSetterInstrumentation.java similarity index 58% rename from apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/Constants.java rename to apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementSetterInstrumentation.java index 8e717a6d2..cf4e9f2e2 100644 --- a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/Constants.java +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/PreparedStatementSetterInstrumentation.java @@ -16,10 +16,18 @@ * */ -package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2; +package org.apache.skywalking.apm.plugin.jdbc.impala.define; -import org.apache.skywalking.apm.agent.core.context.tag.StringTag; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.plugin.jdbc.PSSetterDefinitionOfJDBCInstrumentation; + +public class PreparedStatementSetterInstrumentation extends PreparedStatementInstrumentation { + + @Override + public final InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new PSSetterDefinitionOfJDBCInstrumentation(false) + }; + } -public class Constants { - public static final StringTag SQL_PARAMETERS = new StringTag("db.sql.parameters"); } diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/StatementInstrumentation.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/StatementInstrumentation.java new file mode 100644 index 000000000..90514e732 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/impala/define/StatementInstrumentation.java @@ -0,0 +1,71 @@ +/* + * 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.impala.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.match.NameMatch.byName; + +public class StatementInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + private static final String IMPALA_STATEMENT_CLASS_NAME = "com.cloudera.impala.jdbc.jdbc42.S42Statement"; + private static final String STATEMENT_EXECUTE_METHODS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.impala.StatementExecuteMethodsInterceptor"; + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("execute") + .or(named("executeQuery")) + .or(named("executeUpdate")) + .or(named("executeLargeUpdate")) + .or(named("executeBatch")) + .or(named("executeLargeBatch")); + } + + @Override + public String getMethodsInterceptor() { + return STATEMENT_EXECUTE_METHODS_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return byName(IMPALA_STATEMENT_CLASS_NAME); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..5cdfc6bdc --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,23 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +impala-jdbc-2.6.x=org.apache.skywalking.apm.plugin.jdbc.impala.define.DriverInstrumentation +impala-jdbc-2.6.x=org.apache.skywalking.apm.plugin.jdbc.impala.define.ConnectionInstrumentation +impala-jdbc-2.6.x=org.apache.skywalking.apm.plugin.jdbc.impala.define.StatementInstrumentation +impala-jdbc-2.6.x=org.apache.skywalking.apm.plugin.jdbc.impala.define.PreparedStatementInstrumentation +impala-jdbc-2.6.x=org.apache.skywalking.apm.plugin.jdbc.impala.define.PreparedStatementSetterInstrumentation +impala-jdbc-2.6.x=org.apache.skywalking.apm.plugin.jdbc.impala.define.PreparedStatementNullSetterInstrumentation +impala-jdbc-2.6.x=org.apache.skywalking.apm.plugin.jdbc.impala.define.PreparedStatementIgnoredSetterInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateCallableStatementInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateCallableStatementInterceptorTest.java new file mode 100644 index 000000000..908a57e3a --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateCallableStatementInterceptorTest.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.impala; + +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class CreateCallableStatementInterceptorTest { + + private static final String SQL = "Select * from test"; + + private CreateCallableStatementInterceptor interceptor; + + @Mock + private EnhancedInstance ret; + + @Mock + private EnhancedInstance objectInstance; + + @Mock + private ConnectionInfo connectionInfo; + + @Before + public void setUp() { + interceptor = new CreateCallableStatementInterceptor(); + + when(objectInstance.getSkyWalkingDynamicField()).thenReturn(connectionInfo); + } + + @Test + public void testResultIsEnhanceInstance() { + interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, ret); + verify(ret).setSkyWalkingDynamicField(Matchers.any()); + } + + @Test + public void testResultIsNotEnhanceInstance() { + interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, new Object()); + verify(ret, times(0)).setSkyWalkingDynamicField(Matchers.any()); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreatePreparedStatementInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreatePreparedStatementInterceptorTest.java new file mode 100644 index 000000000..81e5d03e6 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreatePreparedStatementInterceptorTest.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.impala; + +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class CreatePreparedStatementInterceptorTest { + + private static final String SQL = "Select * from test"; + + private CreatePreparedStatementInterceptor interceptor; + + @Mock + private EnhancedInstance ret; + + @Mock + private EnhancedInstance objectInstance; + + @Mock + private ConnectionInfo connectionInfo; + + @Before + public void setUp() { + interceptor = new CreatePreparedStatementInterceptor(); + + when(objectInstance.getSkyWalkingDynamicField()).thenReturn(connectionInfo); + } + + @Test + public void testResultIsEnhanceInstance() { + interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, ret); + verify(ret).setSkyWalkingDynamicField(Matchers.any()); + } + + @Test + public void testResultIsNotEnhanceInstance() { + interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, new Object()); + verify(ret, times(0)).setSkyWalkingDynamicField(Matchers.any()); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateStatementInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateStatementInterceptorTest.java new file mode 100644 index 000000000..5c813435e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/CreateStatementInterceptorTest.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.impala; + +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Matchers; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(MockitoJUnitRunner.class) +public class CreateStatementInterceptorTest { + + private static final String SQL = "Select * from test"; + + private CreateStatementInterceptor interceptor; + + @Mock + private EnhancedInstance ret; + + @Mock + private EnhancedInstance objectInstance; + + @Mock + private ConnectionInfo connectionInfo; + + @Before + public void setUp() { + interceptor = new CreateStatementInterceptor(); + + when(objectInstance.getSkyWalkingDynamicField()).thenReturn(connectionInfo); + } + + @Test + public void testResultIsEnhanceInstance() { + interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, ret); + verify(ret).setSkyWalkingDynamicField(Matchers.any()); + } + + @Test + public void testResultIsNotEnhanceInstance() { + interceptor.afterMethod(objectInstance, null, new Object[]{SQL}, null, new Object()); + verify(ret, times(0)).setSkyWalkingDynamicField(Matchers.any()); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/PreparedStatementExecuteMethodsInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/PreparedStatementExecuteMethodsInterceptorTest.java new file mode 100644 index 000000000..2bfbcdd6d --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/PreparedStatementExecuteMethodsInterceptorTest.java @@ -0,0 +1,154 @@ +/* + * 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.impala; + +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; +import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; +import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.SpanAssert; +import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.apache.skywalking.apm.plugin.jdbc.JDBCPluginConfig; +import org.apache.skywalking.apm.plugin.jdbc.JDBCPreparedStatementSetterInterceptor; +import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; + +import java.lang.reflect.Method; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class PreparedStatementExecuteMethodsInterceptorTest { + + private static final String SQL = "Select * from test where id = ?"; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private PreparedStatementExecuteMethodsInterceptor serviceMethodInterceptor; + + private JDBCPreparedStatementSetterInterceptor preparedStatementSetterInterceptor; + + @Mock + private ConnectionInfo connectionInfo; + @Mock + private EnhancedInstance objectInstance; + @Mock + private Method method; + private StatementEnhanceInfos enhanceRequireCacheObject; + + @Before + public void setUp() { + JDBCPluginConfig.Plugin.JDBC.TRACE_SQL_PARAMETERS = true; + preparedStatementSetterInterceptor = new JDBCPreparedStatementSetterInterceptor(); + serviceMethodInterceptor = new PreparedStatementExecuteMethodsInterceptor(); + + enhanceRequireCacheObject = new StatementEnhanceInfos(connectionInfo, SQL, "PreparedStatement"); + when(objectInstance.getSkyWalkingDynamicField()).thenReturn(enhanceRequireCacheObject); + when(method.getName()).thenReturn("executeQuery"); + when(connectionInfo.getComponent()).thenReturn(ComponentsDefine.IMPALA_JDBC_DRIVER); + when(connectionInfo.getDBType()).thenReturn("Impala"); + when(connectionInfo.getDatabaseName()).thenReturn("test"); + when(connectionInfo.getDatabasePeer()).thenReturn("localhost:21050"); + } + + @After + public void clean() { + JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 2048; + JDBCPluginConfig.Plugin.JDBC.TRACE_SQL_PARAMETERS = false; + } + + @Test + public void testExecutePreparedStatement() throws Throwable { + preparedStatementSetterInterceptor.beforeMethod( + objectInstance, method, new Object[] { + 1, + "abcd" + }, null, null); + preparedStatementSetterInterceptor.beforeMethod( + objectInstance, method, new Object[] { + 2, + "efgh" + }, null, null); + + serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[] {SQL}, null, null); + serviceMethodInterceptor.afterMethod(objectInstance, method, new Object[] {SQL}, null, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment segment = segmentStorage.getTraceSegments().get(0); + assertThat(SegmentHelper.getSpans(segment).size(), is(1)); + AbstractTracingSpan span = SegmentHelper.getSpans(segment).get(0); + SpanAssert.assertLayer(span, SpanLayer.DB); + assertThat(span.getOperationName(), is("Impala/JDBI/PreparedStatement/")); + SpanAssert.assertTag(span, 0, "sql"); + SpanAssert.assertTag(span, 1, "test"); + SpanAssert.assertTag(span, 2, SQL); + SpanAssert.assertTag(span, 3, "[abcd,efgh]"); + } + + @Test + public void testExecutePreparedStatementWithLimitSqlBody() throws Throwable { + JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 10; + + preparedStatementSetterInterceptor.beforeMethod( + objectInstance, method, new Object[] { + 1, + "abcd" + }, null, null); + preparedStatementSetterInterceptor.beforeMethod( + objectInstance, method, new Object[] { + 2, + "efgh" + }, null, null); + + serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[] {SQL}, null, null); + serviceMethodInterceptor.afterMethod(objectInstance, method, new Object[] {SQL}, null, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment segment = segmentStorage.getTraceSegments().get(0); + assertThat(SegmentHelper.getSpans(segment).size(), is(1)); + AbstractTracingSpan span = SegmentHelper.getSpans(segment).get(0); + SpanAssert.assertLayer(span, SpanLayer.DB); + assertThat(span.getOperationName(), is("Impala/JDBI/PreparedStatement/")); + SpanAssert.assertTag(span, 0, "sql"); + SpanAssert.assertTag(span, 1, "test"); + SpanAssert.assertTag(span, 2, "Select * f..."); + SpanAssert.assertTag(span, 3, "[abcd,efgh]"); + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/StatementExecuteMethodsInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/StatementExecuteMethodsInterceptorTest.java new file mode 100644 index 000000000..8517a524d --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/impala-jdbc-2.6.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/impala/StatementExecuteMethodsInterceptorTest.java @@ -0,0 +1,123 @@ +/* + * 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.impala; + +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; +import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; +import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.SpanAssert; +import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.apache.skywalking.apm.plugin.jdbc.JDBCPluginConfig; +import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; + +import java.lang.reflect.Method; + +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class StatementExecuteMethodsInterceptorTest { + + private static final String SQL = "Select * from test"; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + + private StatementExecuteMethodsInterceptor serviceMethodInterceptor; + + @Mock + private ConnectionInfo connectionInfo; + @Mock + private EnhancedInstance objectInstance; + @Mock + private Method method; + private StatementEnhanceInfos enhanceRequireCacheObject; + + @Before + public void setUp() { + serviceMethodInterceptor = new StatementExecuteMethodsInterceptor(); + + enhanceRequireCacheObject = new StatementEnhanceInfos(connectionInfo, SQL, "CallableStatement"); + when(objectInstance.getSkyWalkingDynamicField()).thenReturn(enhanceRequireCacheObject); + when(method.getName()).thenReturn("executeQuery"); + when(connectionInfo.getComponent()).thenReturn(ComponentsDefine.IMPALA_JDBC_DRIVER); + when(connectionInfo.getDBType()).thenReturn("Impala"); + when(connectionInfo.getDatabaseName()).thenReturn("test"); + when(connectionInfo.getDatabasePeer()).thenReturn("localhost:21050"); + } + + @After + public void clean() { + JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 2048; + } + + @Test + public void testExecuteStatement() { + serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[]{SQL}, null, null); + serviceMethodInterceptor.afterMethod(objectInstance, method, new Object[]{SQL}, null, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment segment = segmentStorage.getTraceSegments().get(0); + assertThat(SegmentHelper.getSpans(segment).size(), is(1)); + AbstractTracingSpan span = SegmentHelper.getSpans(segment).get(0); + SpanAssert.assertLayer(span, SpanLayer.DB); + assertThat(span.getOperationName(), is("Impala/JDBI/CallableStatement/")); + SpanAssert.assertTag(span, 0, "sql"); + SpanAssert.assertTag(span, 1, "test"); + SpanAssert.assertTag(span, 2, SQL); + } + + @Test + public void testExecuteStatementWithLimitSqlBody() { + JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 10; + serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[]{SQL}, null, null); + serviceMethodInterceptor.afterMethod(objectInstance, method, new Object[]{SQL}, null, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment segment = segmentStorage.getTraceSegments().get(0); + assertThat(SegmentHelper.getSpans(segment).size(), is(1)); + AbstractTracingSpan span = SegmentHelper.getSpans(segment).get(0); + SpanAssert.assertLayer(span, SpanLayer.DB); + assertThat(span.getOperationName(), is("Impala/JDBI/CallableStatement/")); + SpanAssert.assertTag(span, 0, "sql"); + SpanAssert.assertTag(span, 1, "test"); + SpanAssert.assertTag(span, 2, "Select * f..."); + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/ImpalaJdbcURLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/ImpalaJdbcURLParser.java new file mode 100644 index 000000000..c11052e23 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/ImpalaJdbcURLParser.java @@ -0,0 +1,110 @@ +/* + * 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.connectionurl.parser; + +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.apache.skywalking.apm.network.trace.component.OfficialComponent; +import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; + +public class ImpalaJdbcURLParser extends AbstractURLParser { + + private static final int DEFAULT_PORT = 21050; + private static final String DB_TYPE = "Impala"; + private OfficialComponent component = ComponentsDefine.IMPALA_JDBC_DRIVER; + + public ImpalaJdbcURLParser(String url) { + super(url); + } + + @Override + protected URLLocation fetchDatabaseHostsIndexRange() { + int hostLabelStartIndex = url.indexOf("//"); + int hostLabelEndIndex = url.length(); + int hostLabelEndIndexWithParameter = url.indexOf(";", hostLabelStartIndex); + if (hostLabelEndIndexWithParameter != -1) { + String subUrl = url.substring(0, hostLabelEndIndexWithParameter); + int schemaIndex = subUrl.indexOf("/", hostLabelStartIndex + 2); + if (schemaIndex == -1) { + hostLabelEndIndex = hostLabelEndIndexWithParameter; + } else { + hostLabelEndIndex = schemaIndex; + } + } + return new URLLocation(hostLabelStartIndex + 2, hostLabelEndIndex); + } + + protected String fetchDatabaseNameFromURL(int startSize) { + URLLocation hostsLocation = fetchDatabaseNameIndexRange(startSize); + if (hostsLocation == null) { + return ""; + } + return url.substring(hostsLocation.startIndex(), hostsLocation.endIndex()); + } + + protected URLLocation fetchDatabaseNameIndexRange(int startSize) { + int databaseStartTag = url.indexOf("/", startSize); + int firstParamIndex = url.indexOf(";", startSize); + int databaseEndTag = url.length(); + if (databaseStartTag == -1 && firstParamIndex == -1) { + return null; + } else { + String subUrl = url.substring(startSize, firstParamIndex); + int schemaIndex = subUrl.indexOf("/"); + if (schemaIndex == -1) { + return null; + } else { + databaseEndTag = firstParamIndex; + } + } + return new URLLocation(databaseStartTag + 1, databaseEndTag); + } + + @Override + protected URLLocation fetchDatabaseNameIndexRange() { + URLLocation location = fetchDatabaseHostsIndexRange(); + return fetchDatabaseNameIndexRange(location.endIndex()); + } + + @Override + public ConnectionInfo parse() { + URLLocation location = fetchDatabaseHostsIndexRange(); + String hosts = url.substring(location.startIndex(), location.endIndex()); + String[] hostSegment = hosts.split(","); + if (hostSegment.length > 1) { + StringBuilder sb = new StringBuilder(); + for (String host : hostSegment) { + if (host.split(":").length == 1) { + sb.append(host).append(":").append(DEFAULT_PORT).append(","); + } else { + sb.append(host).append(","); + } + } + return new ConnectionInfo(component, DB_TYPE, sb.substring(0, sb.length() - 1), fetchDatabaseNameFromURL()); + } else { + String[] hostAndPort = hostSegment[0].split(":"); + if (hostAndPort.length != 1) { + return new ConnectionInfo(component, DB_TYPE, hostAndPort[0], Integer.valueOf(hostAndPort[1]), fetchDatabaseNameFromURL(location + .endIndex())); + } else { + return new ConnectionInfo(component, DB_TYPE, hostAndPort[0], DEFAULT_PORT, fetchDatabaseNameFromURL(location + .endIndex())); + } + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java index 19b088679..45b976a82 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-commons/src/main/java/org/apache/skywalking/apm/plugin/jdbc/connectionurl/parser/URLParser.java @@ -34,6 +34,7 @@ public class URLParser { private static final String MSSQL_JTDS_URL_PREFIX = "jdbc:jtds:sqlserver:"; private static final String MSSQL_JDBC_URL_PREFIX = "jdbc:sqlserver:"; private static final String KYLIN_JDBC_URK_PREFIX = "jdbc:kylin"; + private static final String IMPALA_JDBC_URK_PREFIX = "jdbc:impala"; public static ConnectionInfo parser(String url) { ConnectionURLParser parser = null; @@ -54,6 +55,8 @@ public class URLParser { parser = new MssqlJdbcURLParser(url); } else if (lowerCaseUrl.startsWith(KYLIN_JDBC_URK_PREFIX)) { parser = new KylinJdbcURLParser(url); + } else if (lowerCaseUrl.startsWith(IMPALA_JDBC_URK_PREFIX)) { + parser = new ImpalaJdbcURLParser(url); } return parser.parse(); } diff --git a/apm-sniffer/apm-sdk-plugin/kylin-jdbc-2.6.x-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/kylin/PreparedStatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/kylin-jdbc-2.6.x-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/kylin/PreparedStatementExecuteMethodsInterceptor.java index cc02689ab..252cb2ccf 100644 --- a/apm-sniffer/apm-sdk-plugin/kylin-jdbc-2.6.x-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/kylin/PreparedStatementExecuteMethodsInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/kylin-jdbc-2.6.x-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/kylin/PreparedStatementExecuteMethodsInterceptor.java @@ -18,9 +18,6 @@ package org.apache.skywalking.apm.plugin.jdbc.kylin; -import static org.apache.skywalking.apm.plugin.jdbc.kylin.Constants.SQL_PARAMETERS; - -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; @@ -34,6 +31,8 @@ import org.apache.skywalking.apm.plugin.jdbc.SqlBodyUtil; import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import java.lang.reflect.Method; + public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor { @Override @@ -55,7 +54,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho final Object[] parameters = cacheObject.getParameters(); if (parameters != null && parameters.length > 0) { int maxIndex = cacheObject.getMaxIndex(); - SQL_PARAMETERS.set(span, getParameterString(parameters, maxIndex)); + Tags.SQL_PARAMETERS.set(span, getParameterString(parameters, maxIndex)); } } diff --git a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptor.java index a2b0fff11..a54b74fc1 100644 --- a/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/mariadb-2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mariadb/v2/PreparedStatementExecuteMethodsInterceptor.java @@ -18,7 +18,6 @@ package org.apache.skywalking.apm.plugin.jdbc.mariadb.v2; -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; @@ -32,7 +31,7 @@ import org.apache.skywalking.apm.plugin.jdbc.SqlBodyUtil; import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; -import static org.apache.skywalking.apm.plugin.jdbc.mariadb.v2.Constants.SQL_PARAMETERS; +import java.lang.reflect.Method; public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor { @@ -55,7 +54,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho final Object[] parameters = cacheObject.getParameters(); if (parameters != null && parameters.length > 0) { int maxIndex = cacheObject.getMaxIndex(); - SQL_PARAMETERS.set(span, getParameterString(parameters, maxIndex)); + Tags.SQL_PARAMETERS.set(span, getParameterString(parameters, maxIndex)); } } diff --git a/apm-sniffer/apm-sdk-plugin/mssql-commons/src/main/java/org/apache/skywalking/apm/plugin/mssql/commons/Constants.java b/apm-sniffer/apm-sdk-plugin/mssql-commons/src/main/java/org/apache/skywalking/apm/plugin/mssql/commons/Constants.java index d2142ae86..8cbb675d1 100644 --- a/apm-sniffer/apm-sdk-plugin/mssql-commons/src/main/java/org/apache/skywalking/apm/plugin/mssql/commons/Constants.java +++ b/apm-sniffer/apm-sdk-plugin/mssql-commons/src/main/java/org/apache/skywalking/apm/plugin/mssql/commons/Constants.java @@ -18,14 +18,10 @@ package org.apache.skywalking.apm.plugin.mssql.commons; -import org.apache.skywalking.apm.agent.core.context.tag.StringTag; - public class Constants { public static final String CREATE_CALLABLE_STATEMENT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.mssql.commons.CreateCallableStatementInterceptor"; public static final String CREATE_PREPARED_STATEMENT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.mssql.commons.CreatePreparedStatementInterceptor"; public static final String CREATE_STATEMENT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.mssql.commons.CreateStatementInterceptor"; public static final String PREPARED_STATEMENT_EXECUTE_METHODS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.mssql.commons.PreparedStatementExecuteMethodsInterceptor"; public static final String STATEMENT_EXECUTE_METHODS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.mssql.commons.StatementExecuteMethodsInterceptor"; - - public static final StringTag SQL_PARAMETERS = new StringTag("db.sql.parameters"); } diff --git a/apm-sniffer/apm-sdk-plugin/mssql-commons/src/main/java/org/apache/skywalking/apm/plugin/mssql/commons/PreparedStatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/mssql-commons/src/main/java/org/apache/skywalking/apm/plugin/mssql/commons/PreparedStatementExecuteMethodsInterceptor.java index 5c2f64a9c..bf7ff3caa 100644 --- a/apm-sniffer/apm-sdk-plugin/mssql-commons/src/main/java/org/apache/skywalking/apm/plugin/mssql/commons/PreparedStatementExecuteMethodsInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/mssql-commons/src/main/java/org/apache/skywalking/apm/plugin/mssql/commons/PreparedStatementExecuteMethodsInterceptor.java @@ -18,7 +18,6 @@ package org.apache.skywalking.apm.plugin.mssql.commons; -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; @@ -32,6 +31,8 @@ import org.apache.skywalking.apm.plugin.jdbc.SqlBodyUtil; import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import java.lang.reflect.Method; + public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor { @Override @@ -53,7 +54,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho final Object[] parameters = cacheObject.getParameters(); if (parameters != null && parameters.length > 0) { int maxIndex = cacheObject.getMaxIndex(); - Constants.SQL_PARAMETERS.set(span, getParameterString(parameters, maxIndex)); + Tags.SQL_PARAMETERS.set(span, getParameterString(parameters, maxIndex)); } } SpanLayer.asDB(span); diff --git a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/Constants.java b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/Constants.java index 00599f9e8..9dbe001e4 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/Constants.java +++ b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/Constants.java @@ -18,8 +18,6 @@ package org.apache.skywalking.apm.plugin.jdbc.mysql; -import org.apache.skywalking.apm.agent.core.context.tag.StringTag; - public class Constants { public static final String CREATE_CALLABLE_STATEMENT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.CreateCallableStatementInterceptor"; public static final String CREATE_PREPARED_STATEMENT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.CreatePreparedStatementInterceptor"; @@ -29,5 +27,4 @@ public class Constants { public static final String STATEMENT_EXECUTE_METHODS_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.StatementExecuteMethodsInterceptor"; public static final String DRIVER_CONNECT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.mysql.DriverConnectInterceptor"; - public static final StringTag SQL_PARAMETERS = new StringTag("db.sql.parameters"); } diff --git a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/PreparedStatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/PreparedStatementExecuteMethodsInterceptor.java index 23b6c68b4..d915ee7cc 100644 --- a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/PreparedStatementExecuteMethodsInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/PreparedStatementExecuteMethodsInterceptor.java @@ -18,7 +18,6 @@ package org.apache.skywalking.apm.plugin.jdbc.mysql; -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; @@ -32,7 +31,7 @@ import org.apache.skywalking.apm.plugin.jdbc.SqlBodyUtil; import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; -import static org.apache.skywalking.apm.plugin.jdbc.mysql.Constants.SQL_PARAMETERS; +import java.lang.reflect.Method; public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor { @@ -62,7 +61,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho if (parameters != null && parameters.length > 0) { int maxIndex = cacheObject.getMaxIndex(); String parameterString = getParameterString(parameters, maxIndex); - SQL_PARAMETERS.set(span, parameterString); + Tags.SQL_PARAMETERS.set(span, parameterString); } } diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 4082bb252..4188314b6 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -124,6 +124,7 @@ micronaut-plugins nats-2.14.x-2.15.x-plugin jedis-plugins + impala-jdbc-2.6.x-plugin pom 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 index e827be9b7..f3f5e2f4d 100755 --- 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 @@ -18,9 +18,7 @@ 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.StringTag; 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; @@ -33,14 +31,14 @@ import org.apache.skywalking.apm.plugin.jdbc.SqlBodyUtil; import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos; import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo; +import java.lang.reflect.Method; + /** * {@link PreparedStatementExecuteMethodsInterceptor} create the exit span when the client call the interceptor * methods. */ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMethodsAroundInterceptor { - public static final StringTag SQL_PARAMETERS = new StringTag("db.sql.parameters"); - @Override public final void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) { @@ -59,7 +57,7 @@ public class PreparedStatementExecuteMethodsInterceptor implements InstanceMetho if (parameters != null && parameters.length > 0) { int maxIndex = cacheObject.getMaxIndex(); String parameterString = getParameterString(parameters, maxIndex); - SQL_PARAMETERS.set(span, parameterString); + Tags.SQL_PARAMETERS.set(span, parameterString); } } diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md index a723f1fea..c2f6c8183 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -145,3 +145,4 @@ - micronaut-http-client-3.2.x-3.6.x - micronaut-http-server-3.2.x-3.6.x - nats-client-2.14.x-2.15.x +- impala-jdbc-2.6.x diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index 32cb0b011..1660e77bf 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -48,6 +48,7 @@ metrics based on the tracing data. * [Mssql-jdbc](https://github.com/microsoft/mssql-jdbc) 6.x -> 8.x * [ClickHouse-jdbc](https://github.com/ClickHouse/clickhouse-jdbc) 0.3.x * [Apache-Kylin-Jdbc](https://github.com/apache/kylin.git) 2.6.x -> 3.x -> 4.x + * [Impala-jdbc](https://www.cloudera.com/downloads/connectors/impala/jdbc/2-6-29.html) 2.6.x * RPC Frameworks * [Dubbo](https://github.com/alibaba/dubbo) 2.5.4 -> 2.6.0 * [Dubbox](https://github.com/dangdangdotcom/dubbox) 2.8.4 diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/bin/startup.sh b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/bin/startup.sh new file mode 100644 index 000000000..872fc138c --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/bin/startup.sh @@ -0,0 +1,21 @@ +#!/bin/bash +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +home="$(cd "$(dirname $0)"; pwd)" + +java -jar -Dskywalking.plugin.jdbc.trace_sql_parameters=true ${agent_opts} ${home}/../libs/impala-jdbc-2.6.x-scenario.jar & \ No newline at end of file diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/config/expectedData.yaml new file mode 100644 index 000000000..910488f7a --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/config/expectedData.yaml @@ -0,0 +1,117 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +segmentItems: + - serviceName: impala-jdbc-2.6.x-scenario + segmentSize: ge 1 + segments: + - segmentId: not null + spans: + - operationName: Impala/JDBI/Statement/execute + parentSpanId: 0 + spanId: 1 + spanLayer: Database + startTime: nq 0 + endTime: nq 0 + componentId: 133 + isError: false + spanType: Exit + peer: impala-server:21050 + skipAnalysis: 'false' + tags: + - { key: db.type, value: sql } + - { key: db.instance, value: '' } + - key: db.statement + value: "CREATE TABLE IF NOT EXISTS default.impala_test (test_id BIGINT, test_name STRING);" + - operationName: Impala/JDBI/Statement/execute + parentSpanId: 0 + spanId: 2 + spanLayer: Database + startTime: nq 0 + endTime: nq 0 + componentId: 133 + isError: false + spanType: Exit + peer: impala-server:21050 + skipAnalysis: 'false' + tags: + - { key: db.type, value: sql } + - { key: db.instance, value: '' } + - key: db.statement + value: "INSERT INTO impala_test VALUES (123, 'test');" + - operationName: Impala/JDBI/PreparedStatement/executeQuery + parentSpanId: 0 + spanId: 3 + spanLayer: Database + startTime: nq 0 + endTime: nq 0 + componentId: 133 + isError: false + spanType: Exit + peer: impala-server:21050 + skipAnalysis: 'false' + tags: + - { key: db.type, value: sql } + - { key: db.instance, value: '' } + - key: db.statement + value: "SELECT COUNT(*) FROM impala_test;" + - operationName: Impala/JDBI/PreparedStatement/executeQuery + parentSpanId: 0 + spanId: 4 + spanLayer: Database + startTime: nq 0 + endTime: nq 0 + componentId: 133 + isError: false + spanType: Exit + peer: impala-server:21050 + skipAnalysis: 'false' + tags: + - { key: db.type, value: sql } + - { key: db.instance, value: '' } + - key: db.statement + value: 'SELECT COUNT(*) FROM impala_test WHERE test_id = ?;' + - { key: db.sql.parameters, value: '[123]'} + - operationName: Impala/JDBI/Connection/close + parentSpanId: 0 + spanId: 5 + spanLayer: Database + startTime: nq 0 + endTime: nq 0 + componentId: 133 + isError: false + spanType: Exit + peer: impala-server:21050 + skipAnalysis: 'false' + tags: + - { key: db.type, value: sql } + - { key: db.instance, value: '' } + - { key: db.statement, value: '' } + - operationName: HEAD:/impala-jdbc-2.6.x-scenario/case/healthCheck + parentSpanId: -1 + spanId: 0 + startTime: nq 0 + endTime: nq 0 + spanLayer: Http + isError: false + spanType: Entry + peer: '' + componentId: 1 + tags: + - { key: url, value: 'http://localhost:8080/impala-jdbc-2.6.x-scenario/case/healthCheck' } + - { key: http.method, value: HEAD } + - { key: http.status_code, value: '200' } + logs: [ ] + skipAnalysis: 'false' diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/configuration.yml b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/configuration.yml new file mode 100644 index 000000000..af968fbcd --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/configuration.yml @@ -0,0 +1,81 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +type: jvm +entryService: http://localhost:8080/impala-jdbc-2.6.x-scenario/case/impala-jdbc-2.6.x-scenario +healthCheck: http://localhost:8080/impala-jdbc-2.6.x-scenario/case/healthCheck +startScript: ./bin/startup.sh +environment: +depends_on: + - impala-server +dependencies: + postgres: + hostname: postgres + image: parrotstream/postgres:10.5 + environment: + - POSTGRES_PASSWORD=postgres + expose: + - 5432 + zookeeper: + hostname: zookeeper + image: parrotstream/zookeeper:latest + expose: + - 2181 + - 2888 + - 3888 + hadoop: + hostname: hadoop + image: parrotstream/hadoop:3.0.3 + links: + - zookeeper + expose: + - 9870 + - 9864 + - 9820 + - 8042 + - 8088 + - 8188 + - 19888 + hive: + hostname: hive + image: parrotstream/hive:1.1.0-cdh5.11.1 + environment: + - PGPASSWORD=postgres + links: + - hadoop + - zookeeper + - postgres + expose: + - 10000 + - 10001 + - 10002 + - 10003 + - 9083 + - 50111 + - 9999 + impala-server: + hostname: impala-server + image: parrotstream/impala:latest + links: + - hadoop + - hive + - zookeeper + expose: + - 21000 + - 21050 + - 25000 + - 25010 + - 25020 \ No newline at end of file diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/pom.xml b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/pom.xml new file mode 100644 index 000000000..30223782b --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/pom.xml @@ -0,0 +1,135 @@ + + + + + org.apache.skywalking.apm.testcase + impala-jdbc-2.6.x-scenario + 1.0.0 + jar + + 4.0.0 + + + UTF-8 + 1.8 + 2.6.26.1031 + ${test.framework.version} + 2.1.6.RELEASE + 1.18.20 + 2.6.26.1031 + + + skywalking-impala-jdbc-2.6.x-scenario + + + + + org.springframework.boot + spring-boot-dependencies + ${spring.boot.version} + pom + import + + + + + + + Impala + ImpalaJDBC42 + ${test.framework.version} + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-logging + + + + + org.springframework.boot + spring-boot-starter-log4j2 + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + + + + cloudera.repo + https://repository.cloudera.com/artifactory/cloudera-repos/ + + + + + impala-jdbc-2.6.x-scenario + + + org.springframework.boot + spring-boot-maven-plugin + ${spring.boot.version} + + + + repackage + + + + + + maven-compiler-plugin + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/assembly/assembly.xml new file mode 100644 index 000000000..8580373fc --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ${project.build.directory}/impala-jdbc-2.6.x-scenario.jar + ./libs + 0775 + + + diff --git a/apm-sniffer/apm-sdk-plugin/kylin-jdbc-2.6.x-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/kylin/Constants.java b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/Application.java similarity index 65% rename from apm-sniffer/apm-sdk-plugin/kylin-jdbc-2.6.x-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/kylin/Constants.java rename to test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/Application.java index 4fe0fffef..4f85f6924 100644 --- a/apm-sniffer/apm-sdk-plugin/kylin-jdbc-2.6.x-3.x-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/kylin/Constants.java +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/Application.java @@ -16,10 +16,19 @@ * */ -package org.apache.skywalking.apm.plugin.jdbc.kylin; +package org.apache.skywalking.apm.testcase.impalajdbc; -import org.apache.skywalking.apm.agent.core.context.tag.StringTag; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; -public class Constants { - public static final StringTag SQL_PARAMETERS = new StringTag("db.sql.parameters"); +@SpringBootApplication +public class Application { + + public static void main(String[] args) { + try { + SpringApplication.run(Application.class, args); + } catch (Exception e) { + // Never do this + } + } } diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/ImpalaJdbcConfig.java b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/ImpalaJdbcConfig.java new file mode 100644 index 000000000..68d4d1d60 --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/ImpalaJdbcConfig.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.testcase.impalajdbc; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class ImpalaJdbcConfig { + private static final Logger LOGGER = LogManager.getLogger(ImpalaJdbcConfig.class); + private static String URL; + + static { + InputStream inputStream = ImpalaJdbcConfig.class.getClassLoader().getResourceAsStream("jdbc.properties"); + Properties properties = new Properties(); + try { + properties.load(inputStream); + } catch (IOException e) { + LOGGER.error("Failed to load config", e); + } + + URL = properties.getProperty("impala.url"); + } + + public static String getUrl() { + return URL; + } +} diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/SQLExecutor.java b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/SQLExecutor.java new file mode 100644 index 000000000..ce8155ee3 --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/SQLExecutor.java @@ -0,0 +1,77 @@ +/* + * 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.testcase.impalajdbc; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.sql.Statement; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class SQLExecutor implements AutoCloseable { + + private static final Logger LOGGER = LogManager.getLogger(SQLExecutor.class); + + private Connection connection; + private static final String STATEMENT_CREATE_TABLE_SQL = "CREATE TABLE IF NOT EXISTS default.impala_test (test_id BIGINT, test_name STRING);"; + private static final String IMPALA_DRIVER = "com.cloudera.impala.jdbc.Driver"; + + public SQLExecutor() throws SQLException { + try { + Class.forName(IMPALA_DRIVER); + } catch (ClassNotFoundException ex) { + LOGGER.error(ex); + } + connection = DriverManager.getConnection(ImpalaJdbcConfig.getUrl()); + connection.createStatement().execute(STATEMENT_CREATE_TABLE_SQL); + } + + public void execute(String sql) throws SQLException { + Statement statement = connection.createStatement(); + statement.execute(sql); + } + + public void queryData(String sql) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.executeQuery(); + } + + public void queryData(String sql, int id) throws SQLException { + PreparedStatement preparedStatement = connection.prepareStatement(sql); + preparedStatement.setInt(1, id); + preparedStatement.executeQuery(); + } + + public void closeConnection() throws SQLException { + if (this.connection != null) { + this.connection.close(); + } + } + + @Override + public void close() throws Exception { + closeConnection(); + } + + public Connection getConnection() { + return connection; + } +} diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/controller/CaseController.java b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/controller/CaseController.java new file mode 100644 index 000000000..dca9840eb --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/impalajdbc/controller/CaseController.java @@ -0,0 +1,88 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.testcase.impalajdbc.controller; + +import lombok.extern.log4j.Log4j2; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.skywalking.apm.testcase.impalajdbc.SQLExecutor; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; + +@RestController +@RequestMapping("/case") +@Log4j2 +public class CaseController { + + private static final Logger LOGGER = LogManager.getLogger(CaseController.class); + + private static final String SUCCESS = "Success"; + + private static final String STATEMENT_INSERT_DATA_SQL = "INSERT INTO impala_test VALUES (123, 'test');"; + private static final String STATEMENT_QUERY_DATA_SQL = "SELECT COUNT(*) FROM impala_test;"; + private static final String STATEMENT_QUERY_DATA_SQL_PARAM = "SELECT COUNT(*) FROM impala_test WHERE test_id = ?;"; + + @RequestMapping("/impala-jdbc-2.6.x-scenario") + @ResponseBody + public String testcase() throws Exception { + Thread.sleep(2000); + return SUCCESS; + } + + @RequestMapping("/healthCheck") + @ResponseBody + public String healthCheck() throws Exception { + if (!telnet("impala-server", 21050, 1000)) { // + Thread.sleep(5000); // WAIT UTIL CLIENT TIMEOUT + } else { + try (SQLExecutor sqlExecute = new SQLExecutor()) { + sqlExecute.execute(STATEMENT_INSERT_DATA_SQL); + sqlExecute.queryData(STATEMENT_QUERY_DATA_SQL); + sqlExecute.queryData(STATEMENT_QUERY_DATA_SQL_PARAM, 123); + } catch (Exception ex) { + LOGGER.error("Failed to execute sql.", ex); + throw ex; + } + } + return SUCCESS; + } + + private boolean telnet(String hostname, int port, int timeout) { + Socket socket = new Socket(); + boolean isConnected = false; + try { + socket.connect(new InetSocketAddress(hostname, port), timeout); + isConnected = socket.isConnected(); + } catch (IOException e) { + LOGGER.warn("connect to impala server failed"); + } finally { + try { + socket.close(); + } catch (IOException e) { + LOGGER.warn("close failed"); + } + } + return isConnected; + } +} diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/resources/application.yaml new file mode 100644 index 000000000..786ec3440 --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/resources/application.yaml @@ -0,0 +1,23 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +server: + port: 8080 + servlet: + context-path: /impala-jdbc-2.6.x-scenario +logging: + config: classpath:log4j2.xml \ No newline at end of file diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/resources/jdbc.properties b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/resources/jdbc.properties new file mode 100644 index 000000000..988356c8f --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/resources/jdbc.properties @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +impala.url=jdbc:impala://impala-server:21050 diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/resources/log4j2.xml new file mode 100644 index 000000000..9849ed5a8 --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/support-version.list b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/support-version.list new file mode 100644 index 000000000..e795caf90 --- /dev/null +++ b/test/plugin/scenarios/impala-jdbc-2.6.x-scenario/support-version.list @@ -0,0 +1,21 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# lists your version here (Contains only the last version number of each minor version.) + +2.6.26.1031 +2.6.24.1029 +2.6.20.1024 \ No newline at end of file