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 e02e8b22e2a4..88dda710c5f2 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
@@ -124,6 +124,8 @@ public class ComponentsDefine {
public static final OfficialComponent SOLRJ = new OfficialComponent(63, "solrj");
+ public static final OfficialComponent SOLR = new OfficialComponent(64, "solr");
+
public static final OfficialComponent SPRING_ASYNC = new OfficialComponent(65, "SpringAsync");
private static ComponentsDefine INSTANCE = new ComponentsDefine();
@@ -184,6 +186,7 @@ public ComponentsDefine() {
addComponent(SPRING_CLOUD_GATEWAY);
addComponent(RESTEASY);
addComponent(SOLRJ);
+ addComponent(SOLR);
}
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 9efab982bf5b..ba0a2729ec93 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
@@ -226,5 +226,18 @@ public static class SolrJ {
public static boolean TRACE_OPS_PARAMS = false;
}
+ public static class Solr {
+
+ /**
+ * If true, the Trace_ID will be put into MDC. Default is false.
+ */
+ public static boolean PRINT_TRACE_ID_ON_LOG = false;
+
+ /**
+ * If true, not trace admin request, include /admin/ping, /admin/metrics etc. Default is true.
+ */
+ public static boolean SKIP_ADMIN_REQUEST = true;
+ }
+
}
}
diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml
index 87e9266f54c4..e2d5e7e42a07 100644
--- a/apm-sniffer/apm-sdk-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/pom.xml
@@ -74,6 +74,7 @@
vertx-plugins
resteasy-plugin
solrj-7.x-plugin
+ solr-7.x-plugin
pom
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/pom.xml
new file mode 100644
index 000000000000..a4740ff683e3
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/pom.xml
@@ -0,0 +1,56 @@
+
+
+
+
+ apm-sdk-plugin
+ org.apache.skywalking
+ 6.2.0-SNAPSHOT
+
+ 4.0.0
+
+ apm-solr-7.x-plugin
+ jar
+
+ solr-7.x-plugin
+ http://maven.apache.org
+
+
+ UTF-8
+ 7.5.0
+ 7.5.0
+
+
+
+
+ org.apache.solr
+ solr-core
+ ${solr-core.version}
+ provided
+
+
+
+ org.apache.solr
+ solr-solrj
+ ${solr-solrj.version}
+ provided
+
+
+
+
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/RequestHandlerBaseInstrumentation.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/RequestHandlerBaseInstrumentation.java
new file mode 100644
index 000000000000..34ff960ab1fb
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/RequestHandlerBaseInstrumentation.java
@@ -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.solr;
+
+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 RequestHandlerBaseInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ @Override
+ protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[]{
+ };
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return ElementMatchers.named("handleRequest");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solr.RequestHandlerBaseInterceptor";
+ }
+ }
+ };
+ }
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName("org.apache.solr.handler.RequestHandlerBase");
+ }
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/RequestHandlerBaseInterceptor.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/RequestHandlerBaseInterceptor.java
new file mode 100644
index 000000000000..7522532c4cbf
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/RequestHandlerBaseInterceptor.java
@@ -0,0 +1,112 @@
+/*
+ * 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.solr;
+
+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.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+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.network.trace.component.ComponentsDefine;
+import org.apache.solr.common.params.ShardParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.update.processor.DistributingUpdateProcessorFactory;
+import org.slf4j.MDC;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+
+import static org.apache.skywalking.apm.agent.core.conf.Config.Plugin.Solr.PRINT_TRACE_ID_ON_LOG;
+import static org.apache.skywalking.apm.agent.core.conf.Config.Plugin.Solr.SKIP_ADMIN_REQUEST;
+import static org.apache.skywalking.apm.plugin.solr.commons.Constants.*;
+
+public class RequestHandlerBaseInterceptor implements InstanceMethodsAroundInterceptor {
+ private static final ILog LOG = LogManager.getLogger(RequestHandlerBaseInterceptor.class);
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) throws Throwable {
+ final SolrQueryRequest request = (SolrQueryRequest) allArguments[0];
+ if (SKIP_ADMIN_REQUEST && request.getPath().startsWith(SKIP_ADMIN_PREF)) {
+ return;
+ }
+
+ HttpServletRequest req = request.getHttpSolrCall().getReq();
+ ContextCarrier carrier = new ContextCarrier();
+ CarrierItem items = carrier.items();
+ while (items.hasNext()) {
+ items = items.next();
+ items.setHeadValue(req.getHeader(items.getHeadKey()));
+ }
+
+ SolrParams params = request.getParams();
+ String operationPref = OPER_SOLR_PREF;
+
+ if ((params.getBool(ShardParams.IS_SHARD, false) && params.getInt(ShardParams.SHARDS_PURPOSE, 0) != 0)
+ || params.get(DistributingUpdateProcessorFactory.DISTRIB_UPDATE_PARAM) != null) {
+ operationPref = OPER_SHARD_PREF;
+ }
+
+ createSpan(operationPref + req.getServletPath(), carrier);
+ if (PRINT_TRACE_ID_ON_LOG) {
+ MDC.put(MDC_KEY_TRACE_ID, TRACE_ID_PREF + ContextManager.getGlobalTraceId());
+ }
+ }
+
+ private final AbstractSpan createSpan(String operation, ContextCarrier carrier) {
+ AbstractSpan span = ContextManager.createEntrySpan(operation, carrier);
+ span.setComponent(ComponentsDefine.SOLR)
+ .setLayer(SpanLayer.HTTP);
+ return span;
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) throws Throwable {
+ final SolrQueryRequest request = (SolrQueryRequest) allArguments[0];
+ if (SKIP_ADMIN_REQUEST && request.getPath().startsWith(SKIP_ADMIN_PREF)) {
+ return ret;
+ }
+
+ if (ContextManager.isActive()) {
+ SolrQueryResponse response = (SolrQueryResponse) allArguments[1];
+ Exception exp = response.getException();
+ if (exp != null) {
+ ContextManager.activeSpan().errorOccurred().log(exp);
+ }
+ ContextManager.stopSpan();
+ }
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+ Class>[] argumentsTypes, Throwable t) {
+ if (ContextManager.isActive()) {
+ ContextManager.activeSpan().errorOccurred().log(t);
+ }
+ }
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/commons/Constants.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/commons/Constants.java
new file mode 100644
index 000000000000..ab33a8335fa8
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/commons/Constants.java
@@ -0,0 +1,41 @@
+/*
+ * 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.solr.commons;
+
+public interface Constants {
+ String SW_ENHANCE_FLAG = "_sw_enhance_flag_";
+
+ String OPER_SHARD_PREF = "Solr/shard";
+
+ String OPER_SHARD_PREF_SLASH = "Solr/shard/";
+
+ String OPER_STAGE_PREF = "Solr/stage/";
+
+ String OPER_SOLR_PREF = "Solr";
+
+ String SKIP_ADMIN_PREF = "/admin/";
+
+ String TRACE_ID_PREF = "t:";
+
+ String MDC_KEY_CORE = "core";
+
+ String MDC_KEY_NODE_NAME = "node_name";
+
+ String MDC_KEY_TRACE_ID = "traceId";
+}
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/commons/NamesMap.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/commons/NamesMap.java
new file mode 100644
index 000000000000..d262524b8e95
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/commons/NamesMap.java
@@ -0,0 +1,68 @@
+/*
+ * 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.solr.commons;
+
+import org.apache.solr.handler.component.ShardRequest;
+
+public class NamesMap {
+ private static final String[] PURPOSENAMES = {
+ "/PRIVATE",
+ "/GET_TERM_DFS",
+ "/GET_TOP_IDS",
+ "/REFINE_TOP_IDS",
+ "/GET_FACETS",
+ "/REFINE_FACETS",
+ "/GET_FIELDS",
+ "/GET_HIGHLIGHTS",
+ "/GET_DEBUG",
+ "/GET_STATS",
+ "/GET_TERMS",
+ "/GET_TOP_GROUPS",
+ "/GET_MLT_RESULTS",
+ "/REFINE_PIVOT_FACETS",
+ "/SET_TERM_STATS",
+ "/GET_TERM_STATS"
+ };
+
+ public static String getStagName(int stage) {
+ switch (stage) {
+ case 0:
+ return "START";
+ case 1000:
+ return "PARSE_QUERY";
+ case 1500:
+ return "TOP_GROUPS";
+ case 2000:
+ return "EXECUTE_QUERY";
+ case 3000:
+ return "GET_FIELDS";
+ case Integer.MAX_VALUE:
+ return "DONE";
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ public static String gePurposeName(int purpose) {
+ if (purpose < ShardRequest.PURPOSE_PRIVATE || purpose > ShardRequest.PURPOSE_GET_TERM_STATS)
+ return "/PENDING";
+ return PURPOSENAMES[Integer.numberOfTrailingZeros(purpose)];
+ }
+
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/HttpShardHandlerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/HttpShardHandlerInstrumentation.java
new file mode 100644
index 000000000000..b597aa244906
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/HttpShardHandlerInstrumentation.java
@@ -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.solr.search;
+
+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 HttpShardHandlerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ @Override
+ protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[]{
+ };
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public boolean isOverrideArgs() {
+ return true;
+ }
+
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return ElementMatchers.named("submit");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solr.search.HttpShardHandlerInterceptor";
+ }
+ }
+ };
+ }
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName("org.apache.solr.handler.component.HttpShardHandler");
+ }
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/HttpShardHandlerInterceptor.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/HttpShardHandlerInterceptor.java
new file mode 100644
index 000000000000..74a434e91e44
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/HttpShardHandlerInterceptor.java
@@ -0,0 +1,68 @@
+/*
+ * 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.
+ *
+ */
+ /*
+ * 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.solr.search;
+
+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 org.apache.skywalking.apm.plugin.solr.wrappers.ModSolrParamsWrapper;
+import org.apache.solr.common.params.SolrParams;
+
+import java.lang.reflect.Method;
+
+public class HttpShardHandlerInterceptor implements InstanceMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) throws Throwable {
+ if (ContextManager.isActive()) {
+ ModSolrParamsWrapper paramsWrapper = new ModSolrParamsWrapper((SolrParams) allArguments[2]);
+ paramsWrapper.setSkyWalkingDynamicField(ContextManager.capture());
+ allArguments[2] = paramsWrapper;
+ }
+ }
+
+ @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) {
+ }
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/QueryStageTracerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/QueryStageTracerInstrumentation.java
new file mode 100644
index 000000000000..81a233b45aff
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/QueryStageTracerInstrumentation.java
@@ -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.solr.search;
+
+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 QueryStageTracerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ @Override
+ protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[]{
+ };
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return ElementMatchers.named("distributedProcess").or(ElementMatchers.named("finishStage"));
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solr.search.QueryStageTracerInterceptor";
+ }
+ }
+ };
+ }
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName("org.apache.solr.handler.component.QueryComponent");
+ }
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/QueryStageTracerInterceptor.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/QueryStageTracerInterceptor.java
new file mode 100644
index 000000000000..04451443966d
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/search/QueryStageTracerInterceptor.java
@@ -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.solr.search;
+
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+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.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.solr.commons.NamesMap;
+import org.apache.solr.handler.component.ResponseBuilder;
+
+import java.lang.reflect.Method;
+
+import static org.apache.skywalking.apm.plugin.solr.commons.Constants.OPER_STAGE_PREF;
+
+public class QueryStageTracerInterceptor implements InstanceMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) throws Throwable {
+ if (method.getName().equals("distributedProcess")) {
+ ContextSnapshot snapshot = null;
+ if (ContextManager.isActive()) {
+ snapshot = ContextManager.capture();
+ }
+
+ ResponseBuilder rb = (ResponseBuilder) allArguments[0];
+ AbstractSpan span = ContextManager.createLocalSpan(OPER_STAGE_PREF + NamesMap.getStagName(rb.stage));
+ span.setComponent(ComponentsDefine.SOLR);
+
+ if (snapshot != null) {
+ ContextManager.continued(snapshot);
+ }
+ }
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) throws Throwable {
+ if (method.getName().equals("finishStage")) {
+ if (ContextManager.isActive())
+ ContextManager.stopSpan();
+ }
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, Throwable t) {
+ }
+
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/shard/ShardConnectorInterceptor.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/shard/ShardConnectorInterceptor.java
new file mode 100644
index 000000000000..3a4b04774a5c
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/shard/ShardConnectorInterceptor.java
@@ -0,0 +1,58 @@
+/*
+ * 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.solr.shard;
+
+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 ShardConnectorInterceptor implements InstanceMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) throws Throwable {
+ if (!ContextManager.isActive())
+ return;
+
+ 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) {
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/shard/ShardRequestInterceptor.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/shard/ShardRequestInterceptor.java
new file mode 100644
index 000000000000..0ce26b45f820
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/shard/ShardRequestInterceptor.java
@@ -0,0 +1,110 @@
+/*
+ * 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.solr.shard;
+
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.solr.commons.NamesMap;
+import org.apache.skywalking.apm.plugin.solr.wrappers.ModSolrParamsWrapper;
+import org.apache.solr.client.solrj.SolrRequest;
+import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.ShardParams;
+import org.apache.solr.common.params.SolrParams;
+
+import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import static org.apache.skywalking.apm.plugin.solr.commons.Constants.*;
+
+public class ShardRequestInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor {
+
+ @Override
+ public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+ HttpSolrClient client = (HttpSolrClient) objInst;
+ String peer = "", core = "";
+ try {
+ URL url = new URL(client.getBaseURL());
+ peer = url.getHost() + ":" + url.getPort();
+ int idx = url.getPath().lastIndexOf('/');
+ if (idx > 0) {
+ core = url.getPath().substring(idx);
+ }
+ } catch (MalformedURLException ignore) {
+ }
+ objInst.setSkyWalkingDynamicField(new String[]{peer, core});
+ }
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) throws Throwable {
+ SolrRequest> request = (SolrRequest>) allArguments[0];
+ if (request.getPath().startsWith(SKIP_ADMIN_PREF))
+ return;
+
+ String[] info = (String[]) objInst.getSkyWalkingDynamicField();
+ SolrParams params = request.getParams();
+
+ ContextSnapshot snapshot = null;
+ String operationName = OPER_SHARD_PREF + info[1] + request.getPath();
+ if (params.getBool(SW_ENHANCE_FLAG, false)) {
+ if (params instanceof ModSolrParamsWrapper) {
+ EnhancedInstance instance = (EnhancedInstance) request.getParams();
+ snapshot = (ContextSnapshot) instance.getSkyWalkingDynamicField();
+ }
+ ((ModifiableSolrParams) params).remove(SW_ENHANCE_FLAG);
+ final int purpose = params.getInt(ShardParams.SHARDS_PURPOSE, 0);
+ operationName = operationName + NamesMap.gePurposeName(purpose);
+ }
+
+ AbstractSpan span = ContextManager.createExitSpan(operationName, info[0]);
+ span.setComponent(ComponentsDefine.SOLR);
+ span.setLayer(SpanLayer.HTTP);
+
+ if (snapshot != null) {
+ ContextManager.continued(snapshot);
+ }
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) throws Throwable {
+ SolrRequest> request = (SolrRequest>) allArguments[0];
+ if (!request.getPath().startsWith(SKIP_ADMIN_PREF) && ContextManager.isActive()) {
+ ContextManager.stopSpan();
+ }
+ 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/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/shard/SolrClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/shard/SolrClientInstrumentation.java
new file mode 100644
index 000000000000..d890ae28486f
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/shard/SolrClientInstrumentation.java
@@ -0,0 +1,92 @@
+/*
+ * 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.solr.shard;
+
+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 ElementMatcher getConstructorMatcher() {
+ return ElementMatchers.any();
+ }
+
+ @Override
+ public String getConstructorInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solr.shard.ShardRequestInterceptor";
+ }
+ }
+ };
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ 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.solr.shard.ShardConnectorInterceptor";
+ }
+ },
+ 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.solr.shard.ShardRequestInterceptor";
+ }
+ }
+ };
+ }
+
+ @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/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/ConcurrentUpdateSolrClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/ConcurrentUpdateSolrClientInstrumentation.java
new file mode 100644
index 000000000000..ab670ae0cafb
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/ConcurrentUpdateSolrClientInstrumentation.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.solr.update;
+
+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 ConcurrentUpdateSolrClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ @Override
+ protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[]{
+ new ConstructorInterceptPoint() {
+ @Override
+ public String getConstructorInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solr.update.ConcurrentUpdateSolrClientInterceptor";
+ }
+
+ @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("sendUpdateStream");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solr.update.ConcurrentUpdateSolrClientInterceptor";
+ }
+ }
+ };
+ }
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName("org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrClient$Runner");
+ }
+}
\ No newline at end of file
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/ConcurrentUpdateSolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/ConcurrentUpdateSolrClientInterceptor.java
new file mode 100644
index 000000000000..03c57ac395ef
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/ConcurrentUpdateSolrClientInterceptor.java
@@ -0,0 +1,78 @@
+/*
+ * 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.solr.update;
+
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.ContextSnapshot;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.slf4j.MDC;
+
+import java.lang.reflect.Method;
+
+import static org.apache.skywalking.apm.plugin.solr.commons.Constants.*;
+
+public class ConcurrentUpdateSolrClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor {
+
+ @Override
+ public void onConstruct(EnhancedInstance objInst, Object[] allArguments) {
+ String coreName = MDC.get(MDC_KEY_CORE).substring(2);
+ if (ContextManager.isActive()) {
+ objInst.setSkyWalkingDynamicField(new Object[] {ContextManager.capture(), coreName});
+ }
+ }
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) throws Throwable {
+ Object[] params = (Object[]) objInst.getSkyWalkingDynamicField();
+ ContextSnapshot snapshot = (ContextSnapshot) params[0];
+
+ String nodeName = MDC.get(MDC_KEY_NODE_NAME);
+ final String peer = nodeName.substring(2, nodeName.length() - 5);
+
+ AbstractSpan span = ContextManager.createExitSpan(OPER_SHARD_PREF_SLASH + params[1] + "/update", peer);
+ span.setComponent(ComponentsDefine.SOLR).setLayer(SpanLayer.HTTP);
+
+ if (snapshot != null) {
+ ContextManager.continued(snapshot);
+ }
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) throws Throwable {
+ if (ContextManager.isActive()) {
+ ContextManager.stopSpan();
+ }
+ 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/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/UpdateShardHandlerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/UpdateShardHandlerInstrumentation.java
new file mode 100644
index 000000000000..7be0ac4a5bb2
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/UpdateShardHandlerInstrumentation.java
@@ -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.solr.update;
+
+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 UpdateShardHandlerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ @Override
+ protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[]{
+ };
+ }
+
+ @Override
+ protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[]{
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return ElementMatchers.named("getUpdateOnlyHttpClient");
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return "org.apache.skywalking.apm.plugin.solr.update.UpdateShardHandlerInterceptor";
+ }
+ }
+ };
+ }
+
+ @Override
+ protected ClassMatch enhanceClass() {
+ return NameMatch.byName("org.apache.solr.update.UpdateShardHandler");
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/UpdateShardHandlerInterceptor.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/UpdateShardHandlerInterceptor.java
new file mode 100644
index 000000000000..8fa18215b15d
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/update/UpdateShardHandlerInterceptor.java
@@ -0,0 +1,45 @@
+/*
+ * 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.solr.update;
+
+import org.apache.http.impl.client.CloseableHttpClient;
+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.solr.wrappers.CloaseableHttpClientWrapper;
+
+import java.lang.reflect.Method;
+
+public class UpdateShardHandlerInterceptor implements InstanceMethodsAroundInterceptor {
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) throws Throwable {
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) throws Throwable {
+ return new CloaseableHttpClientWrapper((CloseableHttpClient) ret);
+ }
+
+ @Override
+ public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes, Throwable t) {
+ }
+}
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/wrappers/CloaseableHttpClientWrapper.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/wrappers/CloaseableHttpClientWrapper.java
new file mode 100644
index 000000000000..e0adfb94bd76
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/wrappers/CloaseableHttpClientWrapper.java
@@ -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.plugin.solr.wrappers;
+
+import org.apache.http.HttpHost;
+import org.apache.http.HttpRequest;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.HttpContext;
+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.logging.api.ILog;
+import org.apache.skywalking.apm.agent.core.logging.api.LogManager;
+
+import java.io.IOException;
+
+public class CloaseableHttpClientWrapper extends CloseableHttpClient {
+ private static final ILog LOG = LogManager.getLogger(CloaseableHttpClientWrapper.class);
+ private final CloseableHttpClient client;
+
+ public CloaseableHttpClientWrapper(CloseableHttpClient client) {
+ this.client = client;
+ }
+
+ @Override
+ public HttpParams getParams() {
+ return client.getParams();
+ }
+
+ @Override
+ public ClientConnectionManager getConnectionManager() {
+ return client.getConnectionManager();
+ }
+
+ @Override
+ public void close() throws IOException {
+ client.close();
+ }
+
+ @Override
+ protected CloseableHttpResponse doExecute(HttpHost target, HttpRequest request, HttpContext context)
+ throws IOException, ClientProtocolException {
+ try {
+ ContextCarrier carrier = new ContextCarrier();
+ ContextManager.inject(carrier);
+ CarrierItem items = carrier.items();
+ while (items.hasNext()) {
+ items = items.next();
+ request.addHeader(items.getHeadKey(), items.getHeadValue());
+ }
+ } catch (Throwable throwable) {
+ LOG.error("", throwable);
+ }
+ return client.execute(target, request, context);
+ }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/wrappers/ModSolrParamsWrapper.java b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/wrappers/ModSolrParamsWrapper.java
new file mode 100644
index 000000000000..ebb6e262fc59
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solr/wrappers/ModSolrParamsWrapper.java
@@ -0,0 +1,45 @@
+/*
+ * 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.solr.wrappers;
+
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.plugin.solr.commons.Constants;
+import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.params.SolrParams;
+
+public class ModSolrParamsWrapper extends ModifiableSolrParams implements EnhancedInstance {
+ private static final long serialVersionUID = 9015331918376176370L;
+ private Object dynamic = null;
+
+ public ModSolrParamsWrapper(SolrParams params) {
+ super(params);
+ set(Constants.SW_ENHANCE_FLAG, true);
+ }
+
+ @Override
+ public Object getSkyWalkingDynamicField() {
+ return dynamic;
+ }
+
+ @Override
+ public void setSkyWalkingDynamicField(Object object) {
+ this.dynamic = object;
+ }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 000000000000..c3601217fdca
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/solr-7.x-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,22 @@
+# 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.
+
+solr-7.x=org.apache.skywalking.apm.plugin.solr.RequestHandlerBaseInstrumentation
+solr-7.x=org.apache.skywalking.apm.plugin.solr.shard.SolrClientInstrumentation
+solr-7.x=org.apache.skywalking.apm.plugin.solr.search.QueryStageTracerInstrumentation
+solr-7.x=org.apache.skywalking.apm.plugin.solr.search.HttpShardHandlerInstrumentation
+solr-7.x=org.apache.skywalking.apm.plugin.solr.update.ConcurrentUpdateSolrClientInstrumentation
+solr-7.x=org.apache.skywalking.apm.plugin.solr.update.UpdateShardHandlerInstrumentation
\ No newline at end of file
diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md
index 1f52dffdddaa..8f1961f349ca 100644
--- a/docs/en/setup/service-agent/java-agent/Supported-list.md
+++ b/docs/en/setup/service-agent/java-agent/Supported-list.md
@@ -53,7 +53,9 @@
* [Xmemcached](https://github.com/killme2008/xmemcached) 2.x
* [Elasticsearch](https://github.com/elastic/elasticsearch)
* [transport-client](https://github.com/elastic/elasticsearch/tree/master/client/transport) 5.2.x-5.6.x
- * [Solr](https://github.com/apache/lucene-solr/)
+
+ * [Solr]
+ * [Solr](https://github.com/apache/lucene-solr/) 7.x
* [SolrJ](https://github.com/apache/lucene-solr/tree/master/solr/solrj) 7.x
* Service Discovery