diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
index 38f9dcad1417..c8dec42ee00f 100644
--- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
+++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
@@ -122,6 +122,8 @@ public class ComponentsDefine {
public static final OfficialComponent RESTEASY = new OfficialComponent(62, "RESTEasy");
+ public static final OfficialComponent SOLRJ = new OfficialComponent(63, "solrj");
+
private static ComponentsDefine INSTANCE = new ComponentsDefine();
private String[] components;
@@ -179,6 +181,7 @@ public ComponentsDefine() {
addComponent(VERTX);
addComponent(SPRING_CLOUD_GATEWAY);
addComponent(RESTEASY);
+ addComponent(SOLRJ);
}
private void addComponent(OfficialComponent component) {
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
index 14ef3a0a4714..77847001aba0 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java
@@ -193,5 +193,18 @@ public static class Toolkit {
*/
public static boolean USE_QUALIFIED_NAME_AS_OPERATION_NAME = false;
}
+
+ public static class SolrJ {
+ /**
+ * If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request, default is false.
+ */
+ public static boolean TRACE_STATEMENT = false;
+
+ /**
+ * If true, trace all the operation parameters in Solr request, default is false.
+ */
+ public static boolean TRACE_OPS_PARAMS = false;
+ }
+
}
}
diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml
index e850ccd8b213..90bb1a886cc2 100644
--- a/apm-sniffer/apm-sdk-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/pom.xml
@@ -73,6 +73,7 @@
dubbo-2.7.x-conflict-patchvertx-pluginsresteasy-plugin
+ solrj-7.x-pluginpom
diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml
new file mode 100644
index 000000000000..31b931ade3bb
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml
@@ -0,0 +1,47 @@
+
+
+
+
+ apm-sdk-plugin
+ org.apache.skywalking
+ 6.2.0-SNAPSHOT
+
+ 4.0.0
+
+ apm-solrj-7.x-plugin
+ jar
+
+ solrj-7.x-plugin
+ http://maven.apache.org
+
+
+ UTF-8
+ 7.7.1
+
+
+
+
+ org.apache.solr
+ solr-solrj
+ ${solr-solrj.version}
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrConnectorInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrConnectorInterceptor.java
new file mode 100644
index 000000000000..69faa3a81d03
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrConnectorInterceptor.java
@@ -0,0 +1,61 @@
+/*
+ * 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.solrj;
+
+import org.apache.http.client.methods.HttpRequestBase;
+import org.apache.skywalking.apm.agent.core.context.CarrierItem;
+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.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 java.lang.reflect.Method;
+
+public class SolrConnectorInterceptor implements InstanceMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) throws Throwable {
+ if (ContextManager.isActive()) {
+ HttpRequestBase request = (HttpRequestBase) allArguments[0];
+
+ ContextCarrier carrier = new ContextCarrier();
+ ContextManager.inject(carrier);
+
+ CarrierItem items = carrier.items();
+ while (items.hasNext()) {
+ items = items.next();
+ request.setHeader(items.getHeadKey(), items.getHeadValue());
+ }
+ }
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) throws Throwable {
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, Throwable t) {
+ if (ContextManager.isActive()) {
+ ContextManager.activeSpan().errorOccurred().log(t);
+ }
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/SolrjInstance.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/SolrjInstance.java
new file mode 100644
index 000000000000..91e4cfb362f0
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/SolrjInstance.java
@@ -0,0 +1,39 @@
+/*
+ * 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.solrj.commons;
+
+public class SolrjInstance {
+ private String collection = "Unknown";
+ private String remotePeer = "Unknown";
+
+ public String getCollection() {
+ return collection;
+ }
+
+ public void setCollection(String collection) {
+ this.collection = collection;
+ }
+
+ public String getRemotePeer() {
+ return remotePeer;
+ }
+
+ public void setRemotePeer(String remotePeer) {
+ this.remotePeer = remotePeer;
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/SolrjTags.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/SolrjTags.java
new file mode 100644
index 000000000000..3040b850b529
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/SolrjTags.java
@@ -0,0 +1,39 @@
+/*
+ * 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.solrj.commons;
+
+import org.apache.skywalking.apm.agent.core.context.tag.StringTag;
+
+public class SolrjTags {
+ public static StringTag TAG_QT = new StringTag("qt");
+ public static StringTag TAG_COLLECTION = new StringTag("collection");
+
+ public static StringTag TAG_Q_TIME = new StringTag("QTime");
+ public static StringTag TAG_STATUS = new StringTag("status");
+
+ public static StringTag TAG_START = new StringTag("start");
+ public static StringTag TAG_SORT_BY = new StringTag("sort");
+ public static StringTag TAG_NUM_FOUND = new StringTag("numFound");
+
+ public static StringTag TAG_SOFT_COMMIT = new StringTag("softCommit");
+ public static StringTag TAG_COMMIT_WITHIN = new StringTag("commitWithin");
+ public static StringTag TAG_MAX_OPTIMIZE_SEGMENTS = new StringTag("maxOptimizeSegs");
+
+ public static StringTag TAG_DOCS_SIZE = new StringTag("docsSize");
+ public static StringTag TAG_DELETE_VALUE = new StringTag("delete.by");
+}
diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/define/SolrClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/define/SolrClientInstrumentation.java
new file mode 100644
index 000000000000..f552f158527b
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/define/SolrClientInstrumentation.java
@@ -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.solrj.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.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;
+
+public class SolrClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ @Override
+ protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[]{
+ new ConstructorInterceptPoint() {
+
+ @Override
+ public String getConstructorInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solrj.SolrClientInterceptor";
+ }
+
+ @Override
+ public ElementMatcher getConstructorMatcher() {
+ return ElementMatchers.any();
+ }
+ }
+ };
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return ElementMatchers.named("request").and(ElementMatchers.takesArguments(3));
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solrj.SolrClientInterceptor";
+ }
+ },
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return ElementMatchers.named("executeMethod");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solrj.SolrConnectorInterceptor";
+ }
+ }
+ };
+ }
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName("org.apache.solr.client.solrj.impl.HttpSolrClient");
+ }
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 000000000000..f9181f2021f9
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,17 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+solrj-7.x=org.apache.skywalking.apm.plugin.solrj.define.SolrClientInstrumentation
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptorTest.java
new file mode 100644
index 000000000000..c7311a8c6b88
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptorTest.java
@@ -0,0 +1,428 @@
+/*
+ * 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.solrj;
+
+import com.google.common.collect.Lists;
+import org.apache.skywalking.apm.agent.core.conf.Config;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
+import org.apache.skywalking.apm.agent.test.tools.*;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.solrj.commons.SolrjInstance;
+import org.apache.solr.client.solrj.ResponseParser;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
+import org.apache.solr.client.solrj.request.QueryRequest;
+import org.apache.solr.client.solrj.request.UpdateRequest;
+import org.apache.solr.common.*;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.NamedList;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+
+import java.lang.reflect.Method;
+import java.util.List;
+
+import static org.mockito.Mockito.when;
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(TracingSegmentRunner.class)
+public class SolrClientInterceptorTest {
+ SolrClientInterceptor interceptor = new SolrClientInterceptor();
+
+ @SegmentStoragePoint
+ private SegmentStorage segmentStorage;
+
+ @Rule
+ public AgentServiceRule serviceRule = new AgentServiceRule();
+
+ @Mock
+ private HttpSolrClient client;
+
+ @Mock
+ private Method method;
+
+ @Mock
+ private EnhancedInstance enhancedInstance;
+
+ private Object[] arguments = null;
+ private Class[] argumentType = new Class[] {
+ SolrRequest.class,
+ ResponseParser.class,
+ String.class
+ };
+ private String collection = null;
+ private HttpSolrClient.Builder builder;
+
+ @Mock
+ private SolrjInstance instance;
+ private NamedList