Support mongo driver 4.x version. (#5512)
This commit is contained in:
parent
c3edd3dad0
commit
1ff25ac4f4
|
|
@ -47,6 +47,7 @@ jobs:
|
|||
- { name: 'kotlin-coroutine-scenario', title: 'Kotlin Coroutine 1.0.1-1.3.3 (4)' }
|
||||
- { name: 'lettuce-scenario', title: 'Lettuce 5.x (17)' }
|
||||
- { name: 'mongodb-3.x-scenario', title: 'Mongodb 3.4.0-3.11.1 (22)' }
|
||||
- { name: 'mongodb-4.x-scenario', title: 'Mongodb 4.0.0-4.1.0 (7)' }
|
||||
- { name: 'netty-socketio-scenario', title: 'Netty-SocketIO 1.x (4)' }
|
||||
- { name: 'postgresql-above9.4.1207-scenario', title: 'PostgreSQL 9.4.1207+ (62)' }
|
||||
steps:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
~ contributor license agreements. See the NOTICE file distributed with
|
||||
~ this work for additional information regarding copyright ownership.
|
||||
~ The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
~ (the "License"); you may not use this file except in compliance with
|
||||
~ the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
~
|
||||
-->
|
||||
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<artifactId>apm-sdk-plugin</artifactId>
|
||||
<groupId>org.apache.skywalking</groupId>
|
||||
<version>8.2.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>apm-mongodb-4.x-plugin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>mongodb-plugin</name>
|
||||
<url>http://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<mongodb-driver.version>4.1.0</mongodb-driver.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
<version>${mongodb-driver.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
@ -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.v4.define;
|
||||
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
|
||||
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
|
||||
import org.apache.skywalking.apm.plugin.mongodb.v4.interceptor.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. Inject the remotePeer into enhanced OperationExecutor.
|
||||
* <p>
|
||||
* support: 4.0.0 or higher
|
||||
*
|
||||
* @see MongoDBOperationExecutorInstrumentation
|
||||
* @see MongoDBClientDelegateInterceptor
|
||||
*/
|
||||
public class MongoDBClientDelegateInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String WITNESS_CLASS = "com.mongodb.internal.connection.Cluster";
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.mongodb.client.internal.MongoClientDelegate";
|
||||
|
||||
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.mongodb.v4.interceptor.MongoDBClientDelegateInterceptor";
|
||||
|
||||
@Override
|
||||
protected String[] witnessClasses() {
|
||||
return new String[] {WITNESS_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.internal.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,87 @@
|
|||
/*
|
||||
* 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.v4.define;
|
||||
|
||||
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 with org.apache.skywalking.apm.plugin.mongodb.v3.define.v38.MongoDBOperationExecutorInstrumentation
|
||||
* <p>
|
||||
* support: 4.0.x or higher
|
||||
*/
|
||||
public class MongoDBOperationExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String WITNESS_CLASS = "com.mongodb.internal.operation.FindOperation";
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.mongodb.client.internal.MongoClientDelegate$DelegateOperationExecutor";
|
||||
|
||||
private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.mongodb.v4.interceptor.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
|
||||
.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,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.v4.interceptor;
|
||||
|
||||
import com.mongodb.internal.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.v4.support.MongoRemotePeerHelper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class MongoDBClientDelegateInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor {
|
||||
|
||||
private static final ILog LOGGER = LogManager.getLogger(MongoDBClientDelegateInterceptor.class);
|
||||
|
||||
@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 has be enhanced 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,64 @@
|
|||
/*
|
||||
* 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.v4.interceptor;
|
||||
|
||||
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.v4.support.MongoSpanHelper;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@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 included th 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.log(t);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* 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.v4.support;
|
||||
|
||||
public class MongoConstants {
|
||||
|
||||
private MongoConstants() {
|
||||
}
|
||||
|
||||
public static final String DB_TYPE = "MongoDB";
|
||||
|
||||
public static final String MONGO_DB_OP_PREFIX = "MongoDB/";
|
||||
|
||||
public static final String EMPTY = "";
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* 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.v4.support;
|
||||
|
||||
import com.mongodb.internal.bulk.DeleteRequest;
|
||||
import com.mongodb.internal.bulk.InsertRequest;
|
||||
import com.mongodb.internal.bulk.UpdateRequest;
|
||||
import com.mongodb.internal.bulk.WriteRequest;
|
||||
import com.mongodb.internal.operation.CountOperation;
|
||||
import com.mongodb.internal.operation.CreateCollectionOperation;
|
||||
import com.mongodb.internal.operation.CreateIndexesOperation;
|
||||
import com.mongodb.internal.operation.CreateViewOperation;
|
||||
import com.mongodb.internal.operation.DeleteOperation;
|
||||
import com.mongodb.internal.operation.DistinctOperation;
|
||||
import com.mongodb.internal.operation.FindAndDeleteOperation;
|
||||
import com.mongodb.internal.operation.FindAndReplaceOperation;
|
||||
import com.mongodb.internal.operation.FindAndUpdateOperation;
|
||||
import com.mongodb.internal.operation.FindOperation;
|
||||
import com.mongodb.internal.operation.InsertOperation;
|
||||
import com.mongodb.internal.operation.ListCollectionsOperation;
|
||||
import com.mongodb.internal.operation.MapReduceToCollectionOperation;
|
||||
import com.mongodb.internal.operation.MapReduceWithInlineResultsOperation;
|
||||
import com.mongodb.internal.operation.MixedBulkWriteOperation;
|
||||
import com.mongodb.internal.operation.UpdateOperation;
|
||||
import org.bson.BsonDocument;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@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.
|
||||
* @param obj operation
|
||||
* @return result
|
||||
*/
|
||||
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 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(",");
|
||||
}
|
||||
final int filterLengthLimit = MongoPluginConfig.Plugin.MongoDB.FILTER_LENGTH_LIMIT;
|
||||
if (filterLengthLimit > 0 && params.length() > filterLengthLimit) {
|
||||
return params.substring(0, filterLengthLimit) + "...";
|
||||
}
|
||||
}
|
||||
return params.toString();
|
||||
}
|
||||
|
||||
private static String limitFilter(String filter) {
|
||||
final StringBuilder params = new StringBuilder();
|
||||
final int filterLengthLimit = MongoPluginConfig.Plugin.MongoDB.FILTER_LENGTH_LIMIT;
|
||||
if (filterLengthLimit > 0 && filter.length() > filterLengthLimit) {
|
||||
return params.append(filter, 0, filterLengthLimit).append("...").toString();
|
||||
} else {
|
||||
return filter;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.v4.support;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.boot.PluginConfig;
|
||||
|
||||
public class MongoPluginConfig {
|
||||
public static class Plugin {
|
||||
@PluginConfig(root = MongoPluginConfig.class)
|
||||
public static class MongoDB {
|
||||
/**
|
||||
* If true, trace all the parameters in MongoDB access, default is false. Only trace the operation, not
|
||||
* include parameters.
|
||||
*/
|
||||
public static boolean TRACE_PARAM = false;
|
||||
|
||||
/**
|
||||
* For the sake of performance, SkyWalking won't save the entire parameters string into the tag, but only
|
||||
* the first {@code FILTER_LENGTH_LIMIT} characters.
|
||||
* <p>
|
||||
* Set a negative number to save the complete parameter string to the tag.
|
||||
*/
|
||||
public static int FILTER_LENGTH_LIMIT = 256;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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.v4.support;
|
||||
|
||||
import com.mongodb.ServerAddress;
|
||||
import com.mongodb.connection.ServerDescription;
|
||||
import com.mongodb.internal.connection.Cluster;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MongoRemotePeerHelper {
|
||||
|
||||
private MongoRemotePeerHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param cluster cluster
|
||||
* @return result
|
||||
*/
|
||||
public static String getRemotePeer(Cluster cluster) {
|
||||
StringBuilder peersBuilder = new StringBuilder();
|
||||
for (ServerDescription description : cluster.getDescription().getServerDescriptions()) {
|
||||
ServerAddress address = description.getAddress();
|
||||
peersBuilder.append(address.getHost()).append(":").append(address.getPort()).append(";");
|
||||
}
|
||||
return peersBuilder.substring(0, peersBuilder.length() - 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.mongodb.v4.support;
|
||||
|
||||
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;
|
||||
|
||||
public class MongoSpanHelper {
|
||||
|
||||
private MongoSpanHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* createExitSpan
|
||||
* @param executeMethod executeMethod
|
||||
* @param remotePeer remotePeer
|
||||
* @param operation operation
|
||||
*/
|
||||
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 (MongoPluginConfig.Plugin.MongoDB.TRACE_PARAM) {
|
||||
Tags.DB_BIND_VARIABLES.set(span, MongoOperationHelper.getTraceParam(operation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
# 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.
|
||||
|
||||
# v4.0.0~
|
||||
mongodb-4.x=org.apache.skywalking.apm.plugin.mongodb.v4.define.MongoDBClientDelegateInstrumentation
|
||||
mongodb-4.x=org.apache.skywalking.apm.plugin.mongodb.v4.define.MongoDBOperationExecutorInstrumentation
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.plugin.mongodb.v4;
|
||||
|
||||
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import org.apache.skywalking.apm.plugin.mongodb.v4.interceptor.MongoDBClientDelegateInterceptor;
|
||||
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;
|
||||
|
||||
@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,141 @@
|
|||
/*
|
||||
* 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.v4;
|
||||
|
||||
import com.mongodb.MongoNamespace;
|
||||
import com.mongodb.ReadConcern;
|
||||
import com.mongodb.client.internal.OperationExecutor;
|
||||
import com.mongodb.internal.operation.FindOperation;
|
||||
import com.mongodb.internal.operation.WriteOperation;
|
||||
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.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.plugin.mongodb.v4.interceptor.MongoDBOperationExecutorInterceptor;
|
||||
import org.apache.skywalking.apm.plugin.mongodb.v4.support.MongoPluginConfig;
|
||||
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;
|
||||
|
||||
@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();
|
||||
|
||||
MongoPluginConfig.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);
|
||||
assertMongoSpan(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);
|
||||
assertMongoSpan(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 assertMongoSpan(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("{\"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);
|
||||
}
|
||||
}
|
||||
|
|
@ -36,6 +36,7 @@
|
|||
<module>tomcat-7.x-8.x-plugin</module>
|
||||
<module>motan-plugin</module>
|
||||
<module>mongodb-3.x-plugin</module>
|
||||
<module>mongodb-4.x-plugin</module>
|
||||
<module>feign-default-http-9.x-plugin</module>
|
||||
<module>okhttp-3.x-plugin</module>
|
||||
<module>spring-plugins</module>
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
- memcache-2.x
|
||||
- mongodb-2.x
|
||||
- mongodb-3.x
|
||||
- mongodb-4.x
|
||||
- motan-0.x
|
||||
- mysql-5.x
|
||||
- mysql-6.x
|
||||
|
|
|
|||
|
|
@ -58,7 +58,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
|
||||
* [MongoDB Java Driver](https://github.com/mongodb/mongo-java-driver) 2.13-2.14, 3.4.0-3.11.1
|
||||
* [MongoDB Java Driver](https://github.com/mongodb/mongo-java-driver) 2.13-2.14, 3.4.0-3.11.1, 4.0.0-4.1.0
|
||||
* Memcached Client
|
||||
* [Spymemcached](https://github.com/couchbase/spymemcached) 2.x
|
||||
* [Xmemcached](https://github.com/killme2008/xmemcached) 2.x
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
home="$(cd "$(dirname $0)"; pwd)"
|
||||
|
||||
java -jar ${agent_opts} -Dskywalking.plugin.mongodb.trace_param=true ${home}/../libs/mongodb-4.x-scenario.jar &
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
segmentItems:
|
||||
- serviceName: mongodb-4.x-scenario
|
||||
segmentSize: ge 2
|
||||
segments:
|
||||
- segmentId: not null
|
||||
spans:
|
||||
- operationName: MongoDB/CreateCollectionOperation
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 1
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 42
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: mongodb-server:27017
|
||||
tags:
|
||||
- {key: db.type, value: MongoDB}
|
||||
- {key: db.bind_vars, value: 'testCollection'}
|
||||
skipAnalysis: 'false'
|
||||
- operationName: MongoDB/MixedBulkWriteOperation
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 2
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 42
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: mongodb-server:27017
|
||||
tags:
|
||||
- {key: db.type, value: MongoDB}
|
||||
- {key: db.bind_vars, value: not null}
|
||||
skipAnalysis: 'false'
|
||||
- operationName: MongoDB/FindOperation
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 3
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 42
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: mongodb-server:27017
|
||||
tags:
|
||||
- {key: db.type, value: MongoDB}
|
||||
- {key: db.bind_vars, value: '{"name": "org"}'}
|
||||
skipAnalysis: 'false'
|
||||
- operationName: MongoDB/MixedBulkWriteOperation
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 4
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 42
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: mongodb-server:27017
|
||||
tags:
|
||||
- {key: db.type, value: MongoDB}
|
||||
- {key: db.bind_vars, value: '{"name": "org"},'}
|
||||
skipAnalysis: 'false'
|
||||
- operationName: MongoDB/FindOperation
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 5
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 42
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: mongodb-server:27017
|
||||
tags:
|
||||
- {key: db.type, value: MongoDB}
|
||||
- {key: db.bind_vars, value: '{"name": "testA"}'}
|
||||
skipAnalysis: 'false'
|
||||
- operationName: MongoDB/MixedBulkWriteOperation
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 6
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 42
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: mongodb-server:27017
|
||||
tags:
|
||||
- {key: db.type, value: MongoDB}
|
||||
- {key: db.bind_vars, value: '{"id": "1"},'}
|
||||
skipAnalysis: 'false'
|
||||
- operationName: MongoDB/DropDatabaseOperation
|
||||
operationId: 0
|
||||
parentSpanId: 0
|
||||
spanId: 7
|
||||
spanLayer: Database
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 42
|
||||
isError: false
|
||||
spanType: Exit
|
||||
peer: mongodb-server:27017
|
||||
tags:
|
||||
- {key: db.type, value: MongoDB}
|
||||
- {key: db.bind_vars, value: null}
|
||||
skipAnalysis: 'false'
|
||||
- operationName: /mongodb-4.x-scenario/case/mongodb-4.x-scenario
|
||||
operationId: 0
|
||||
parentSpanId: -1
|
||||
spanId: 0
|
||||
spanLayer: Http
|
||||
startTime: nq 0
|
||||
endTime: nq 0
|
||||
componentId: 1
|
||||
isError: false
|
||||
spanType: Entry
|
||||
peer: ''
|
||||
tags:
|
||||
- {key: url, value: 'http://localhost:8080/mongodb-4.x-scenario/case/mongodb-4.x-scenario'}
|
||||
- {key: http.method, value: GET}
|
||||
skipAnalysis: 'false'
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
type: jvm
|
||||
entryService: http://localhost:8080/mongodb-4.x-scenario/case/mongodb-4.x-scenario
|
||||
healthCheck: http://localhost:8080/mongodb-4.x-scenario/case/healthCheck
|
||||
startScript: ./bin/startup.sh
|
||||
dependencies:
|
||||
mongodb-server:
|
||||
image: mongo:4.2
|
||||
hostname: mongodb-server
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<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">
|
||||
|
||||
<groupId>org.apache.skywalking.apm.testcase</groupId>
|
||||
<artifactId>mongodb-4.x-scenario</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
<test.framework.version>4.0.0</test.framework.version>
|
||||
<spring-boot-version>2.1.6.RELEASE</spring-boot-version>
|
||||
<lombok.version>1.18.10</lombok.version>
|
||||
</properties>
|
||||
|
||||
<name>skywalking-mongodb-4.x-scenario</name>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
<version>${spring-boot-version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>bson</artifactId>
|
||||
<version>${test.framework.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-core</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>mongodb-driver-sync</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.mongodb</groupId>
|
||||
<artifactId>bson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-log4j2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>${lombok.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>mongodb-4.x-scenario</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>${compiler.version}</source>
|
||||
<target>${compiler.version}</target>
|
||||
<encoding>${project.build.sourceEncoding}</encoding>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>assemble</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<descriptors>
|
||||
<descriptor>src/main/assembly/assembly.xml</descriptor>
|
||||
</descriptors>
|
||||
<outputDirectory>./target/</outputDirectory>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<formats>
|
||||
<format>zip</format>
|
||||
</formats>
|
||||
|
||||
<fileSets>
|
||||
<fileSet>
|
||||
<directory>./bin</directory>
|
||||
<fileMode>0775</fileMode>
|
||||
</fileSet>
|
||||
</fileSets>
|
||||
|
||||
<files>
|
||||
<file>
|
||||
<source>${project.build.directory}/mongodb-4.x-scenario.jar</source>
|
||||
<outputDirectory>./libs</outputDirectory>
|
||||
<fileMode>0775</fileMode>
|
||||
</file>
|
||||
</files>
|
||||
</assembly>
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.testcase.mongodb;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class Application {
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
SpringApplication.run(Application.class, args);
|
||||
} catch (Exception e) {
|
||||
// Never do this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.apache.skywalking.apm.testcase.mongodb.controller;
|
||||
|
||||
import com.mongodb.client.*;
|
||||
import org.bson.BsonDocument;
|
||||
import org.bson.Document;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static com.mongodb.client.model.Filters.eq;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/case")
|
||||
public class CaseController {
|
||||
|
||||
@Value(value = "${mongodb.uri}")
|
||||
private String connectionString;
|
||||
|
||||
@GetMapping("/healthCheck")
|
||||
public String health() {
|
||||
// check connect to mongodb server
|
||||
try (MongoClient mongoClient = MongoClients.create(connectionString)) {
|
||||
return "success";
|
||||
}
|
||||
}
|
||||
|
||||
@RequestMapping("/mongodb-4.x-scenario")
|
||||
public String mongoDBCase() {
|
||||
try (MongoClient mongoClient = MongoClients.create(connectionString)) {
|
||||
MongoDatabase db = mongoClient.getDatabase("test-database");
|
||||
// CreateCollectionOperation
|
||||
db.createCollection("testCollection");
|
||||
|
||||
MongoCollection<Document> collection = db.getCollection("testCollection");
|
||||
Document document = Document.parse("{id: 1, name: \"test\"}");
|
||||
// MixedBulkWriteOperation
|
||||
collection.insertOne(document);
|
||||
|
||||
// FindOperation
|
||||
FindIterable<Document> findIterable = collection.find(eq("name", "org"));
|
||||
findIterable.first();
|
||||
|
||||
// MixedBulkWriteOperation
|
||||
collection.updateOne(eq("name", "org"), BsonDocument.parse("{ $set : { \"name\": \"testA\"} }"));
|
||||
|
||||
// FindOperation
|
||||
findIterable = collection.find(eq("name", "testA"));
|
||||
findIterable.first();
|
||||
|
||||
// MixedBulkWriteOperation
|
||||
collection.deleteOne(eq("id", "1"));
|
||||
|
||||
// DropDatabaseOperation
|
||||
mongoClient.getDatabase("test-database").drop();
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#
|
||||
# Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
# contributor license agreements. See the NOTICE file distributed with
|
||||
# this work for additional information regarding copyright ownership.
|
||||
# The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
# (the "License"); you may not use this file except in compliance with
|
||||
# the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
#
|
||||
server:
|
||||
port: 8080
|
||||
servlet:
|
||||
context-path: /mongodb-4.x-scenario
|
||||
logging:
|
||||
config: classpath:log4j2.xml
|
||||
mongodb:
|
||||
uri: mongodb://mongodb-server/test
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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.
|
||||
~
|
||||
-->
|
||||
<Configuration status="WARN">
|
||||
<Appenders>
|
||||
<Console name="Console" target="SYSTEM_ERR">
|
||||
<PatternLayout charset="UTF-8" pattern="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="WARN">
|
||||
<AppenderRef ref="Console"/>
|
||||
</Root>
|
||||
</Loggers>
|
||||
</Configuration>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
4.0.0
|
||||
4.0.1
|
||||
4.0.2
|
||||
4.0.3
|
||||
4.0.4
|
||||
4.0.5
|
||||
4.1.0
|
||||
Loading…
Reference in New Issue