Merge branch 'master' into feature/headcheck
This commit is contained in:
commit
f0d6db2a93
|
|
@ -65,6 +65,8 @@ public class ComponentsDefine {
|
|||
|
||||
public static final OfficialComponent MEMCACHE = new OfficialComponent(20, "Memcache");
|
||||
|
||||
public static final OfficialComponent SHARDING_JDBC = new OfficialComponent(21, "ShardingJDBC");
|
||||
|
||||
private static ComponentsDefine instance = new ComponentsDefine();
|
||||
|
||||
private String[] components;
|
||||
|
|
@ -74,7 +76,7 @@ public class ComponentsDefine {
|
|||
}
|
||||
|
||||
public ComponentsDefine() {
|
||||
components = new String[21];
|
||||
components = new String[22];
|
||||
addComponent(TOMCAT);
|
||||
addComponent(HTTPCLIENT);
|
||||
addComponent(DUBBO);
|
||||
|
|
@ -95,6 +97,7 @@ public class ComponentsDefine {
|
|||
addComponent(JETTY_CLIENT);
|
||||
addComponent(JETTY_SERVER);
|
||||
addComponent(MEMCACHE);
|
||||
addComponent(SHARDING_JDBC);
|
||||
}
|
||||
|
||||
private void addComponent(OfficialComponent component) {
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ public class ContextManager implements TracingContextListener, BootService, Igno
|
|||
if (snapshot == null) {
|
||||
throw new IllegalArgumentException("ContextSnapshot can't be null.");
|
||||
}
|
||||
if (snapshot.isValid()) {
|
||||
if (snapshot.isValid() && !snapshot.isFromCurrent()) {
|
||||
get().continued(snapshot);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,4 +113,8 @@ public class ContextSnapshot {
|
|||
public int getEntryApplicationInstanceId() {
|
||||
return entryApplicationInstanceId;
|
||||
}
|
||||
|
||||
public boolean isFromCurrent() {
|
||||
return traceSegmentId.equals(ContextManager.capture().getTraceSegmentId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,6 +53,11 @@ public final class Tags {
|
|||
*/
|
||||
public static final StringTag DB_STATEMENT = new StringTag("db.statement");
|
||||
|
||||
/**
|
||||
* DB_BIND_VARIABLES records the bind variables of sql statement.
|
||||
*/
|
||||
public static final StringTag DB_BIND_VARIABLES = new StringTag("db.bind_vars");
|
||||
|
||||
public static final class HTTP {
|
||||
public static final StringTag METHOD = new StringTag("http.method");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,6 +148,11 @@
|
|||
<artifactId>apm-spymemcached-2.x-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.skywalking</groupId>
|
||||
<artifactId>apm-sharding-jdbc-1.5.x-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- activation -->
|
||||
<dependency>
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
<module>nutz-plugins</module>
|
||||
<module>jetty-plugin</module>
|
||||
<module>spymemcached-2.x-plugin</module>
|
||||
<module>sharding-jdbc-1.5.x-plugin</module>
|
||||
</modules>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Copyright 2017, OpenSkywalking Organization All rights reserved.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
~ Project repository: https://github.com/OpenSkywalking/skywalking
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>apm-sdk-plugin</artifactId>
|
||||
<groupId>org.skywalking</groupId>
|
||||
<version>3.2.3-2017</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>apm-sharding-jdbc-1.5.x-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>sharding-jdbc-1.5.x-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${groupId}</groupId>
|
||||
<artifactId>apm-jdbc-plugin</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>[2.0.14,6.0.6]</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.dangdang</groupId>
|
||||
<artifactId>sharding-jdbc-core</artifactId>
|
||||
<version>[1.5.0,2.0.0)</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- 源码插件 -->
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<!-- 发布时自动将源码同时发布的配置 -->
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright 2017, OpenSkywalking Organization All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Project repository: https://github.com/OpenSkywalking/skywalking
|
||||
*/
|
||||
|
||||
package org.skywalking.apm.plugin.sjdbc;
|
||||
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.event.AbstractExecutionEvent;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.event.DMLExecutionEvent;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.event.DQLExecutionEvent;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.threadlocal.ExecutorDataMap;
|
||||
import com.dangdang.ddframe.rdb.sharding.util.EventBusInstance;
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.eventbus.AllowConcurrentEvents;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import org.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.skywalking.apm.agent.core.context.ContextSnapshot;
|
||||
import org.skywalking.apm.agent.core.context.tag.Tags;
|
||||
import org.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
import org.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
import org.skywalking.apm.plugin.sjdbc.define.AsyncExecuteInterceptor;
|
||||
|
||||
/**
|
||||
* Sharding-jdbc provides {@link EventBusInstance} to help external systems get events of sql execution.
|
||||
* {@link ExecuteEventListener} can get sql statement start and end events, resulting in db span.
|
||||
*
|
||||
* @author gaohongtao
|
||||
*/
|
||||
public class ExecuteEventListener {
|
||||
|
||||
public static void init() {
|
||||
EventBusInstance.getInstance().register(new ExecuteEventListener());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@AllowConcurrentEvents
|
||||
public void listenDML(DMLExecutionEvent event) {
|
||||
handle(event, "MODIFY");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@AllowConcurrentEvents
|
||||
public void listenDQL(DQLExecutionEvent event) {
|
||||
handle(event, "QUERY");
|
||||
}
|
||||
|
||||
private void handle(AbstractExecutionEvent event, String operation) {
|
||||
switch (event.getEventExecutionType()) {
|
||||
case BEFORE_EXECUTE:
|
||||
AbstractSpan span = ContextManager.createExitSpan("/SJDBC/BRANCH/" + operation, event.getDataSource());
|
||||
if (ExecutorDataMap.getDataMap().containsKey(AsyncExecuteInterceptor.SNAPSHOT_DATA_KEY)) {
|
||||
ContextManager.continued((ContextSnapshot)ExecutorDataMap.getDataMap().get(AsyncExecuteInterceptor.SNAPSHOT_DATA_KEY));
|
||||
}
|
||||
Tags.DB_TYPE.set(span, "sql");
|
||||
Tags.DB_INSTANCE.set(span, event.getDataSource());
|
||||
Tags.DB_STATEMENT.set(span, event.getSql());
|
||||
if (!event.getParameters().isEmpty()) {
|
||||
Tags.DB_BIND_VARIABLES.set(span, Joiner.on(",").join(event.getParameters()));
|
||||
}
|
||||
span.setComponent(ComponentsDefine.SHARDING_JDBC);
|
||||
SpanLayer.asDB(span);
|
||||
break;
|
||||
case EXECUTE_FAILURE:
|
||||
span = ContextManager.activeSpan();
|
||||
span.errorOccurred();
|
||||
if (event.getException().isPresent()) {
|
||||
span.log(event.getException().get());
|
||||
}
|
||||
case EXECUTE_SUCCESS:
|
||||
ContextManager.stopSpan();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Copyright 2017, OpenSkywalking Organization All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Project repository: https://github.com/OpenSkywalking/skywalking
|
||||
*/
|
||||
|
||||
package org.skywalking.apm.plugin.sjdbc.define;
|
||||
|
||||
import com.dangdang.ddframe.rdb.sharding.constant.SQLType;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.ExecuteCallback;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.threadlocal.ExecutorDataMap;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.skywalking.apm.agent.core.context.ContextSnapshot;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* {@link AsyncExecuteInterceptor} enhances {@link com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine#asyncExecute(SQLType, Collection, List, ExecuteCallback)}
|
||||
* so that the sql executor can get a {@link ContextSnapshot} of main thread when it is executed asynchronously.
|
||||
*
|
||||
* @author gaohongtao
|
||||
*/
|
||||
public class AsyncExecuteInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
public static final String SNAPSHOT_DATA_KEY = "APM_SKYWALKING_SNAPSHOT_DATA";
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
ExecutorDataMap.getDataMap().put(SNAPSHOT_DATA_KEY, ContextManager.capture());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright 2017, OpenSkywalking Organization All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Project repository: https://github.com/OpenSkywalking/skywalking
|
||||
*/
|
||||
|
||||
package org.skywalking.apm.plugin.sjdbc.define;
|
||||
|
||||
import com.dangdang.ddframe.rdb.sharding.constant.SQLType;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.ExecuteCallback;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import org.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
|
||||
import org.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
|
||||
/**
|
||||
* {@link ExecuteInterceptor} enhances {@link com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine#execute(SQLType, Collection, List, ExecuteCallback)}
|
||||
* ,creating a local span that records the overall execution of sql
|
||||
*
|
||||
* @author gaohongtao
|
||||
*/
|
||||
public class ExecuteInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) throws Throwable {
|
||||
SQLType sqlType = (SQLType)allArguments[0];
|
||||
ContextManager.createLocalSpan("/SJDBC/TRUNK/" + sqlType.name()).setComponent(ComponentsDefine.SHARDING_JDBC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) throws Throwable {
|
||||
ContextManager.stopSpan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
ContextManager.activeSpan().errorOccurred().log(t);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* Copyright 2017, OpenSkywalking Organization All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Project repository: https://github.com/OpenSkywalking/skywalking
|
||||
*/
|
||||
|
||||
package org.skywalking.apm.plugin.sjdbc.define;
|
||||
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||
import org.skywalking.apm.plugin.sjdbc.ExecuteEventListener;
|
||||
|
||||
/**
|
||||
* {@link ExecutorEngineConstructorInterceptor} enhances {@link ExecutorEngine#}'s constructor, initializing {@link ExecuteEventListener}
|
||||
*
|
||||
* @author gaohongtao
|
||||
*/
|
||||
public class ExecutorEngineConstructorInterceptor implements InstanceConstructorInterceptor {
|
||||
|
||||
@Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
|
||||
ExecuteEventListener.init();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Copyright 2017, OpenSkywalking Organization All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Project repository: https://github.com/OpenSkywalking/skywalking
|
||||
*/
|
||||
|
||||
package org.skywalking.apm.plugin.sjdbc.define;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
|
||||
import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
|
||||
import org.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.any;
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
|
||||
|
||||
/**
|
||||
* {@link ExecutorInstrumentation} presents that skywalking intercepts {@link com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine}.
|
||||
*
|
||||
* @author gaohongtao
|
||||
*/
|
||||
public class ExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.dangdang.ddframe.rdb.sharding.executor.ExecutorEngine";
|
||||
|
||||
private static final String EXECUTOR_ENGINE_CONSTRUCTOR_INTERCEPTOR_CLASS = "org.skywalking.apm.plugin.sjdbc.define.ExecutorEngineConstructorInterceptor";
|
||||
|
||||
private static final String EXECUTE_INTERCEPTOR_CLASS = "org.skywalking.apm.plugin.sjdbc.define.ExecuteInterceptor";
|
||||
|
||||
private static final String ASYNC_EXECUTE_INTERCEPTOR_CLASS = "org.skywalking.apm.plugin.sjdbc.define.AsyncExecuteInterceptor";
|
||||
|
||||
@Override
|
||||
protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[] {
|
||||
new ConstructorInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return EXECUTOR_ENGINE_CONSTRUCTOR_INTERCEPTOR_CLASS;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("execute");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return EXECUTE_INTERCEPTOR_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("asyncExecute");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return ASYNC_EXECUTE_INTERCEPTOR_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return byName(ENHANCE_CLASS);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
sharding-jdbc-1.5.x=org.skywalking.apm.plugin.sjdbc.define.ExecutorInstrumentation
|
||||
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Copyright 2017, OpenSkywalking Organization All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* Project repository: https://github.com/OpenSkywalking/skywalking
|
||||
*/
|
||||
|
||||
package org.skywalking.apm.plugin.sjdbc;
|
||||
|
||||
import com.dangdang.ddframe.rdb.sharding.constant.SQLType;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.event.DMLExecutionEvent;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.event.DQLExecutionEvent;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.event.EventExecutionType;
|
||||
import com.dangdang.ddframe.rdb.sharding.executor.threadlocal.ExecutorDataMap;
|
||||
import com.dangdang.ddframe.rdb.sharding.util.EventBusInstance;
|
||||
import com.google.common.base.Optional;
|
||||
import java.sql.SQLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
|
||||
import org.skywalking.apm.agent.core.context.trace.SpanLayer;
|
||||
import org.skywalking.apm.agent.core.context.trace.TraceSegment;
|
||||
import org.skywalking.apm.agent.test.helper.SegmentHelper;
|
||||
import org.skywalking.apm.agent.test.tools.AgentServiceRule;
|
||||
import org.skywalking.apm.agent.test.tools.SegmentStorage;
|
||||
import org.skywalking.apm.agent.test.tools.SegmentStoragePoint;
|
||||
import org.skywalking.apm.agent.test.tools.TracingSegmentRunner;
|
||||
import org.skywalking.apm.network.trace.component.ComponentsDefine;
|
||||
import org.skywalking.apm.plugin.sjdbc.define.AsyncExecuteInterceptor;
|
||||
import org.skywalking.apm.plugin.sjdbc.define.ExecuteInterceptor;
|
||||
import org.skywalking.apm.plugin.sjdbc.define.ExecutorEngineConstructorInterceptor;
|
||||
|
||||
import static org.hamcrest.core.Is.is;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent;
|
||||
import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLayer;
|
||||
import static org.skywalking.apm.agent.test.tools.SpanAssert.assertOccurException;
|
||||
import static org.skywalking.apm.agent.test.tools.SpanAssert.assertTag;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
|
||||
public class InterceptorTest {
|
||||
|
||||
private static ExecutorService ES;
|
||||
|
||||
@SegmentStoragePoint
|
||||
private SegmentStorage segmentStorage;
|
||||
|
||||
@Rule
|
||||
public AgentServiceRule serviceRule = new AgentServiceRule();
|
||||
|
||||
private ExecuteInterceptor executeInterceptor;
|
||||
|
||||
private AsyncExecuteInterceptor asyncExecuteInterceptor;
|
||||
|
||||
private Object[] allArguments;
|
||||
|
||||
@BeforeClass
|
||||
public static void init() {
|
||||
ExecuteEventListener.init();
|
||||
new ExecutorEngineConstructorInterceptor().onConstruct(null, null);
|
||||
ES = Executors.newSingleThreadExecutor();
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void finish() {
|
||||
ES.shutdown();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws SQLException {
|
||||
executeInterceptor = new ExecuteInterceptor();
|
||||
asyncExecuteInterceptor = new AsyncExecuteInterceptor();
|
||||
allArguments = new Object[]{SQLType.DQL, null};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertSyncExecute() throws Throwable {
|
||||
executeInterceptor.beforeMethod(null, null, allArguments, null, null);
|
||||
sendEvent("ds_0", "select * from t_order_0");
|
||||
executeInterceptor.afterMethod(null, null, allArguments, null, null);
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment segment = segmentStorage.getTraceSegments().get(0);
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(segment);
|
||||
assertNotNull(spans);
|
||||
assertThat(spans.size(), is(2));
|
||||
assertSpan(spans.get(0), 0);
|
||||
assertThat(spans.get(1).getOperationName(), is("/SJDBC/TRUNK/DQL"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertAsyncExecute() throws Throwable {
|
||||
executeInterceptor.beforeMethod(null, null, allArguments, null, null);
|
||||
asyncExecuteInterceptor.beforeMethod(null, null, null, null, null);
|
||||
final Map<String, Object> dataMap = ExecutorDataMap.getDataMap();
|
||||
ES.submit(() -> {
|
||||
ExecutorDataMap.setDataMap(dataMap);
|
||||
sendEvent("ds_1", "select * from t_order_1");
|
||||
}).get();
|
||||
asyncExecuteInterceptor.afterMethod(null, null, null, null, null);
|
||||
sendEvent("ds_0", "select * from t_order_0");
|
||||
executeInterceptor.afterMethod(null, null, allArguments, null, null);
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(2));
|
||||
TraceSegment segment0 = segmentStorage.getTraceSegments().get(0);
|
||||
TraceSegment segment1 = segmentStorage.getTraceSegments().get(1);
|
||||
assertThat(segment0.getRefs().size(), is(1));
|
||||
assertNull(segment1.getRefs());
|
||||
List<AbstractTracingSpan> spans0 = SegmentHelper.getSpans(segment0);
|
||||
assertNotNull(spans0);
|
||||
assertThat(spans0.size(), is(1));
|
||||
assertSpan(spans0.get(0), 1);
|
||||
List<AbstractTracingSpan> spans1 = SegmentHelper.getSpans(segment1);
|
||||
assertNotNull(spans1);
|
||||
assertThat(spans1.size(), is(2));
|
||||
assertSpan(spans1.get(0), 0);
|
||||
assertThat(spans1.get(1).getOperationName(), is("/SJDBC/TRUNK/DQL"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void assertExecuteError() throws Throwable {
|
||||
executeInterceptor.beforeMethod(null, null, allArguments, null, null);
|
||||
asyncExecuteInterceptor.beforeMethod(null, null, null, null, null);
|
||||
final Map<String, Object> dataMap = ExecutorDataMap.getDataMap();
|
||||
ES.submit(() -> {
|
||||
ExecutorDataMap.setDataMap(dataMap);
|
||||
sendError();
|
||||
}).get();
|
||||
asyncExecuteInterceptor.handleMethodException(null, null, null, null, new SQLException("test"));
|
||||
asyncExecuteInterceptor.afterMethod(null, null, null, null, null);
|
||||
sendEvent("ds_0", "select * from t_order_0");
|
||||
executeInterceptor.handleMethodException(null, null, allArguments, null, new SQLException("Test"));
|
||||
executeInterceptor.afterMethod(null, null, allArguments, null, null);
|
||||
assertThat(segmentStorage.getTraceSegments().size(), is(2));
|
||||
TraceSegment segment0 = segmentStorage.getTraceSegments().get(0);
|
||||
TraceSegment segment1 = segmentStorage.getTraceSegments().get(1);
|
||||
List<AbstractTracingSpan> spans0 = SegmentHelper.getSpans(segment0);
|
||||
assertNotNull(spans0);
|
||||
assertThat(spans0.size(), is(1));
|
||||
assertErrorSpan(spans0.get(0));
|
||||
List<AbstractTracingSpan> spans1 = SegmentHelper.getSpans(segment1);
|
||||
assertNotNull(spans1);
|
||||
assertThat(spans1.size(), is(2));
|
||||
assertSpan(spans1.get(0), 0);
|
||||
assertErrorSpan(spans1.get(1));
|
||||
}
|
||||
|
||||
private void assertSpan(AbstractTracingSpan span, int index) {
|
||||
assertComponent(span, ComponentsDefine.SHARDING_JDBC);
|
||||
assertLayer(span, SpanLayer.DB);
|
||||
assertTag(span, 0, "sql");
|
||||
assertTag(span, 1, "ds_" + index);
|
||||
assertTag(span, 2, "select * from t_order_" + index);
|
||||
assertThat(span.isExit(), is(true));
|
||||
assertThat(span.getOperationName(), is("/SJDBC/BRANCH/QUERY"));
|
||||
}
|
||||
|
||||
private void assertErrorSpan(AbstractTracingSpan span) {
|
||||
assertOccurException(span, true);
|
||||
}
|
||||
|
||||
private void sendEvent(String datasource, String sql) {
|
||||
DQLExecutionEvent event = new DQLExecutionEvent(datasource, sql, Arrays.asList("1", 100));
|
||||
EventBusInstance.getInstance().post(event);
|
||||
event.setEventExecutionType(EventExecutionType.EXECUTE_SUCCESS);
|
||||
EventBusInstance.getInstance().post(event);
|
||||
}
|
||||
|
||||
private void sendError() {
|
||||
DMLExecutionEvent event = new DMLExecutionEvent("", "", Collections.emptyList());
|
||||
EventBusInstance.getInstance().post(event);
|
||||
event.setEventExecutionType(EventExecutionType.EXECUTE_FAILURE);
|
||||
event.setException(Optional.of(new SQLException("Test")));
|
||||
EventBusInstance.getInstance().post(event);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue