Skip to content

Commit 80b5ac8

Browse files
author
youjie_li
committed
support mongo db.instance and AggregateOperation test scenarios
1 parent 5801ee2 commit 80b5ac8

File tree

11 files changed

+217
-74
lines changed

11 files changed

+217
-74
lines changed

apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mongodb/v3/support/MongoSpanHelper.java

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,20 @@
2121
import com.mongodb.MongoNamespace;
2222
import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
2323
import org.apache.skywalking.apm.agent.core.context.ContextManager;
24+
import org.apache.skywalking.apm.agent.core.context.tag.AbstractTag;
2425
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
2526
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
2627
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
27-
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
2828
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
2929
import org.apache.skywalking.apm.plugin.mongodb.v3.MongoPluginConfig;
30+
import org.apache.skywalking.apm.util.StringUtil;
3031

3132
import java.lang.reflect.Field;
3233

3334
public class MongoSpanHelper {
3435

36+
private static final AbstractTag<String> DB_COLLECTION_TAG = Tags.ofKey("db.collection");
37+
3538
private MongoSpanHelper() {
3639
}
3740

@@ -43,33 +46,35 @@ public static void createExitSpan(String executeMethod, String remotePeer, Objec
4346
SpanLayer.asDB(span);
4447

4548
try {
46-
Field namespaceField = operation.getClass().getDeclaredField("namespace");
47-
Field.setAccessible(new Field[]{namespaceField}, true);
48-
MongoNamespace namespace = (MongoNamespace) namespaceField.get(operation);
49-
Tags.DB_INSTANCE.set(span, namespace.getFullName());
49+
MongoNamespace namespace = tryToGetMongoNamespace(operation);
50+
extractTagsFromNamespace(span, namespace);
5051
} catch (Exception e) {
5152
try {
5253
Field wrappedField = operation.getClass().getDeclaredField("wrapped");
5354
Field.setAccessible(new Field[]{wrappedField}, true);
5455
Object wrappedOperation = wrappedField.get(operation);
55-
Field wrappedNamespaceField = wrappedOperation.getClass().getDeclaredField("namespace");
56-
Field.setAccessible(new Field[]{wrappedNamespaceField}, true);
57-
MongoNamespace wrappedNamespace = (MongoNamespace) wrappedNamespaceField.get(wrappedOperation);
58-
Tags.DB_INSTANCE.set(span, wrappedNamespace.getFullName());
56+
MongoNamespace namespace = tryToGetMongoNamespace(wrappedOperation);
57+
extractTagsFromNamespace(span, namespace);
5958
} catch (Exception e2) {
6059

6160
}
6261
}
6362

64-
if (operation instanceof EnhancedInstance) {
65-
Object databaseName = ((EnhancedInstance) operation).getSkyWalkingDynamicField();
66-
if (databaseName != null) {
67-
Tags.DB_INSTANCE.set(span, (String) databaseName);
68-
}
69-
}
70-
7163
if (MongoPluginConfig.Plugin.MongoDB.TRACE_PARAM) {
7264
Tags.DB_BIND_VARIABLES.set(span, MongoOperationHelper.getTraceParam(operation));
7365
}
7466
}
67+
68+
private static void extractTagsFromNamespace(AbstractSpan span, MongoNamespace namespace) {
69+
Tags.DB_INSTANCE.set(span, namespace.getDatabaseName());
70+
if (StringUtil.isNotEmpty(namespace.getCollectionName())) {
71+
span.tag(DB_COLLECTION_TAG, namespace.getCollectionName());
72+
}
73+
}
74+
75+
private static MongoNamespace tryToGetMongoNamespace(Object operation) throws IllegalAccessException, NoSuchFieldException {
76+
Field namespaceField = operation.getClass().getDeclaredField("namespace");
77+
Field.setAccessible(new Field[]{namespaceField}, true);
78+
return (MongoNamespace) namespaceField.get(operation);
79+
}
7580
}

apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/mongodb/v3/interceptor/v30/MongoDBInterceptorTest.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
import static org.mockito.Mockito.mock;
2424
import static org.mockito.Mockito.when;
2525
import java.lang.reflect.Method;
26+
import java.util.Collections;
2627
import java.util.List;
28+
29+
import com.mongodb.operation.AggregateOperation;
2730
import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
2831
import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
2932
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
@@ -70,6 +73,7 @@ public class MongoDBInterceptorTest {
7073
@Mock
7174
private EnhancedInstance enhancedInstance;
7275

76+
private Decoder decoder;
7377
private Object[] arguments;
7478
private Class[] argumentTypes;
7579

@@ -89,7 +93,7 @@ public void setUp() throws Exception {
8993
BsonDocument document = new BsonDocument();
9094
document.append("name", new BsonString("by"));
9195
MongoNamespace mongoNamespace = new MongoNamespace("test.user");
92-
Decoder decoder = mock(Decoder.class);
96+
decoder = mock(Decoder.class);
9397
FindOperation findOperation = new FindOperation(mongoNamespace, decoder);
9498
findOperation.filter(document);
9599

@@ -108,6 +112,24 @@ public void testIntercept() throws Throwable {
108112
assertRedisSpan(spans.get(0));
109113
}
110114

115+
@Test
116+
public void testAggregateOperationIntercept() throws Throwable {
117+
MongoNamespace mongoNamespace = new MongoNamespace("test.user");
118+
BsonDocument matchStage = new BsonDocument("$match", new BsonDocument("name", new BsonString("by")));
119+
List<BsonDocument> pipeline = Collections.singletonList(matchStage);
120+
AggregateOperation<BsonDocument> aggregateOperation = new AggregateOperation(mongoNamespace, pipeline, decoder);
121+
Object[] arguments = {aggregateOperation};
122+
Class[] argumentTypes = {aggregateOperation.getClass()};
123+
124+
interceptor.beforeMethod(enhancedInstance, getExecuteMethod(), arguments, argumentTypes, null);
125+
interceptor.afterMethod(enhancedInstance, getExecuteMethod(), arguments, argumentTypes, null);
126+
127+
MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1));
128+
TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
129+
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
130+
assertMongoAggregateOperationSpan(spans.get(0));
131+
}
132+
111133
@Test
112134
public void testInterceptWithException() throws Throwable {
113135
interceptor.beforeMethod(enhancedInstance, getExecuteMethod(), arguments, argumentTypes, null);
@@ -128,9 +150,22 @@ private void assertRedisSpan(AbstractTracingSpan span) {
128150
assertThat(span.getOperationName(), is("MongoDB/FindOperation"));
129151
assertThat(SpanHelper.getComponentId(span), is(42));
130152
List<TagValuePair> tags = SpanHelper.getTags(span);
131-
assertThat(tags.get(1).getValue(), is("test.user"));
132-
assertThat(tags.get(2).getValue(), is("{\"name\": \"by\"}"));
133153
assertThat(tags.get(0).getValue(), is("MongoDB"));
154+
assertThat(tags.get(1).getValue(), is("test"));
155+
assertThat(tags.get(2).getValue(), is("user"));
156+
assertThat(tags.get(3).getValue(), is("{\"name\": \"by\"}"));
157+
assertThat(span.isExit(), is(true));
158+
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.DB));
159+
}
160+
161+
private void assertMongoAggregateOperationSpan(AbstractTracingSpan span) {
162+
assertThat(span.getOperationName(), is("MongoDB/AggregateOperation"));
163+
assertThat(SpanHelper.getComponentId(span), is(42));
164+
List<TagValuePair> tags = SpanHelper.getTags(span);
165+
assertThat(tags.get(0).getValue(), is("MongoDB"));
166+
assertThat(tags.get(1).getValue(), is("test"));
167+
assertThat(tags.get(2).getValue(), is("user"));
168+
assertThat(tags.get(3).getValue(), is("{\"$match\": {\"name\": \"by\"}},"));
134169
assertThat(span.isExit(), is(true));
135170
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.DB));
136171
}

apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/mongodb/v3/interceptor/v37/MongoDBOperationExecutorInterceptorTest.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,10 @@ private void assertMongoAggregateOperationSpan(AbstractTracingSpan span) {
149149
assertThat(span.getOperationName(), is("MongoDB/AggregateOperation"));
150150
assertThat(SpanHelper.getComponentId(span), is(42));
151151
List<TagValuePair> tags = SpanHelper.getTags(span);
152-
assertThat(tags.get(1).getValue(), is("test.user"));
153-
assertThat(tags.get(2).getValue(), is("{\"$match\": {\"name\": \"by\"}},"));
154152
assertThat(tags.get(0).getValue(), is("MongoDB"));
153+
assertThat(tags.get(1).getValue(), is("test"));
154+
assertThat(tags.get(2).getValue(), is("user"));
155+
assertThat(tags.get(3).getValue(), is("{\"$match\": {\"name\": \"by\"}},"));
155156
assertThat(span.isExit(), is(true));
156157
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.DB));
157158
}
@@ -160,9 +161,10 @@ private void assertMongoFindOperationSpan(AbstractTracingSpan span) {
160161
assertThat(span.getOperationName(), is("MongoDB/FindOperation"));
161162
assertThat(SpanHelper.getComponentId(span), is(42));
162163
List<TagValuePair> tags = SpanHelper.getTags(span);
163-
assertThat(tags.get(1).getValue(), is("test.user"));
164-
assertThat(tags.get(2).getValue(), is("{\"name\": \"by\"}"));
165164
assertThat(tags.get(0).getValue(), is("MongoDB"));
165+
assertThat(tags.get(1).getValue(), is("test"));
166+
assertThat(tags.get(2).getValue(), is("user"));
167+
assertThat(tags.get(3).getValue(), is("{\"name\": \"by\"}"));
166168
assertThat(span.isExit(), is(true));
167169
assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.DB));
168170
}

apm-sniffer/apm-sdk-plugin/mongodb-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mongodb/v4/interceptor/MongoDBOperationExecutorInterceptor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ public class MongoDBOperationExecutorInterceptor implements InstanceMethodsAroun
3737
@Override
3838
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
3939
MethodInterceptResult result) {
40-
String executeMethod = allArguments[0].getClass().getSimpleName();
40+
String executeMethod = argumentsTypes[0].getSimpleName();
4141
// OperationExecutor has included th remotePeer
4242
// See: MongoDBClientDelegateInterceptor.afterMethod
4343
String remotePeer = (String) objInst.getSkyWalkingDynamicField();

apm-sniffer/apm-sdk-plugin/mongodb-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mongodb/v4/interceptor/operation/OperationNamespaceConstructInterceptor.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ public class OperationNamespaceConstructInterceptor implements InstanceConstruct
2727
@Override
2828
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
2929
MongoNamespace mongoNamespace = (MongoNamespace) allArguments[0];
30-
String databaseName = mongoNamespace.getDatabaseName();
31-
objInst.setSkyWalkingDynamicField(databaseName);
30+
objInst.setSkyWalkingDynamicField(mongoNamespace);
3231
}
3332

3433
}

apm-sniffer/apm-sdk-plugin/mongodb-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mongodb/v4/support/MongoSpanHelper.java

Lines changed: 13 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,18 @@
2121
import com.mongodb.MongoNamespace;
2222
import org.apache.skywalking.apm.agent.core.context.ContextCarrier;
2323
import org.apache.skywalking.apm.agent.core.context.ContextManager;
24+
import org.apache.skywalking.apm.agent.core.context.tag.AbstractTag;
2425
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
2526
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
2627
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
2728
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
2829
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
29-
30-
import java.lang.reflect.Field;
30+
import org.apache.skywalking.apm.util.StringUtil;
3131

3232
public class MongoSpanHelper {
3333

34+
private static final AbstractTag<String> DB_COLLECTION_TAG = Tags.ofKey("db.collection");
35+
3436
private MongoSpanHelper() {
3537
}
3638

@@ -42,34 +44,19 @@ private MongoSpanHelper() {
4244
*/
4345
public static void createExitSpan(String executeMethod, String remotePeer, Object operation) {
4446
AbstractSpan span = ContextManager.createExitSpan(
45-
MongoConstants.MONGO_DB_OP_PREFIX + executeMethod, new ContextCarrier(), remotePeer);
47+
MongoConstants.MONGO_DB_OP_PREFIX + executeMethod, new ContextCarrier(), remotePeer);
4648
span.setComponent(ComponentsDefine.MONGO_DRIVER);
4749
Tags.DB_TYPE.set(span, MongoConstants.DB_TYPE);
4850
SpanLayer.asDB(span);
4951

50-
try {
51-
Field namespaceField = operation.getClass().getDeclaredField("namespace");
52-
Field.setAccessible(new Field[]{namespaceField}, true);
53-
MongoNamespace namespace = (MongoNamespace) namespaceField.get(operation);
54-
Tags.DB_INSTANCE.set(span, namespace.getFullName());
55-
} catch (Exception e) {
56-
try {
57-
Field wrappedField = operation.getClass().getDeclaredField("wrapped");
58-
Field.setAccessible(new Field[]{wrappedField}, true);
59-
Object wrappedOperation = wrappedField.get(operation);
60-
Field wrappedNamespaceField = wrappedOperation.getClass().getDeclaredField("namespace");
61-
Field.setAccessible(new Field[]{wrappedNamespaceField}, true);
62-
MongoNamespace wrappedNamespace = (MongoNamespace) wrappedNamespaceField.get(wrappedOperation);
63-
Tags.DB_INSTANCE.set(span, wrappedNamespace.getFullName());
64-
} catch (Exception e2) {
65-
66-
}
67-
}
68-
6952
if (operation instanceof EnhancedInstance) {
70-
Object databaseName = ((EnhancedInstance) operation).getSkyWalkingDynamicField();
71-
if (databaseName != null) {
72-
Tags.DB_INSTANCE.set(span, (String) databaseName);
53+
Object namespaceObj = ((EnhancedInstance) operation).getSkyWalkingDynamicField();
54+
if (namespaceObj != null) {
55+
MongoNamespace namespace = (MongoNamespace) namespaceObj;
56+
Tags.DB_INSTANCE.set(span, namespace.getDatabaseName());
57+
if (StringUtil.isNotEmpty(namespace.getCollectionName())) {
58+
span.tag(DB_COLLECTION_TAG, namespace.getCollectionName());
59+
}
7360
}
7461
}
7562

@@ -78,3 +65,4 @@ public static void createExitSpan(String executeMethod, String remotePeer, Objec
7865
}
7966
}
8067
}
68+

0 commit comments

Comments
 (0)