feat: add support of mongodb v3.7.x or higher (#3591)
* feat: add support of mongodb v3.7.x or higher * feat: remove mapping, using EnhancedInstance to mark remotePeer * feat: add support of v3.6.x * fix: disable support will 3.6.x, which will throw ClassCircularityError exception * style: clean code * fix support of 3.8.x~3.11.1, update test case and doc * update stage name * rename class * rename stage
This commit is contained in:
parent
69a28d4591
commit
80af166752
|
|
@ -66,7 +66,7 @@ pipeline {
|
|||
sh './mvnw -f test/plugin/pom.xml clean package -DskipTests -Dbuild_id=wl3_${BUILD_ID} docker:build'
|
||||
}
|
||||
}
|
||||
stage('Test Cases Report (137)') {
|
||||
stage('Test Cases Report (149)') {
|
||||
steps {
|
||||
echo "reserve."
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ pipeline {
|
|||
sh 'bash test/plugin/run.sh --build_id=wl3_${BUILD_ID} sofarpc-scenario'
|
||||
}
|
||||
}
|
||||
stage('mongodb 3.0-3.5.0 (5)') {
|
||||
stage('mongodb 3.4.0-3.11.1 (17)') {
|
||||
steps {
|
||||
sh 'bash test/plugin/run.sh --build_id=wl3_${BUILD_ID} mongodb-3.x-scenario'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<mongo-java-driver.version>3.4.2</mongo-java-driver.version>
|
||||
<mongo-java-driver.version>3.11.0</mongo-java-driver.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
|||
|
|
@ -1,211 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
package org.apache.skywalking.apm.plugin.mongodb.v3;
|
||||
|
||||
import com.mongodb.ReadPreference;
|
||||
import com.mongodb.ServerAddress;
|
||||
import com.mongodb.bulk.DeleteRequest;
|
||||
import com.mongodb.bulk.InsertRequest;
|
||||
import com.mongodb.bulk.UpdateRequest;
|
||||
import com.mongodb.bulk.WriteRequest;
|
||||
import com.mongodb.connection.Cluster;
|
||||
import com.mongodb.connection.ServerDescription;
|
||||
import com.mongodb.operation.CountOperation;
|
||||
import com.mongodb.operation.CreateCollectionOperation;
|
||||
import com.mongodb.operation.CreateIndexesOperation;
|
||||
import com.mongodb.operation.CreateViewOperation;
|
||||
import com.mongodb.operation.DeleteOperation;
|
||||
import com.mongodb.operation.DistinctOperation;
|
||||
import com.mongodb.operation.FindAndDeleteOperation;
|
||||
import com.mongodb.operation.FindAndReplaceOperation;
|
||||
import com.mongodb.operation.FindAndUpdateOperation;
|
||||
import com.mongodb.operation.FindOperation;
|
||||
import com.mongodb.operation.GroupOperation;
|
||||
import com.mongodb.operation.InsertOperation;
|
||||
import com.mongodb.operation.ListCollectionsOperation;
|
||||
import com.mongodb.operation.MapReduceToCollectionOperation;
|
||||
import com.mongodb.operation.MapReduceWithInlineResultsOperation;
|
||||
import com.mongodb.operation.MixedBulkWriteOperation;
|
||||
import com.mongodb.operation.ReadOperation;
|
||||
import com.mongodb.operation.UpdateOperation;
|
||||
import com.mongodb.operation.WriteOperation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
|
||||
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.InstanceConstructorInterceptor;
|
||||
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.network.trace.component.ComponentsDefine;
|
||||
import org.bson.BsonDocument;
|
||||
|
||||
/**
|
||||
* {@link MongoDBMethodInterceptor} intercept method of {@link com.mongodb.Mongo#execute(ReadOperation, ReadPreference)}
|
||||
* or {@link com.mongodb.Mongo#execute(WriteOperation)}. record the mongoDB host, operation name and the key of the
|
||||
* operation.
|
||||
*
|
||||
* @author baiyang
|
||||
*/
|
||||
public class MongoDBMethodInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor {
|
||||
|
||||
private static final String DB_TYPE = "MongoDB";
|
||||
|
||||
private static final String MONGO_DB_OP_PREFIX = "MongoDB/";
|
||||
|
||||
private static final int FILTER_LENGTH_LIMIT = 256;
|
||||
|
||||
private static final String EMPTY = "";
|
||||
|
||||
/**
|
||||
* Convert ReadOperation interface or WriteOperation interface to the implementation class. Get the method name and
|
||||
* filter info.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
private String getTraceParam(Object obj) {
|
||||
if (obj instanceof CountOperation) {
|
||||
BsonDocument filter = ((CountOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof DistinctOperation) {
|
||||
BsonDocument filter = ((DistinctOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof FindOperation) {
|
||||
BsonDocument filter = ((FindOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof GroupOperation) {
|
||||
BsonDocument filter = ((GroupOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof ListCollectionsOperation) {
|
||||
BsonDocument filter = ((ListCollectionsOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof MapReduceWithInlineResultsOperation) {
|
||||
BsonDocument filter = ((MapReduceWithInlineResultsOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof DeleteOperation) {
|
||||
List<DeleteRequest> writeRequestList = ((DeleteOperation)obj).getDeleteRequests();
|
||||
return getFilter(writeRequestList);
|
||||
} else if (obj instanceof InsertOperation) {
|
||||
List<InsertRequest> writeRequestList = ((InsertOperation)obj).getInsertRequests();
|
||||
return getFilter(writeRequestList);
|
||||
} else if (obj instanceof UpdateOperation) {
|
||||
List<UpdateRequest> writeRequestList = ((UpdateOperation)obj).getUpdateRequests();
|
||||
return getFilter(writeRequestList);
|
||||
} else if (obj instanceof CreateCollectionOperation) {
|
||||
String filter = ((CreateCollectionOperation)obj).getCollectionName();
|
||||
return limitFilter(filter);
|
||||
} else if (obj instanceof CreateIndexesOperation) {
|
||||
List<String> filter = ((CreateIndexesOperation)obj).getIndexNames();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof CreateViewOperation) {
|
||||
String filter = ((CreateViewOperation)obj).getViewName();
|
||||
return limitFilter(filter);
|
||||
} else if (obj instanceof FindAndDeleteOperation) {
|
||||
BsonDocument filter = ((FindAndDeleteOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof FindAndReplaceOperation) {
|
||||
BsonDocument filter = ((FindAndReplaceOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof FindAndUpdateOperation) {
|
||||
BsonDocument filter = ((FindAndUpdateOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof MapReduceToCollectionOperation) {
|
||||
BsonDocument filter = ((MapReduceToCollectionOperation)obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof MixedBulkWriteOperation) {
|
||||
List<? extends WriteRequest> writeRequestList = ((MixedBulkWriteOperation)obj).getWriteRequests();
|
||||
return getFilter(writeRequestList);
|
||||
} else {
|
||||
return EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
private String getFilter(List<? extends WriteRequest> writeRequestList) {
|
||||
StringBuilder params = new StringBuilder();
|
||||
for (WriteRequest request : writeRequestList) {
|
||||
if (request instanceof InsertRequest) {
|
||||
params.append(((InsertRequest)request).getDocument().toString()).append(",");
|
||||
} else if (request instanceof DeleteRequest) {
|
||||
params.append(((DeleteRequest)request).getFilter()).append(",");
|
||||
} else if (request instanceof UpdateRequest) {
|
||||
params.append(((UpdateRequest)request).getFilter()).append(",");
|
||||
}
|
||||
if (params.length() > FILTER_LENGTH_LIMIT) {
|
||||
params.append("...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return params.toString();
|
||||
}
|
||||
|
||||
private String limitFilter(String filter) {
|
||||
final StringBuilder params = new StringBuilder();
|
||||
if (filter.length() > FILTER_LENGTH_LIMIT) {
|
||||
return params.append(filter.substring(0, FILTER_LENGTH_LIMIT)).append("...").toString();
|
||||
} else {
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
@Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
|
||||
Object[] arguments = allArguments;
|
||||
|
||||
String executeMethod = arguments[0].getClass().getSimpleName();
|
||||
String remotePeer = (String)objInst.getSkyWalkingDynamicField();
|
||||
AbstractSpan span = ContextManager.createExitSpan(MONGO_DB_OP_PREFIX + executeMethod, new ContextCarrier(), remotePeer);
|
||||
span.setComponent(ComponentsDefine.MONGO_DRIVER);
|
||||
Tags.DB_TYPE.set(span, DB_TYPE);
|
||||
SpanLayer.asDB(span);
|
||||
|
||||
if (Config.Plugin.MongoDB.TRACE_PARAM) {
|
||||
Tags.DB_STATEMENT.set(span, executeMethod + " " + this.getTraceParam(arguments[0]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@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) {
|
||||
AbstractSpan activeSpan = ContextManager.activeSpan();
|
||||
activeSpan.errorOccurred();
|
||||
activeSpan.log(t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
|
||||
Cluster cluster = (Cluster)allArguments[0];
|
||||
StringBuilder peers = new StringBuilder();
|
||||
for (ServerDescription description : cluster.getDescription().getServerDescriptions()) {
|
||||
ServerAddress address = description.getAddress();
|
||||
peers.append(address.getHost() + ":" + address.getPort() + ";");
|
||||
}
|
||||
|
||||
objInst.setSkyWalkingDynamicField(peers.subSequence(0, peers.length() - 1).toString());
|
||||
}
|
||||
}
|
||||
|
|
@ -17,62 +17,42 @@
|
|||
*/
|
||||
|
||||
|
||||
package org.apache.skywalking.apm.plugin.mongodb.v3.define;
|
||||
package org.apache.skywalking.apm.plugin.mongodb.v3.define.v30;
|
||||
|
||||
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.agent.core.plugin.match.NameMatch;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
|
||||
import org.apache.skywalking.apm.plugin.mongodb.v3.interceptor.v30.MongoDBInterceptor;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
|
||||
|
||||
/**
|
||||
* Enhance {@code com.mongodb.Mongo} instance, and intercept {@code com.mongodb.Mongo#execute(...)} method,
|
||||
* this method is a unified entrance of execute mongo command.
|
||||
* <p>
|
||||
* support: 3.0.x~3.5.x
|
||||
*
|
||||
* @author scolia
|
||||
* @see MongoDBInterceptor
|
||||
*/
|
||||
@SuppressWarnings({"Duplicates"})
|
||||
public class MongoDBInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String WITNESS_CLASS = "com.mongodb.connection.WriteCommandProtocol";
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.mongodb.Mongo";
|
||||
|
||||
private static final String MONGDB_METHOD_INTERCET_CLASS = "org.apache.skywalking.apm.plugin.mongodb.v3.MongoDBMethodInterceptor";
|
||||
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.mongodb.v3.interceptor.v30.MongoDBInterceptor";
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[] {
|
||||
new ConstructorInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return takesArgumentWithType(0, "com.mongodb.connection.Cluster");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return MONGDB_METHOD_INTERCET_CLASS;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[] {
|
||||
new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("execute");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return MONGDB_METHOD_INTERCET_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
protected String[] witnessClasses() {
|
||||
// this class only exist in version: 3.0.x~3.5.x
|
||||
return new String[]{WITNESS_CLASS};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -80,4 +60,43 @@ public class MongoDBInstrumentation extends ClassInstanceMethodsEnhancePluginDef
|
|||
return NameMatch.byName(ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[]{new ConstructorInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return takesArgumentWithType(0, "com.mongodb.connection.Cluster");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return INTERCEPTOR_CLASS;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("execute");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPTOR_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* 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.mongodb.v3.define.v37;
|
||||
|
||||
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.mongodb.v3.interceptor.v37.MongoDBClientDelegateInterceptor;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.named;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
|
||||
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
|
||||
|
||||
/**
|
||||
* Enhance {@code com.mongodb.client.internal.MongoClientDelegate} instance, and intercept
|
||||
* {@code com.mongodb.client.internal.MongoClientDelegate#getOperationExecutor()}, this is the only way to
|
||||
* get OperationExecutor which is unified entrance of execute mongo command. we can mark OperationExecutor
|
||||
* which connection belongs to.
|
||||
* <p>
|
||||
* support: 3.7.x or higher
|
||||
*
|
||||
* @author scolia
|
||||
* @see MongoDBOperationExecutorInstrumentation
|
||||
* @see MongoDBClientDelegateInterceptor
|
||||
*/
|
||||
public class MongoDBClientDelegateInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.mongodb.client.internal.MongoClientDelegate";
|
||||
|
||||
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.mongodb.v3.interceptor.v37.MongoDBClientDelegateInterceptor";
|
||||
|
||||
@Override
|
||||
protected String[] witnessClasses() {
|
||||
return new String[]{ENHANCE_CLASS};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return byName(ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[]{new ConstructorInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return takesArgumentWithType(0, "com.mongodb.connection.Cluster");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return INTERCEPTOR_CLASS;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return named("getOperationExecutor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPTOR_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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.mongodb.v3.define.v37;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch;
|
||||
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.agent.core.plugin.match.NameMatch;
|
||||
import org.apache.skywalking.apm.plugin.mongodb.v3.interceptor.v37.MongoDBOperationExecutorInterceptor;
|
||||
|
||||
/**
|
||||
* {@code com.mongodb.client.internal.OperationExecutor} which is unified entrance of execute mongo command.
|
||||
* so we can intercept {@code com.mongodb.client.internal.OperationExecutor#execute(...)} method
|
||||
* to known which command will be execute.
|
||||
* <p>
|
||||
* support: 3.7.x
|
||||
*
|
||||
* @author scolia
|
||||
* @see MongoDBOperationExecutorInterceptor
|
||||
*/
|
||||
@SuppressWarnings({"Duplicates"})
|
||||
public class MongoDBOperationExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String WITNESS_CLASS = "com.mongodb.client.internal.MongoClientDelegate";
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor";
|
||||
|
||||
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.mongodb.v3.interceptor.v37.MongoDBOperationExecutorInterceptor";
|
||||
|
||||
private static final String METHOD_NAME = "execute";
|
||||
|
||||
private static final String ARGUMENT_TYPE = "com.mongodb.session.ClientSession";
|
||||
|
||||
@Override
|
||||
protected String[] witnessClasses() {
|
||||
return new String[]{WITNESS_CLASS};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return NameMatch.byName(ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return ElementMatchers
|
||||
// 3.7.x
|
||||
.named(METHOD_NAME).and(ArgumentTypeNameMatch.takesArgumentWithType(1, ARGUMENT_TYPE))
|
||||
.or(ElementMatchers.<MethodDescription>named(METHOD_NAME)
|
||||
.and(ArgumentTypeNameMatch.takesArgumentWithType(2, ARGUMENT_TYPE))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPTOR_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* 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.mongodb.v3.define.v38;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import net.bytebuddy.matcher.ElementMatchers;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch;
|
||||
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.agent.core.plugin.match.NameMatch;
|
||||
|
||||
/**
|
||||
* same whit {@link org.apache.skywalking.apm.plugin.mongodb.v3.define.v37.MongoDBOperationExecutorInstrumentation}
|
||||
* <p>
|
||||
* support: 3.8.x or higher
|
||||
*
|
||||
* @author scolia
|
||||
*/
|
||||
public class MongoDBOperationExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String WITNESS_CLASS = "com.mongodb.client.ClientSession";
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor";
|
||||
|
||||
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.mongodb.v3.interceptor.v37.MongoDBOperationExecutorInterceptor";
|
||||
|
||||
private static final String METHOD_NAME = "execute";
|
||||
|
||||
private static final String ARGUMENT_TYPE = "com.mongodb.client.ClientSession";
|
||||
|
||||
@Override
|
||||
protected String[] witnessClasses() {
|
||||
return new String[]{WITNESS_CLASS};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return NameMatch.byName(ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() {
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getMethodsMatcher() {
|
||||
return ElementMatchers
|
||||
// 3.8.x~3.11.x
|
||||
.named(METHOD_NAME).and(ArgumentTypeNameMatch.takesArgumentWithType(2, ARGUMENT_TYPE))
|
||||
.or(ElementMatchers.<MethodDescription>named(METHOD_NAME)
|
||||
.and(ArgumentTypeNameMatch.takesArgumentWithType(3, ARGUMENT_TYPE))
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMethodsInterceptor() {
|
||||
return INTERCEPTOR_CLASS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOverrideArgs() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* 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.mongodb.v3.interceptor.v30;
|
||||
|
||||
import com.mongodb.connection.Cluster;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||
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.mongodb.v3.support.MongoRemotePeerHelper;
|
||||
import org.apache.skywalking.apm.plugin.mongodb.v3.support.MongoSpanHelper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Intercept method of {@code com.mongodb.Mongo#execute(ReadOperation, ReadPreference)} or
|
||||
* {@code com.mongodb.Mongo#execute(WriteOperation)}. record the MongoDB host, operation name and the key of the
|
||||
* operation.
|
||||
* <p>
|
||||
* only supported: 3.0.x-3.5.x
|
||||
*
|
||||
* @author scolia
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "Duplicates"})
|
||||
public class MongoDBInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor {
|
||||
|
||||
private static final ILog logger = LogManager.getLogger(MongoDBInterceptor.class);
|
||||
|
||||
@Override
|
||||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
|
||||
Cluster cluster = (Cluster) allArguments[0];
|
||||
String peers = MongoRemotePeerHelper.getRemotePeer(cluster);
|
||||
objInst.setSkyWalkingDynamicField(peers);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, MethodInterceptResult result) {
|
||||
String executeMethod = allArguments[0].getClass().getSimpleName();
|
||||
String remotePeer = (String) objInst.getSkyWalkingDynamicField();
|
||||
if (logger.isDebugEnable()) {
|
||||
logger.debug("Mongo execute: [executeMethod: {}, remotePeer: {}]", executeMethod, remotePeer);
|
||||
}
|
||||
MongoSpanHelper.createExitSpan(executeMethod, remotePeer, allArguments[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) {
|
||||
ContextManager.stopSpan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
AbstractSpan activeSpan = ContextManager.activeSpan();
|
||||
activeSpan.errorOccurred();
|
||||
activeSpan.log(t);
|
||||
}
|
||||
}
|
||||
|
|
@ -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.mongodb.v3.interceptor.v37;
|
||||
|
||||
import com.mongodb.connection.Cluster;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||
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.mongodb.v3.support.MongoRemotePeerHelper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author scolia
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class MongoDBClientDelegateInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor {
|
||||
|
||||
private static final ILog logger = LogManager.getLogger(MongoDBClientDelegateInterceptor.class);
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
|
||||
Cluster cluster = (Cluster) allArguments[0];
|
||||
String remotePeer = MongoRemotePeerHelper.getRemotePeer(cluster);
|
||||
objInst.setSkyWalkingDynamicField(remotePeer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, MethodInterceptResult result) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Object ret) {
|
||||
if (ret instanceof EnhancedInstance) {
|
||||
// pass remotePeer to OperationExecutor, which will be wrapper as EnhancedInstance
|
||||
// @see: org.apache.skywalking.apm.plugin.mongodb.v3.define.v37.MongoDBOperationExecutorInstrumentation
|
||||
EnhancedInstance retInstance = (EnhancedInstance) ret;
|
||||
String remotePeer = (String) objInst.getSkyWalkingDynamicField();
|
||||
if (logger.isDebugEnable()) {
|
||||
logger.debug("Mark OperationExecutor remotePeer: {}", remotePeer);
|
||||
}
|
||||
retInstance.setSkyWalkingDynamicField(remotePeer);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.mongodb.v3.interceptor.v37;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextManager;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.ILog;
|
||||
import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
|
||||
import org.apache.skywalking.apm.agent.core.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.mongodb.v3.support.MongoSpanHelper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* @author scolia
|
||||
*/
|
||||
@SuppressWarnings("Duplicates")
|
||||
public class MongoDBOperationExecutorInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
private static final ILog logger = LogManager.getLogger(MongoDBOperationExecutorInterceptor.class);
|
||||
|
||||
@Override
|
||||
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
MethodInterceptResult result) {
|
||||
String executeMethod = allArguments[0].getClass().getSimpleName();
|
||||
// OperationExecutor has be mark it's remotePeer
|
||||
// @see: MongoDBClientDelegateInterceptor.afterMethod
|
||||
String remotePeer = (String) objInst.getSkyWalkingDynamicField();
|
||||
if (logger.isDebugEnable()) {
|
||||
logger.debug("Mongo execute: [executeMethod: {}, remotePeer: {}]", executeMethod, remotePeer);
|
||||
}
|
||||
MongoSpanHelper.createExitSpan(executeMethod, remotePeer, allArguments[0]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
|
||||
Object ret) {
|
||||
ContextManager.stopSpan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
|
||||
Class<?>[] argumentsTypes, Throwable t) {
|
||||
AbstractSpan activeSpan = ContextManager.activeSpan();
|
||||
activeSpan.errorOccurred();
|
||||
activeSpan.log(t);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* 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.mongodb.v3.support;
|
||||
|
||||
/**
|
||||
* @author scolia
|
||||
*/
|
||||
public class MongoConstants {
|
||||
|
||||
private MongoConstants() {
|
||||
}
|
||||
|
||||
public static final String DB_TYPE = "MongoDB";
|
||||
|
||||
public static final String MONGO_DB_OP_PREFIX = "MongoDB/";
|
||||
|
||||
public static final int FILTER_LENGTH_LIMIT = 256;
|
||||
|
||||
public static final String EMPTY = "";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* 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.mongodb.v3.support;
|
||||
|
||||
import com.mongodb.bulk.DeleteRequest;
|
||||
import com.mongodb.bulk.InsertRequest;
|
||||
import com.mongodb.bulk.UpdateRequest;
|
||||
import com.mongodb.bulk.WriteRequest;
|
||||
import com.mongodb.operation.*;
|
||||
import org.bson.BsonDocument;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author scolia
|
||||
*/
|
||||
@SuppressWarnings({"deprecation", "Duplicates"})
|
||||
public class MongoOperationHelper {
|
||||
|
||||
|
||||
private MongoOperationHelper() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert ReadOperation interface or WriteOperation interface to the implementation class. Get the method name and
|
||||
* filter info.
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static String getTraceParam(Object obj) {
|
||||
if (obj instanceof CountOperation) {
|
||||
BsonDocument filter = ((CountOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof DistinctOperation) {
|
||||
BsonDocument filter = ((DistinctOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof FindOperation) {
|
||||
BsonDocument filter = ((FindOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof GroupOperation) {
|
||||
BsonDocument filter = ((GroupOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof ListCollectionsOperation) {
|
||||
BsonDocument filter = ((ListCollectionsOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof MapReduceWithInlineResultsOperation) {
|
||||
BsonDocument filter = ((MapReduceWithInlineResultsOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof DeleteOperation) {
|
||||
List<DeleteRequest> writeRequestList = ((DeleteOperation) obj).getDeleteRequests();
|
||||
return getFilter(writeRequestList);
|
||||
} else if (obj instanceof InsertOperation) {
|
||||
List<InsertRequest> writeRequestList = ((InsertOperation) obj).getInsertRequests();
|
||||
return getFilter(writeRequestList);
|
||||
} else if (obj instanceof UpdateOperation) {
|
||||
List<UpdateRequest> writeRequestList = ((UpdateOperation) obj).getUpdateRequests();
|
||||
return getFilter(writeRequestList);
|
||||
} else if (obj instanceof CreateCollectionOperation) {
|
||||
String filter = ((CreateCollectionOperation) obj).getCollectionName();
|
||||
return limitFilter(filter);
|
||||
} else if (obj instanceof CreateIndexesOperation) {
|
||||
List<String> filter = ((CreateIndexesOperation) obj).getIndexNames();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof CreateViewOperation) {
|
||||
String filter = ((CreateViewOperation) obj).getViewName();
|
||||
return limitFilter(filter);
|
||||
} else if (obj instanceof FindAndDeleteOperation) {
|
||||
BsonDocument filter = ((FindAndDeleteOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof FindAndReplaceOperation) {
|
||||
BsonDocument filter = ((FindAndReplaceOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof FindAndUpdateOperation) {
|
||||
BsonDocument filter = ((FindAndUpdateOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof MapReduceToCollectionOperation) {
|
||||
BsonDocument filter = ((MapReduceToCollectionOperation) obj).getFilter();
|
||||
return limitFilter(filter.toString());
|
||||
} else if (obj instanceof MixedBulkWriteOperation) {
|
||||
List<? extends WriteRequest> writeRequestList = ((MixedBulkWriteOperation) obj).getWriteRequests();
|
||||
return getFilter(writeRequestList);
|
||||
} else {
|
||||
return MongoConstants.EMPTY;
|
||||
}
|
||||
}
|
||||
|
||||
private static String getFilter(List<? extends WriteRequest> writeRequestList) {
|
||||
StringBuilder params = new StringBuilder();
|
||||
for (WriteRequest request : writeRequestList) {
|
||||
if (request instanceof InsertRequest) {
|
||||
params.append(((InsertRequest) request).getDocument().toString()).append(",");
|
||||
} else if (request instanceof DeleteRequest) {
|
||||
params.append(((DeleteRequest) request).getFilter()).append(",");
|
||||
} else if (request instanceof UpdateRequest) {
|
||||
params.append(((UpdateRequest) request).getFilter()).append(",");
|
||||
}
|
||||
if (params.length() > MongoConstants.FILTER_LENGTH_LIMIT) {
|
||||
params.append("...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return params.toString();
|
||||
}
|
||||
|
||||
private static String limitFilter(String filter) {
|
||||
final StringBuilder params = new StringBuilder();
|
||||
if (filter.length() > MongoConstants.FILTER_LENGTH_LIMIT) {
|
||||
return params.append(filter, 0, MongoConstants.FILTER_LENGTH_LIMIT).append("...").toString();
|
||||
} else {
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.mongodb.v3.support;
|
||||
|
||||
import com.mongodb.ServerAddress;
|
||||
import com.mongodb.connection.Cluster;
|
||||
import com.mongodb.connection.ServerDescription;
|
||||
|
||||
/**
|
||||
* @author scolia
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MongoRemotePeerHelper {
|
||||
|
||||
private MongoRemotePeerHelper() {
|
||||
}
|
||||
|
||||
|
||||
public static String getRemotePeer(Cluster cluster) {
|
||||
StringBuilder peersBuilder = new StringBuilder();
|
||||
for (ServerDescription description : cluster.getDescription().getAll()) {
|
||||
ServerAddress address = description.getAddress();
|
||||
peersBuilder.append(address.getHost()).append(":").append(address.getPort()).append(";");
|
||||
}
|
||||
return peersBuilder.substring(0, peersBuilder.length() - 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -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.mongodb.v3.support;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
|
||||
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.network.trace.component.ComponentsDefine;
|
||||
|
||||
/**
|
||||
* @author scolia
|
||||
*/
|
||||
public class MongoSpanHelper {
|
||||
|
||||
private MongoSpanHelper() {
|
||||
}
|
||||
|
||||
public static void createExitSpan(String executeMethod, String remotePeer, Object operation) {
|
||||
AbstractSpan span = ContextManager.createExitSpan(MongoConstants.MONGO_DB_OP_PREFIX + executeMethod, new ContextCarrier(), remotePeer);
|
||||
span.setComponent(ComponentsDefine.MONGO_DRIVER);
|
||||
Tags.DB_TYPE.set(span, MongoConstants.DB_TYPE);
|
||||
SpanLayer.asDB(span);
|
||||
|
||||
if (Config.Plugin.MongoDB.TRACE_PARAM) {
|
||||
Tags.DB_STATEMENT.set(span, executeMethod + " " + MongoOperationHelper.getTraceParam(operation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,4 +14,10 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
mongodb-3.x=org.apache.skywalking.apm.plugin.mongodb.v3.define.MongoDBInstrumentation
|
||||
# v3.0.x~v3.5.x
|
||||
mongodb-3.x=org.apache.skywalking.apm.plugin.mongodb.v3.define.v30.MongoDBInstrumentation
|
||||
# v3.7.x~
|
||||
mongodb-3.x=org.apache.skywalking.apm.plugin.mongodb.v3.define.v37.MongoDBClientDelegateInstrumentation
|
||||
mongodb-3.x=org.apache.skywalking.apm.plugin.mongodb.v3.define.v37.MongoDBOperationExecutorInstrumentation
|
||||
# v3.8.x~
|
||||
mongodb-3.x=org.apache.skywalking.apm.plugin.mongodb.v3.define.v38.MongoDBOperationExecutorInstrumentation
|
||||
|
|
@ -17,13 +17,11 @@
|
|||
*/
|
||||
|
||||
|
||||
package org.apache.skywalking.apm.plugin.mongodb.v3;
|
||||
package org.apache.skywalking.apm.plugin.mongodb.v3.interceptor.v30;
|
||||
|
||||
import com.mongodb.Mongo;
|
||||
import com.mongodb.MongoNamespace;
|
||||
import com.mongodb.operation.FindOperation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
|
||||
|
|
@ -33,11 +31,7 @@ import org.apache.skywalking.apm.agent.core.context.util.TagValuePair;
|
|||
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.helper.SpanHelper;
|
||||
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.agent.test.tools.*;
|
||||
import org.bson.BsonDocument;
|
||||
import org.bson.BsonString;
|
||||
import org.bson.codecs.Decoder;
|
||||
|
|
@ -52,13 +46,16 @@ import org.powermock.api.mockito.PowerMockito;
|
|||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
|
||||
public class MongoDBMethodInterceptorTest {
|
||||
public class MongoDBInterceptorTest {
|
||||
|
||||
@SegmentStoragePoint
|
||||
private SegmentStorage segmentStorage;
|
||||
|
|
@ -66,7 +63,7 @@ public class MongoDBMethodInterceptorTest {
|
|||
@Rule
|
||||
public AgentServiceRule serviceRule = new AgentServiceRule();
|
||||
|
||||
private MongoDBMethodInterceptor interceptor;
|
||||
private MongoDBInterceptor interceptor;
|
||||
|
||||
@Mock
|
||||
private EnhancedInstance enhancedInstance;
|
||||
|
|
@ -78,7 +75,7 @@ public class MongoDBMethodInterceptorTest {
|
|||
@Before
|
||||
public void setUp() throws Exception {
|
||||
|
||||
interceptor = new MongoDBMethodInterceptor();
|
||||
interceptor = new MongoDBInterceptor();
|
||||
|
||||
Config.Plugin.MongoDB.TRACE_PARAM = true;
|
||||
|
||||
|
|
@ -91,8 +88,8 @@ public class MongoDBMethodInterceptorTest {
|
|||
FindOperation findOperation = new FindOperation(mongoNamespace, decoder);
|
||||
findOperation.filter(document);
|
||||
|
||||
arguments = new Object[] {findOperation};
|
||||
argumentTypes = new Class[] {findOperation.getClass()};
|
||||
arguments = new Object[]{findOperation};
|
||||
argumentTypes = new Class[]{findOperation.getClass()};
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -125,7 +122,7 @@ public class MongoDBMethodInterceptorTest {
|
|||
assertThat(span.getOperationName(), is("MongoDB/FindOperation"));
|
||||
assertThat(SpanHelper.getComponentId(span), is(42));
|
||||
List<TagValuePair> tags = SpanHelper.getTags(span);
|
||||
assertThat(tags.get(1).getValue(), is("FindOperation { \"name\" : \"by\" }"));
|
||||
assertThat(tags.get(1).getValue(), is("FindOperation {\"name\": \"by\"}"));
|
||||
assertThat(tags.get(0).getValue(), is("MongoDB"));
|
||||
assertThat(span.isExit(), is(true));
|
||||
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.DB));
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
package org.apache.skywalking.apm.plugin.mongodb.v3.interceptor.v37;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author scolia
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
public class MongoDBClientDelegateInterceptorTest {
|
||||
|
||||
private MongoDBClientDelegateInterceptor interceptor;
|
||||
|
||||
@Mock
|
||||
private EnhancedInstance clientDelegateEnhancedInstance;
|
||||
|
||||
private EnhancedInstance retEnhancedInstance;
|
||||
|
||||
private final static String REMOTE_PEER = "127.0.0.1:27017";
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
interceptor = new MongoDBClientDelegateInterceptor();
|
||||
retEnhancedInstance = new FieldEnhancedInstance();
|
||||
when(clientDelegateEnhancedInstance.getSkyWalkingDynamicField()).thenReturn(REMOTE_PEER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAfterMethod() {
|
||||
interceptor.afterMethod(clientDelegateEnhancedInstance, null, null, null, retEnhancedInstance);
|
||||
Assert.assertEquals(REMOTE_PEER, retEnhancedInstance.getSkyWalkingDynamicField());
|
||||
}
|
||||
|
||||
private static class FieldEnhancedInstance implements EnhancedInstance {
|
||||
|
||||
private Object skyWalkingDynamicField;
|
||||
|
||||
@Override
|
||||
public Object getSkyWalkingDynamicField() {
|
||||
return skyWalkingDynamicField;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSkyWalkingDynamicField(Object value) {
|
||||
this.skyWalkingDynamicField = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -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.mongodb.v3.interceptor.v37;
|
||||
|
||||
import com.mongodb.MongoNamespace;
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.client.internal.OperationExecutor;
|
||||
import com.mongodb.operation.FindOperation;
|
||||
import com.mongodb.operation.WriteOperation;
|
||||
import org.apache.skywalking.apm.agent.core.conf.Config;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
|
||||
import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
|
||||
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.context.util.TagValuePair;
|
||||
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.helper.SpanHelper;
|
||||
import org.apache.skywalking.apm.agent.test.tools.*;
|
||||
import org.bson.BsonDocument;
|
||||
import org.bson.BsonString;
|
||||
import org.bson.codecs.Decoder;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.MatcherAssert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.modules.junit4.PowerMockRunnerDelegate;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* @author scolia
|
||||
*/
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PowerMockRunnerDelegate(TracingSegmentRunner.class)
|
||||
public class MongoDBOperationExecutorInterceptorTest {
|
||||
|
||||
@SegmentStoragePoint
|
||||
private SegmentStorage segmentStorage;
|
||||
|
||||
@Rule
|
||||
public AgentServiceRule serviceRule = new AgentServiceRule();
|
||||
|
||||
@Mock
|
||||
private EnhancedInstance enhancedInstance;
|
||||
|
||||
private MongoDBOperationExecutorInterceptor interceptor;
|
||||
|
||||
private Object[] arguments;
|
||||
|
||||
private Class[] argumentTypes;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
interceptor = new MongoDBOperationExecutorInterceptor();
|
||||
|
||||
Config.Plugin.MongoDB.TRACE_PARAM = true;
|
||||
|
||||
when(enhancedInstance.getSkyWalkingDynamicField()).thenReturn("127.0.0.1:27017");
|
||||
|
||||
BsonDocument document = new BsonDocument();
|
||||
document.append("name", new BsonString("by"));
|
||||
MongoNamespace mongoNamespace = new MongoNamespace("test.user");
|
||||
Decoder decoder = PowerMockito.mock(Decoder.class);
|
||||
FindOperation findOperation = new FindOperation(mongoNamespace, decoder);
|
||||
findOperation.filter(document);
|
||||
|
||||
arguments = new Object[]{findOperation};
|
||||
argumentTypes = new Class[]{findOperation.getClass()};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIntercept() throws Throwable {
|
||||
interceptor.beforeMethod(enhancedInstance, getMethod(), arguments, argumentTypes, null);
|
||||
interceptor.afterMethod(enhancedInstance, getMethod(), arguments, argumentTypes, null);
|
||||
|
||||
MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertRedisSpan(spans.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInterceptWithException() throws Throwable {
|
||||
interceptor.beforeMethod(enhancedInstance, getMethod(), arguments, argumentTypes, null);
|
||||
interceptor.handleMethodException(enhancedInstance, getMethod(), arguments, argumentTypes, new RuntimeException());
|
||||
interceptor.afterMethod(enhancedInstance, getMethod(), arguments, argumentTypes, null);
|
||||
|
||||
MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1));
|
||||
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
|
||||
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
|
||||
assertRedisSpan(spans.get(0));
|
||||
List<LogDataEntity> logDataEntities = SpanHelper.getLogs(spans.get(0));
|
||||
assertThat(logDataEntities.size(), is(1));
|
||||
SpanAssert.assertException(logDataEntities.get(0), RuntimeException.class);
|
||||
}
|
||||
|
||||
private void assertRedisSpan(AbstractTracingSpan span) {
|
||||
assertThat(span.getOperationName(), is("MongoDB/FindOperation"));
|
||||
assertThat(SpanHelper.getComponentId(span), is(42));
|
||||
List<TagValuePair> tags = SpanHelper.getTags(span);
|
||||
assertThat(tags.get(1).getValue(), is("FindOperation {\"name\": \"by\"}"));
|
||||
assertThat(tags.get(0).getValue(), is("MongoDB"));
|
||||
assertThat(span.isExit(), is(true));
|
||||
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.DB));
|
||||
}
|
||||
|
||||
private Method getMethod() throws Exception {
|
||||
return OperationExecutor.class.getMethod("execute", WriteOperation.class, ReadConcern.class);
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
* [Jedis](https://github.com/xetorthio/jedis) 2.x
|
||||
* [Redisson](https://github.com/redisson/redisson) Easy Java Redis client 3.5.2+
|
||||
* [Lettuce](https://github.com/lettuce-io/lettuce-core) 5.x (Optional²)
|
||||
* [MongoDB Java Driver](https://github.com/mongodb/mongo-java-driver) 2.13-2.14,3.4.0-3.5.0
|
||||
* [MongoDB Java Driver](https://github.com/mongodb/mongo-java-driver) 2.13-2.14, 3.4.0-3.5.0, 3.7.x-3.11.1
|
||||
* Memcached Client
|
||||
* [Spymemcached](https://github.com/couchbase/spymemcached) 2.x
|
||||
* [Xmemcached](https://github.com/killme2008/xmemcached) 2.x
|
||||
|
|
|
|||
|
|
@ -19,3 +19,15 @@
|
|||
3.4.2
|
||||
3.4.3
|
||||
3.5.0
|
||||
3.7.0
|
||||
3.7.1
|
||||
3.8.0
|
||||
3.8.1
|
||||
3.8.2
|
||||
3.9.0
|
||||
3.9.1
|
||||
3.10.0
|
||||
3.10.1
|
||||
3.10.2
|
||||
3.11.0
|
||||
3.11.1
|
||||
Loading…
Reference in New Issue