From de5b793a52d70d78585e20acfd197d9af9602441 Mon Sep 17 00:00:00 2001 From: daming Date: Wed, 22 May 2019 11:24:01 +0800 Subject: [PATCH 01/20] new branch for solrj-plugin --- .../trace/component/ComponentsDefine.java | 3 + apm-sniffer/apm-sdk-plugin/pom.xml | 5 +- .../apm-sdk-plugin/solrj-7.x-plugin/pom.xml | 64 ++++++ .../plugin/solrj/SolrClientInterceptor.java | 198 ++++++++++++++++++ .../solrj/SolrConnectorInterceptor.java | 64 ++++++ .../plugin/solrj/commons/SolrjInstance.java | 61 ++++++ .../apm/plugin/solrj/commons/SolrjTags.java | 69 ++++++ .../define/HttpClientInstrumentation.java | 64 ++++++ .../define/SolrClientInstrumentation.java | 75 +++++++ .../src/main/resources/skywalking-plugin.def | 18 ++ 10 files changed, 619 insertions(+), 2 deletions(-) create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrConnectorInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/SolrjInstance.java create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/SolrjTags.java create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/define/HttpClientInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/define/SolrClientInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/resources/skywalking-plugin.def 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 c3a10f28f7f7..6104c0c1a81b 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 @@ -120,6 +120,8 @@ public class ComponentsDefine { public static final OfficialComponent SPRING_CLOUD_GATEWAY = new OfficialComponent(61, "spring-cloud-gateway"); + public static final OfficialComponent SOLRJ = new OfficialComponent(62, "solrj"); + private static ComponentsDefine INSTANCE = new ComponentsDefine(); private String[] components; @@ -176,6 +178,7 @@ public ComponentsDefine() { addComponent(ZOOKEEPER); addComponent(VERTX); addComponent(SPRING_CLOUD_GATEWAY); + addComponent(SOLRJ); } private void addComponent(OfficialComponent component) { diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 1bd9a70cdc96..505be380c826 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -28,7 +28,7 @@ apm-sdk-plugin - dubbo-plugin + + solrj-7.x-plugins pom 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..f41a8f2830cf --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml @@ -0,0 +1,64 @@ + + + + + apm-sdk-plugin + org.apache.skywalking + 6.1.0-SNAPSHOT + + 4.0.0 + + apm-solrj-7.x-plugin + jar + + solrj-7.x-plugin + http://maven.apache.org + + + UTF-8 + 1.8 + ${java.version} + ${java.version} + 7.7.1 + + + + + org.apache.solr + solr-solrj + ${solr-solrj.version} + provided + + + org.apache.httpcomponents + httpclient + 4.5.6 + provided + + + org.apache.httpcomponents + httpcore + 4.4.10 + 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/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java new file mode 100644 index 000000000000..498c2a1d4e5d --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -0,0 +1,198 @@ +/* + * 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.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.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.solrj.commons.SolrjInstance; +import org.apache.skywalking.apm.plugin.solrj.commons.SolrjTags; +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.SolrDocumentList; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.params.CommonParams; +import org.apache.solr.common.params.ModifiableSolrParams; +import org.apache.solr.common.params.SolrParams; +import org.apache.solr.common.params.UpdateParams; +import org.apache.solr.common.util.NamedList; + +import java.lang.reflect.Method; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +// +public class SolrClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { + private static final Pattern URL_REGEX = Pattern.compile("(?http(s)?://)*(?[\\w_.\\-\\d]+(:\\d+)?)?/(?solr/(?[\\w_]+))?(/.*)?"); + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { +// HttpSolrClient(HttpSolrClient.Builder builder) + SolrjInstance instance = new SolrjInstance(); + HttpSolrClient client = (HttpSolrClient) objInst; + + Matcher matcher = URL_REGEX.matcher(client.getBaseURL()); + if (matcher.find()) { + instance.setRemotePeer(matcher.group(3)); + if (matcher.group(6) != null) + instance.setCollection(matcher.group(6)); + } + objInst.setSkyWalkingDynamicField(instance); + } + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + SolrRequest request = (SolrRequest) allArguments[0]; + SolrjInstance instance = (SolrjInstance) objInst.getSkyWalkingDynamicField(); + + String collection = instance.getCollection(); + Object ocollection = allArguments[2]; + if (ocollection != null) { + collection = ocollection.toString(); + } + if (collection == null || "".equals(collection)) { + collection = ""; + } + + SolrParams params = request.getParams(); + if (params == null) { + params = new ModifiableSolrParams(); + } + + + AbstractSpan span = null; + if (request instanceof AbstractUpdateRequest) { + AbstractUpdateRequest update = (AbstractUpdateRequest) request; + String action = "ADD"; + if (update.getAction() != null) { + action = update.getAction().name(); + + if (update.getAction() == AbstractUpdateRequest.ACTION.COMMIT) { + span = getSpan(collection, request.getPath(), action, instance.getRemotePeer()); + + span.tag(SolrjTags.TAG_COMMIT, params.get(UpdateParams.COMMIT, "true")); + span.tag(SolrjTags.TAG_SOFT_COMMIT, params.get(UpdateParams.SOFT_COMMIT, "")); + } else if (update.getAction() == AbstractUpdateRequest.ACTION.OPTIMIZE) { + span = getSpan(collection, request.getPath(), action, instance.getRemotePeer()); + + span.tag(SolrjTags.TAG_OPTIMIZE, params.get(UpdateParams.OPTIMIZE, "true")); + span.tag(SolrjTags.TAG_MAX_OPTIMIZE_SEGMENTS, params.get(UpdateParams.MAX_OPTIMIZE_SEGMENTS, "1")); + } + } else { + if (update instanceof UpdateRequest) { + UpdateRequest ur = (UpdateRequest) update; + List documents = ur.getDocuments(); + if (documents == null) { + action = "DELETE"; + + span = getSpan(collection, request.getPath(), action, instance.getRemotePeer()); + List deleteBy = ur.getDeleteById(); + if (deleteBy != null && !deleteBy.isEmpty()) { + span.tag(SolrjTags.TAG_DELETE_TYPE, "deleteByIds"); + span.tag(SolrjTags.TAG_DELETE_VALUE, deleteBy.toString()); + } + List deleteQuery = ur.getDeleteQuery(); + if (deleteQuery != null && !deleteQuery.isEmpty()) { + span.tag(SolrjTags.TAG_DELETE_TYPE, "deleteByQuery"); + span.tag(SolrjTags.TAG_DELETE_VALUE, deleteQuery.toString()); + } + } else { + span = getSpan(collection, request.getPath(), action, instance.getRemotePeer()); + span.tag(SolrjTags.TAG_DOCS_SIZE, String.valueOf(documents.size())); + span.tag(SolrjTags.TAG_COMMIT_WITHIN, String.valueOf(update.getCommitWithin())); + } + } + } + span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, "/update")); + span.tag(SolrjTags.TAG_ACTION, action); + } else if (request instanceof QueryRequest) { + String operatorName = String.format("solrJ/%s%s", collection, request.getPath()); + span = ContextManager.createExitSpan(operatorName, instance.getRemotePeer()) + .setComponent(ComponentsDefine.SOLRJ) + .setLayer(SpanLayer.DB); + span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, "/select")); + } + + span.tag(SolrjTags.TAG_PATH, request.getPath()); + span.tag(SolrjTags.TAG_COLLECTION, collection); + span.tag(SolrjTags.TAG_METHOD, request.getMethod().name()); + + ContextManager.getRuntimeContext().put("instance", instance); + ContextManager.getRuntimeContext().put("request.start", Long.valueOf(System.currentTimeMillis())); + } + + @Override + @SuppressWarnings("unchecked") + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + if (!ContextManager.isActive()) return ret; + + Long qStart = ContextManager.getRuntimeContext().get("request.start", Long.class); + long elapse = System.currentTimeMillis() - qStart.longValue(); + + AbstractSpan span = ContextManager.activeSpan(); + if (ret instanceof SolrDocumentList) { + SolrDocumentList list = (SolrDocumentList) ret; + span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); + } + NamedList response = (NamedList) ret; + if (response != null) { + NamedList header = (NamedList) response.get("responseHeader"); + if (header != null) { // common + span.tag(SolrjTags.TAG_STATUS, header.get("status").toString()); + span.tag(SolrjTags.TAG_Q_TIME, header.get("QTime").toString()); + } + SolrDocumentList list = (SolrDocumentList) response.get("response"); + if (list != null) { // query + span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); + } + } + SolrjInstance instance = ContextManager.getRuntimeContext().get("instance", SolrjInstance.class); + SolrjTags.addHttpResponse(span, instance); + SolrjTags.addElapseTime(span, elapse); + + ContextManager.getRuntimeContext().remove("instance"); + ContextManager.getRuntimeContext().remove("request.start"); + ContextManager.stopSpan(); + + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + ContextManager.activeSpan().errorOccurred().log(t); + } + + static final AbstractSpan getSpan(String collection, String path, String action, String remotePeer) { + // solr/collection/update/ + String operatorName = String.format("solrJ/%s%s/%s", collection, path, action); + return ContextManager.createExitSpan(operatorName, remotePeer) + .setComponent(ComponentsDefine.SOLRJ) + .setLayer(SpanLayer.DB); + } +} 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..14ac1434f898 --- /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,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.solrj; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpUriRequest; +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 org.apache.skywalking.apm.plugin.solrj.commons.SolrjInstance; + +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 { + HttpUriRequest request = (HttpUriRequest) 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 { + SolrjInstance instance = ContextManager.getRuntimeContext().get("instance", SolrjInstance.class); + if (ContextManager.isActive()) { + CloseableHttpResponse response = (CloseableHttpResponse) ret; + instance.withHttpResponse(response.getStatusLine().getStatusCode(), response.getEntity()); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + 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..8d4bdb0ead86 --- /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,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.commons; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; + +public class SolrjInstance { + private String collection; + private String remotePeer; + + 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; + } + + long contentLength = 0; + String contentType = ""; + String contentEncoding = ""; + int statusCode = -1; + + public void withHttpResponse(int statusCode, HttpEntity entity) { + Header header = entity.getContentEncoding(); + if (header != null) { + this.contentEncoding = header.toString(); + } + header = entity.getContentType(); + if (header != null) { + this.contentType = header.toString(); + } + + this.statusCode = statusCode; + this.contentLength = entity.getContentLength(); + } +} 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..f504460b7849 --- /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,69 @@ +/* + * 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; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; + +public class SolrjTags { + + // public static StringTag DB_TYPE = new StringTag(1, "db.type"); + public static StringTag TAG_QT = new StringTag(1,"qt"); + public static StringTag TAG_PATH = new StringTag(2, "path"); + public static StringTag TAG_COLLECTION = new StringTag(3, "collection"); + public static StringTag TAG_ACTION = new StringTag(4, "action"); + public static StringTag TAG_METHOD = new StringTag(5, "method"); + public static StringTag TAG_COMMIT_WITHIN = new StringTag(6, "commitWithin"); + public static StringTag TAG_STATUS = new StringTag(7, "status"); + public static StringTag TAG_Q_TIME = new StringTag(8, "QTime"); + public static StringTag TAG_NUM_FOUND = new StringTag(9, "numFound"); + + + + public static StringTag TAG_STATUS_CODE = new StringTag(10, "statusCode"); + public static StringTag TAG_ELAPSE_TIME = new StringTag(11, "elapseTime"); + + public static StringTag TAG_CONTENT_TYPE = new StringTag(12, "contentType"); + public static StringTag TAG_CONTENT_LENGTH = new StringTag(13, "contentLength"); + public static StringTag TAG_CONTENT_ENCODING = new StringTag(14, "contentEncoding"); + + public static StringTag TAG_COMMIT = new StringTag(15, "commit"); + public static StringTag TAG_SOFT_COMMIT = new StringTag(16, "softCommit"); + + public static StringTag TAG_OPTIMIZE = new StringTag(17, "optimize"); + public static StringTag TAG_MAX_OPTIMIZE_SEGMENTS = new StringTag(18, "maxOptimizeSegs"); + + public static StringTag TAG_DELETE_TYPE = new StringTag(19, "delete.type"); + public static StringTag TAG_DELETE_VALUE = new StringTag(20, "delete.by"); + public static StringTag TAG_DOCS_SIZE = new StringTag(21, "docsSize"); + + + public static void addElapseTime(AbstractSpan span, long etime) { + span.tag(TAG_ELAPSE_TIME, Long.toString(etime)); + } + + public static void addHttpResponse(AbstractSpan span, SolrjInstance instance) { + span.tag(TAG_CONTENT_TYPE, instance.contentType); + span.tag(TAG_CONTENT_ENCODING, instance.contentEncoding); + + span.tag(TAG_STATUS_CODE, Integer.toString(instance.statusCode)); + span.tag(TAG_CONTENT_LENGTH, Long.toString(instance.contentLength)); + } + + +} diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/define/HttpClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/define/HttpClientInstrumentation.java new file mode 100644 index 000000000000..56e752b07282 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/define/HttpClientInstrumentation.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.solrj.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.matcher.ElementMatchers; +import org.apache.http.client.methods.HttpUriRequest; +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 HttpClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + private static String ENHANCE_CLASS = "org.apache.http.impl.client.CloseableHttpClient"; + + @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("execute").and(ElementMatchers.takesArgument(0, HttpUriRequest.class)); + } + + @Override + public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.solrj.SolrConnectorInterceptor"; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.byName(ENHANCE_CLASS); + } +} \ 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/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..75f3a2e27b83 --- /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,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.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"; + } + } + }; + } + + @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..04e757a21f7b --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,18 @@ +# 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=org.apache.skywalking.apm.plugin.solrj.define.SolrClientInstrumentation +solrj=org.apache.skywalking.apm.plugin.solrj.define.HttpClientInstrumentation \ No newline at end of file From 1031356c75ff7e00b1a1f47ae094a28f240e705c Mon Sep 17 00:00:00 2001 From: daming Date: Wed, 22 May 2019 14:14:00 +0800 Subject: [PATCH 02/20] rollback and add module solrj-plugin --- apm-sniffer/apm-sdk-plugin/pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 505be380c826..09bdad286499 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -28,7 +28,7 @@ apm-sdk-plugin - - solrj-7.x-plugins + vertx-plugins + solrj-7.x-plugin pom From 0ce30170f52520f8f864a0c02124fa34fe186188 Mon Sep 17 00:00:00 2001 From: daming Date: Wed, 22 May 2019 14:16:03 +0800 Subject: [PATCH 03/20] preparing to pr --- .../apm-sdk-plugin/solrj-7.x-plugin/pom.xml | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) 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 index f41a8f2830cf..648dbfd6fd54 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml @@ -20,7 +20,7 @@ apm-sdk-plugin org.apache.skywalking - 6.1.0-SNAPSHOT + 6.2.0-SNAPSHOT 4.0.0 @@ -39,26 +39,12 @@ - + org.apache.solr solr-solrj ${solr-solrj.version} provided - - org.apache.httpcomponents - httpclient - 4.5.6 - provided - - - org.apache.httpcomponents - httpcore - 4.4.10 - provided - - - \ No newline at end of file From 9151a87048989ba29894d221adce40891498320b Mon Sep 17 00:00:00 2001 From: daming Date: Thu, 23 May 2019 14:35:52 +0800 Subject: [PATCH 04/20] to resolve reviewers' suggestions --- .../plugin/solrj/SolrClientInterceptor.java | 102 +++++++++--------- .../solrj/SolrConnectorInterceptor.java | 3 +- .../apm/plugin/solrj/commons/Context.java | 90 ++++++++++++++++ .../plugin/solrj/commons/SolrjInstance.java | 26 +---- .../apm/plugin/solrj/commons/SolrjTags.java | 14 +-- .../src/main/resources/skywalking-plugin.def | 4 +- 6 files changed, 152 insertions(+), 87 deletions(-) create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java index 498c2a1d4e5d..ba336572c674 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -25,6 +25,7 @@ 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.solrj.commons.Context; import org.apache.skywalking.apm.plugin.solrj.commons.SolrjInstance; import org.apache.skywalking.apm.plugin.solrj.commons.SolrjTags; import org.apache.solr.client.solrj.SolrRequest; @@ -45,7 +46,6 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -// public class SolrClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { private static final Pattern URL_REGEX = Pattern.compile("(?http(s)?://)*(?[\\w_.\\-\\d]+(:\\d+)?)?/(?solr/(?[\\w_]+))?(/.*)?"); @@ -58,8 +58,9 @@ public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { Matcher matcher = URL_REGEX.matcher(client.getBaseURL()); if (matcher.find()) { instance.setRemotePeer(matcher.group(3)); - if (matcher.group(6) != null) + if (matcher.group(6) != null) { instance.setCollection(matcher.group(6)); + } } objInst.setSkyWalkingDynamicField(instance); } @@ -70,47 +71,23 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr SolrRequest request = (SolrRequest) allArguments[0]; SolrjInstance instance = (SolrjInstance) objInst.getSkyWalkingDynamicField(); - String collection = instance.getCollection(); - Object ocollection = allArguments[2]; - if (ocollection != null) { - collection = ocollection.toString(); - } - if (collection == null || "".equals(collection)) { - collection = ""; - } - - SolrParams params = request.getParams(); - if (params == null) { - params = new ModifiableSolrParams(); - } - + SolrParams params = getParams(request.getParams()); + String collection = getCollection(instance, allArguments[2]); AbstractSpan span = null; - if (request instanceof AbstractUpdateRequest) { + if ("/update".equals(request.getPath())) { AbstractUpdateRequest update = (AbstractUpdateRequest) request; - String action = "ADD"; - if (update.getAction() != null) { - action = update.getAction().name(); - if (update.getAction() == AbstractUpdateRequest.ACTION.COMMIT) { - span = getSpan(collection, request.getPath(), action, instance.getRemotePeer()); - - span.tag(SolrjTags.TAG_COMMIT, params.get(UpdateParams.COMMIT, "true")); - span.tag(SolrjTags.TAG_SOFT_COMMIT, params.get(UpdateParams.SOFT_COMMIT, "")); - } else if (update.getAction() == AbstractUpdateRequest.ACTION.OPTIMIZE) { - span = getSpan(collection, request.getPath(), action, instance.getRemotePeer()); - - span.tag(SolrjTags.TAG_OPTIMIZE, params.get(UpdateParams.OPTIMIZE, "true")); - span.tag(SolrjTags.TAG_MAX_OPTIMIZE_SEGMENTS, params.get(UpdateParams.MAX_OPTIMIZE_SEGMENTS, "1")); - } - } else { + String actionName = "ADD"; + AbstractUpdateRequest.ACTION action = update.getAction(); + if (action == null) { if (update instanceof UpdateRequest) { UpdateRequest ur = (UpdateRequest) update; List documents = ur.getDocuments(); if (documents == null) { - action = "DELETE"; + actionName = "DELETE"; - span = getSpan(collection, request.getPath(), action, instance.getRemotePeer()); + span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); List deleteBy = ur.getDeleteById(); if (deleteBy != null && !deleteBy.isEmpty()) { span.tag(SolrjTags.TAG_DELETE_TYPE, "deleteByIds"); @@ -122,28 +99,41 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr span.tag(SolrjTags.TAG_DELETE_VALUE, deleteQuery.toString()); } } else { - span = getSpan(collection, request.getPath(), action, instance.getRemotePeer()); + span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); span.tag(SolrjTags.TAG_DOCS_SIZE, String.valueOf(documents.size())); span.tag(SolrjTags.TAG_COMMIT_WITHIN, String.valueOf(update.getCommitWithin())); } } + } else { + actionName = action.name(); + if (action == AbstractUpdateRequest.ACTION.COMMIT) { + span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); + + span.tag(SolrjTags.TAG_COMMIT, "true"); + span.tag(SolrjTags.TAG_SOFT_COMMIT, params.get(UpdateParams.SOFT_COMMIT, "")); + } else { + span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); + + span.tag(SolrjTags.TAG_OPTIMIZE, "true"); + span.tag(SolrjTags.TAG_MAX_OPTIMIZE_SEGMENTS, params.get(UpdateParams.MAX_OPTIMIZE_SEGMENTS, "1")); + } } - span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, "/update")); - span.tag(SolrjTags.TAG_ACTION, action); - } else if (request instanceof QueryRequest) { + span.tag(SolrjTags.TAG_ACTION, actionName); + } else if (request instanceof QueryRequest) { // It failed to spot that through 'path' when it had defined QueryType. String operatorName = String.format("solrJ/%s%s", collection, request.getPath()); span = ContextManager.createExitSpan(operatorName, instance.getRemotePeer()) .setComponent(ComponentsDefine.SOLRJ) .setLayer(SpanLayer.DB); - span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, "/select")); + } else { // No admin API + return; } span.tag(SolrjTags.TAG_PATH, request.getPath()); span.tag(SolrjTags.TAG_COLLECTION, collection); span.tag(SolrjTags.TAG_METHOD, request.getMethod().name()); + span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, request.getPath())); - ContextManager.getRuntimeContext().put("instance", instance); - ContextManager.getRuntimeContext().put("request.start", Long.valueOf(System.currentTimeMillis())); + Context.get().start(); } @Override @@ -152,14 +142,10 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA Class[] argumentsTypes, Object ret) throws Throwable { if (!ContextManager.isActive()) return ret; - Long qStart = ContextManager.getRuntimeContext().get("request.start", Long.class); - long elapse = System.currentTimeMillis() - qStart.longValue(); + final Context context = Context.remove(); + final long elapse = System.currentTimeMillis() - context.getStartTime(); AbstractSpan span = ContextManager.activeSpan(); - if (ret instanceof SolrDocumentList) { - SolrDocumentList list = (SolrDocumentList) ret; - span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); - } NamedList response = (NamedList) ret; if (response != null) { NamedList header = (NamedList) response.get("responseHeader"); @@ -172,14 +158,10 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); } } - SolrjInstance instance = ContextManager.getRuntimeContext().get("instance", SolrjInstance.class); - SolrjTags.addHttpResponse(span, instance); + SolrjTags.addHttpResponse(span, context); SolrjTags.addElapseTime(span, elapse); - ContextManager.getRuntimeContext().remove("instance"); - ContextManager.getRuntimeContext().remove("request.start"); ContextManager.stopSpan(); - return ret; } @@ -188,11 +170,25 @@ public void handleMethodException(EnhancedInstance objInst, Method method, Objec ContextManager.activeSpan().errorOccurred().log(t); } - static final AbstractSpan getSpan(String collection, String path, String action, String remotePeer) { + private static final AbstractSpan getSpan(String collection, String path, String action, String remotePeer) { // solr/collection/update/ String operatorName = String.format("solrJ/%s%s/%s", collection, path, action); return ContextManager.createExitSpan(operatorName, remotePeer) .setComponent(ComponentsDefine.SOLRJ) .setLayer(SpanLayer.DB); } + + private static final String getCollection(SolrjInstance instance, Object argument) { + if (null == argument) { + return instance.getCollection(); + } + return String.valueOf(argument); + } + + private static final SolrParams getParams(SolrParams params) { + if (params == null) { + return new ModifiableSolrParams(); + } + return params; + } } 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 index 14ac1434f898..600b6e4bdcd9 100644 --- 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 @@ -25,6 +25,7 @@ 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.solrj.commons.Context; import org.apache.skywalking.apm.plugin.solrj.commons.SolrjInstance; import java.lang.reflect.Method; @@ -52,7 +53,7 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA SolrjInstance instance = ContextManager.getRuntimeContext().get("instance", SolrjInstance.class); if (ContextManager.isActive()) { CloseableHttpResponse response = (CloseableHttpResponse) ret; - instance.withHttpResponse(response.getStatusLine().getStatusCode(), response.getEntity()); + Context.get().withHttpResponse(response.getStatusLine().getStatusCode(), response.getEntity()); } return ret; } diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java new file mode 100644 index 000000000000..0f56247a6fea --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java @@ -0,0 +1,90 @@ +/* + * 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.http.Header; +import org.apache.http.HttpEntity; + +public class Context { + private static final ThreadLocal CONTEXT = new ThreadLocal() { + @Override + protected Context initialValue() { + return new Context(); + } + }; + + private long contentLength = 0; + private String contentType = ""; + private String contentEncoding = ""; + private int statusCode = -1; + + private long startTime = 0; + + private Context() { + } + + public void start() { + startTime = System.currentTimeMillis(); + } + + public static final void withHttpResponse(int statusCode, HttpEntity entity) { + final Context context = CONTEXT.get(); + Header header = entity.getContentEncoding(); + if (header != null) { + context.contentEncoding = header.toString(); + } + header = entity.getContentType(); + if (header != null) { + context.contentType = header.toString(); + } + + context.statusCode = statusCode; + context.contentLength = entity.getContentLength(); + } + + public static final Context get() { + return CONTEXT.get(); + } + + public static final Context remove() { + final Context context = CONTEXT.get(); + CONTEXT.remove(); + return context; + } + + public long getContentLength() { + return contentLength; + } + + public String getContentType() { + return contentType; + } + + public String getContentEncoding() { + return contentEncoding; + } + + public int getStatusCode() { + return statusCode; + } + + public long getStartTime() { + return startTime; + } +} 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 index 8d4bdb0ead86..91e4cfb362f0 100644 --- 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 @@ -17,12 +17,9 @@ */ package org.apache.skywalking.apm.plugin.solrj.commons; -import org.apache.http.Header; -import org.apache.http.HttpEntity; - public class SolrjInstance { - private String collection; - private String remotePeer; + private String collection = "Unknown"; + private String remotePeer = "Unknown"; public String getCollection() { return collection; @@ -39,23 +36,4 @@ public String getRemotePeer() { public void setRemotePeer(String remotePeer) { this.remotePeer = remotePeer; } - - long contentLength = 0; - String contentType = ""; - String contentEncoding = ""; - int statusCode = -1; - - public void withHttpResponse(int statusCode, HttpEntity entity) { - Header header = entity.getContentEncoding(); - if (header != null) { - this.contentEncoding = header.toString(); - } - header = entity.getContentType(); - if (header != null) { - this.contentType = header.toString(); - } - - this.statusCode = statusCode; - this.contentLength = entity.getContentLength(); - } } 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 index f504460b7849..39637cdac752 100644 --- 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 @@ -53,16 +53,16 @@ public class SolrjTags { public static StringTag TAG_DOCS_SIZE = new StringTag(21, "docsSize"); - public static void addElapseTime(AbstractSpan span, long etime) { - span.tag(TAG_ELAPSE_TIME, Long.toString(etime)); + public static void addElapseTime(AbstractSpan span, long eTime) { + span.tag(TAG_ELAPSE_TIME, Long.toString(eTime)); } - public static void addHttpResponse(AbstractSpan span, SolrjInstance instance) { - span.tag(TAG_CONTENT_TYPE, instance.contentType); - span.tag(TAG_CONTENT_ENCODING, instance.contentEncoding); + public static void addHttpResponse(AbstractSpan span, Context context) { + span.tag(TAG_CONTENT_TYPE, context.getContentType()); + span.tag(TAG_CONTENT_ENCODING, context.getContentEncoding()); - span.tag(TAG_STATUS_CODE, Integer.toString(instance.statusCode)); - span.tag(TAG_CONTENT_LENGTH, Long.toString(instance.contentLength)); + span.tag(TAG_STATUS_CODE, Integer.toString(context.getStatusCode())); + span.tag(TAG_CONTENT_LENGTH, Long.toString(context.getContentLength())); } 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 index 04e757a21f7b..fd2fd6cd0b67 100644 --- 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 @@ -14,5 +14,5 @@ # See the License for the specific language governing permissions and # limitations under the License. -solrj=org.apache.skywalking.apm.plugin.solrj.define.SolrClientInstrumentation -solrj=org.apache.skywalking.apm.plugin.solrj.define.HttpClientInstrumentation \ No newline at end of file +solrj-7.x=org.apache.skywalking.apm.plugin.solrj.define.SolrClientInstrumentation +solrj-7.x=org.apache.skywalking.apm.plugin.solrj.define.HttpClientInstrumentation \ No newline at end of file From 10d923c96a75fe2228770ac8e8f02a069d9c71df Mon Sep 17 00:00:00 2001 From: daming Date: Thu, 23 May 2019 14:39:30 +0800 Subject: [PATCH 05/20] remove unused code --- .../skywalking/apm/plugin/solrj/SolrConnectorInterceptor.java | 1 - 1 file changed, 1 deletion(-) 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 index 600b6e4bdcd9..9576a474aacd 100644 --- 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 @@ -50,7 +50,6 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { - SolrjInstance instance = ContextManager.getRuntimeContext().get("instance", SolrjInstance.class); if (ContextManager.isActive()) { CloseableHttpResponse response = (CloseableHttpResponse) ret; Context.get().withHttpResponse(response.getStatusLine().getStatusCode(), response.getEntity()); From e6b4d32d7b2617f798750cade8100da06693cd09 Mon Sep 17 00:00:00 2001 From: daming Date: Thu, 23 May 2019 14:43:21 +0800 Subject: [PATCH 06/20] remove unused code --- .../skywalking/apm/plugin/solrj/SolrConnectorInterceptor.java | 1 - 1 file changed, 1 deletion(-) 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 index 9576a474aacd..46d331e867f5 100644 --- 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 @@ -26,7 +26,6 @@ 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.solrj.commons.Context; -import org.apache.skywalking.apm.plugin.solrj.commons.SolrjInstance; import java.lang.reflect.Method; From 7bee1d676e1376dd7b0ecfaae7f568117361b90e Mon Sep 17 00:00:00 2001 From: daming Date: Fri, 24 May 2019 18:48:38 +0800 Subject: [PATCH 07/20] remove unused comments --- .../apm/plugin/solrj/SolrClientInterceptor.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java index ba336572c674..43c0c08aa19e 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -51,7 +51,6 @@ public class SolrClientInterceptor implements InstanceMethodsAroundInterceptor, @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { -// HttpSolrClient(HttpSolrClient.Builder builder) SolrjInstance instance = new SolrjInstance(); HttpSolrClient client = (HttpSolrClient) objInst; @@ -119,12 +118,12 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr } } span.tag(SolrjTags.TAG_ACTION, actionName); - } else if (request instanceof QueryRequest) { // It failed to spot that through 'path' when it had defined QueryType. + } else if (request instanceof QueryRequest) { String operatorName = String.format("solrJ/%s%s", collection, request.getPath()); span = ContextManager.createExitSpan(operatorName, instance.getRemotePeer()) .setComponent(ComponentsDefine.SOLRJ) .setLayer(SpanLayer.DB); - } else { // No admin API + } else { // No Admin API return; } @@ -149,12 +148,12 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA NamedList response = (NamedList) ret; if (response != null) { NamedList header = (NamedList) response.get("responseHeader"); - if (header != null) { // common - span.tag(SolrjTags.TAG_STATUS, header.get("status").toString()); - span.tag(SolrjTags.TAG_Q_TIME, header.get("QTime").toString()); + if (header != null) { + span.tag(SolrjTags.TAG_STATUS, String.valueOf(header.get("status"))); + span.tag(SolrjTags.TAG_Q_TIME, String.valueOf(header.get("QTime"))); } SolrDocumentList list = (SolrDocumentList) response.get("response"); - if (list != null) { // query + if (list != null) { span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); } } @@ -171,7 +170,6 @@ public void handleMethodException(EnhancedInstance objInst, Method method, Objec } private static final AbstractSpan getSpan(String collection, String path, String action, String remotePeer) { - // solr/collection/update/ String operatorName = String.format("solrJ/%s%s/%s", collection, path, action); return ContextManager.createExitSpan(operatorName, remotePeer) .setComponent(ComponentsDefine.SOLRJ) From a26b659b2e27e043d0ddebbf04419565de92b64f Mon Sep 17 00:00:00 2001 From: daming Date: Sat, 25 May 2019 02:30:11 +0800 Subject: [PATCH 08/20] To avoid NPE --- .../trace/component/ComponentsDefine.java | 3 ++ apm-sniffer/apm-sdk-plugin/pom.xml | 45 +------------------ .../plugin/solrj/SolrClientInterceptor.java | 9 ++-- .../solrj/SolrConnectorInterceptor.java | 4 +- 4 files changed, 13 insertions(+), 48 deletions(-) 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..70ff27398846 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 RESTEASY = 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-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 0060c880f0f8..a3eaf1f30d4d 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -28,50 +28,7 @@ apm-sdk-plugin - dubbo-plugin - jdbc-commons - httpClient-4.x-plugin - jedis-2.x-plugin - redisson-3.x-plugin - tomcat-7.x-8.x-plugin - motan-plugin - mongodb-3.x-plugin - feign-default-http-9.x-plugin - okhttp-3.x-plugin - spring-plugins - struts2-2.x-plugin - nutz-plugins - jetty-plugin - spymemcached-2.x-plugin - sharding-jdbc-1.5.x-plugin - sharding-sphere-3.x-plugin - xmemcached-2.x-plugin - grpc-1.x-plugin - mysql-5.x-plugin - mysql-6.x-plugin - mysql-8.x-plugin - mysql-common - h2-1.x-plugin - postgresql-8.x-plugin - rocketMQ-3.x-plugin - rocketMQ-4.x-plugin - elastic-job-2.x-plugin - mongodb-2.x-plugin - httpasyncclient-4.x-plugin - kafka-v1-plugin - servicecomb-plugin - hystrix-1.x-plugin - sofarpc-plugin - activemq-5.x-plugin - elasticsearch-5.x-plugin - undertow-plugins - rabbitmq-5.x-plugin - dubbo-conflict-patch - canal-1.x-plugin - dubbo-2.7.x-plugin - dubbo-2.7.x-conflict-patch - vertx-plugins - resteasy-plugin + solrj-7.x-plugin pom diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java index 43c0c08aa19e..c2f3d4ed5086 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -123,10 +123,11 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr span = ContextManager.createExitSpan(operatorName, instance.getRemotePeer()) .setComponent(ComponentsDefine.SOLRJ) .setLayer(SpanLayer.DB); - } else { // No Admin API - return; } + if (null == span) + return; + span.tag(SolrjTags.TAG_PATH, request.getPath()); span.tag(SolrjTags.TAG_COLLECTION, collection); span.tag(SolrjTags.TAG_METHOD, request.getMethod().name()); @@ -166,7 +167,9 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { - ContextManager.activeSpan().errorOccurred().log(t); + if (ContextManager.isActive()) { + ContextManager.activeSpan().errorOccurred().log(t); + } } private static final AbstractSpan getSpan(String collection, String path, String action, String remotePeer) { 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 index 46d331e867f5..8004922bcd17 100644 --- 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 @@ -58,6 +58,8 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { - ContextManager.activeSpan().errorOccurred().log(t); + if (ContextManager.isActive()) { + ContextManager.activeSpan().errorOccurred().log(t); + } } } From cced8a7688f7aa538b741f28c6d138da606c0cef Mon Sep 17 00:00:00 2001 From: daming Date: Sat, 25 May 2019 02:33:58 +0800 Subject: [PATCH 09/20] fix typo --- .../apm/network/trace/component/ComponentsDefine.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 70ff27398846..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,7 +122,7 @@ public class ComponentsDefine { public static final OfficialComponent RESTEASY = new OfficialComponent(62, "RESTEasy"); - public static final OfficialComponent RESTEASY = new OfficialComponent(63, "solrj"); + public static final OfficialComponent SOLRJ = new OfficialComponent(63, "solrj"); private static ComponentsDefine INSTANCE = new ComponentsDefine(); From 57799c8b9c7ff10304fdb18673ad6b26dcf32467 Mon Sep 17 00:00:00 2001 From: daming Date: Sun, 26 May 2019 02:15:17 +0800 Subject: [PATCH 10/20] Change to JRE6 --- apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml | 2 +- .../apm/plugin/solrj/SolrClientInterceptor.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) 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 index 648dbfd6fd54..f94a053bbf04 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml @@ -32,7 +32,7 @@ UTF-8 - 1.8 + 1.6 ${java.version} ${java.version} 7.7.1 diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java index c2f3d4ed5086..95b30b76fdaf 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -47,7 +47,7 @@ import java.util.regex.Pattern; public class SolrClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { - private static final Pattern URL_REGEX = Pattern.compile("(?http(s)?://)*(?[\\w_.\\-\\d]+(:\\d+)?)?/(?solr/(?[\\w_]+))?(/.*)?"); + private static final Pattern URL_REGEX = Pattern.compile("http(s)?://(?[\\w_.-]+(:\\d+)?)?/(?solr/(?[\\w-_]+))?"); @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { @@ -56,9 +56,9 @@ public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { Matcher matcher = URL_REGEX.matcher(client.getBaseURL()); if (matcher.find()) { - instance.setRemotePeer(matcher.group(3)); - if (matcher.group(6) != null) { - instance.setCollection(matcher.group(6)); + instance.setRemotePeer(matcher.group(2)); + if (matcher.group(4) != null) { + instance.setCollection(matcher.group(4)); } } objInst.setSkyWalkingDynamicField(instance); From 4af0a8fca006fae4c855ddf776df61d7e8b82f35 Mon Sep 17 00:00:00 2001 From: daming Date: Sun, 26 May 2019 03:23:56 +0800 Subject: [PATCH 11/20] fix pom.xml merge incorrectly. and java.net.URL instead of Regex --- apm-sniffer/apm-sdk-plugin/pom.xml | 46 ++++++++++++++++++- .../plugin/solrj/SolrClientInterceptor.java | 19 ++++---- 2 files changed, 56 insertions(+), 9 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index a3eaf1f30d4d..6fcd6fbf8818 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -28,6 +28,50 @@ apm-sdk-plugin + dubbo-plugin + jdbc-commons + httpClient-4.x-plugin + jedis-2.x-plugin + redisson-3.x-plugin + tomcat-7.x-8.x-plugin + motan-plugin + mongodb-3.x-plugin + feign-default-http-9.x-plugin + okhttp-3.x-plugin + spring-plugins + struts2-2.x-plugin + nutz-plugins + jetty-plugin + spymemcached-2.x-plugin + sharding-jdbc-1.5.x-plugin + sharding-sphere-3.x-plugin + xmemcached-2.x-plugin + grpc-1.x-plugin + mysql-5.x-plugin + mysql-6.x-plugin + mysql-8.x-plugin + mysql-common + h2-1.x-plugin + postgresql-8.x-plugin + rocketMQ-3.x-plugin + rocketMQ-4.x-plugin + elastic-job-2.x-plugin + mongodb-2.x-plugin + httpasyncclient-4.x-plugin + kafka-v1-plugin + servicecomb-plugin + hystrix-1.x-plugin + sofarpc-plugin + activemq-5.x-plugin + elasticsearch-5.x-plugin + undertow-plugins + rabbitmq-5.x-plugin + dubbo-conflict-patch + canal-1.x-plugin + dubbo-2.7.x-plugin + dubbo-2.7.x-conflict-patch + vertx-plugins + resteasy-plugin solrj-7.x-plugin pom @@ -138,4 +182,4 @@ - + \ 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/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java index 95b30b76fdaf..fb76005b2806 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -42,24 +42,27 @@ import org.apache.solr.common.util.NamedList; import java.lang.reflect.Method; +import java.net.MalformedURLException; +import java.net.URL; import java.util.List; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class SolrClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { - private static final Pattern URL_REGEX = Pattern.compile("http(s)?://(?[\\w_.-]+(:\\d+)?)?/(?solr/(?[\\w-_]+))?"); @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { SolrjInstance instance = new SolrjInstance(); HttpSolrClient client = (HttpSolrClient) objInst; - Matcher matcher = URL_REGEX.matcher(client.getBaseURL()); - if (matcher.find()) { - instance.setRemotePeer(matcher.group(2)); - if (matcher.group(4) != null) { - instance.setCollection(matcher.group(4)); + try { + URL url = new URL(client.getBaseURL()); + instance.setRemotePeer(url.getHost() + ":" + url.getPort()); + + String path = url.getPath(); + int idx = path.lastIndexOf('/'); + if (idx > 0) { + instance.setCollection(path.substring(idx + 1)); } + } catch (MalformedURLException ignore) { } objInst.setSkyWalkingDynamicField(instance); } From 99c31f8f05988408b122e44ed446034538e6a859 Mon Sep 17 00:00:00 2001 From: daming Date: Sun, 26 May 2019 12:44:28 +0800 Subject: [PATCH 12/20] Using RuntimeContext instead of ThreadLocal --- .../plugin/solrj/SolrClientInterceptor.java | 41 ++++++++++--------- .../solrj/SolrConnectorInterceptor.java | 3 +- .../apm/plugin/solrj/commons/Context.java | 36 ++++------------ 3 files changed, 32 insertions(+), 48 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java index fb76005b2806..4649e53ae022 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -136,7 +136,7 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr span.tag(SolrjTags.TAG_METHOD, request.getMethod().name()); span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, request.getPath())); - Context.get().start(); + ContextManager.getRuntimeContext().put("context", new Context()); } @Override @@ -145,26 +145,29 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA Class[] argumentsTypes, Object ret) throws Throwable { if (!ContextManager.isActive()) return ret; - final Context context = Context.remove(); - final long elapse = System.currentTimeMillis() - context.getStartTime(); - - AbstractSpan span = ContextManager.activeSpan(); - NamedList response = (NamedList) ret; - if (response != null) { - NamedList header = (NamedList) response.get("responseHeader"); - if (header != null) { - span.tag(SolrjTags.TAG_STATUS, String.valueOf(header.get("status"))); - span.tag(SolrjTags.TAG_Q_TIME, String.valueOf(header.get("QTime"))); - } - SolrDocumentList list = (SolrDocumentList) response.get("response"); - if (list != null) { - span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); + try { + final Context context = ContextManager.getRuntimeContext().get("context", Context.class); + final long elapse = System.currentTimeMillis() - context.getStartTime(); + + AbstractSpan span = ContextManager.activeSpan(); + NamedList response = (NamedList) ret; + if (response != null) { + NamedList header = (NamedList) response.get("responseHeader"); + if (header != null) { + span.tag(SolrjTags.TAG_STATUS, String.valueOf(header.get("status"))); + span.tag(SolrjTags.TAG_Q_TIME, String.valueOf(header.get("QTime"))); + } + SolrDocumentList list = (SolrDocumentList) response.get("response"); + if (list != null) { + span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); + } } + SolrjTags.addHttpResponse(span, context); + SolrjTags.addElapseTime(span, elapse); + } finally { + ContextManager.stopSpan(); + ContextManager.getRuntimeContext().remove("context"); } - SolrjTags.addHttpResponse(span, context); - SolrjTags.addElapseTime(span, elapse); - - ContextManager.stopSpan(); return ret; } 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 index 8004922bcd17..14536ac33de5 100644 --- 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 @@ -51,7 +51,8 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA Object ret) throws Throwable { if (ContextManager.isActive()) { CloseableHttpResponse response = (CloseableHttpResponse) ret; - Context.get().withHttpResponse(response.getStatusLine().getStatusCode(), response.getEntity()); + Context context = ContextManager.getRuntimeContext().get("context", Context.class); + context.withHttpResponse(response.getStatusLine().getStatusCode(), response.getEntity()); } return ret; } diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java index 0f56247a6fea..ce9241bc9482 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java @@ -22,13 +22,6 @@ import org.apache.http.HttpEntity; public class Context { - private static final ThreadLocal CONTEXT = new ThreadLocal() { - @Override - protected Context initialValue() { - return new Context(); - } - }; - private long contentLength = 0; private String contentType = ""; private String contentEncoding = ""; @@ -36,36 +29,23 @@ protected Context initialValue() { private long startTime = 0; - private Context() { - } - - public void start() { + public Context() { startTime = System.currentTimeMillis(); } - public static final void withHttpResponse(int statusCode, HttpEntity entity) { - final Context context = CONTEXT.get(); - Header header = entity.getContentEncoding(); + public final void withHttpResponse(int statusCode, HttpEntity entity) { + Header header = null; + header = entity.getContentEncoding(); if (header != null) { - context.contentEncoding = header.toString(); + this.contentEncoding = header.toString(); } header = entity.getContentType(); if (header != null) { - context.contentType = header.toString(); + this.contentType = header.toString(); } - context.statusCode = statusCode; - context.contentLength = entity.getContentLength(); - } - - public static final Context get() { - return CONTEXT.get(); - } - - public static final Context remove() { - final Context context = CONTEXT.get(); - CONTEXT.remove(); - return context; + this.statusCode = statusCode; + this.contentLength = entity.getContentLength(); } public long getContentLength() { From f809f8c0b0fc642db91fd85204e018e137b2f7ea Mon Sep 17 00:00:00 2001 From: daming Date: Sun, 26 May 2019 17:54:27 +0800 Subject: [PATCH 13/20] To reduce unnecessary tags --- .../plugin/solrj/SolrClientInterceptor.java | 66 +++++++---------- .../solrj/SolrConnectorInterceptor.java | 7 -- .../apm/plugin/solrj/commons/Context.java | 70 ------------------- .../apm/plugin/solrj/commons/SolrjTags.java | 54 ++++---------- 4 files changed, 37 insertions(+), 160 deletions(-) delete mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java index 4649e53ae022..ed6c97b841c0 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -25,7 +25,6 @@ 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.solrj.commons.Context; import org.apache.skywalking.apm.plugin.solrj.commons.SolrjInstance; import org.apache.skywalking.apm.plugin.solrj.commons.SolrjTags; import org.apache.solr.client.solrj.SolrRequest; @@ -87,56 +86,50 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr UpdateRequest ur = (UpdateRequest) update; List documents = ur.getDocuments(); if (documents == null) { - actionName = "DELETE"; + actionName = "DELETE_BY_IDS"; - span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); List deleteBy = ur.getDeleteById(); - if (deleteBy != null && !deleteBy.isEmpty()) { - span.tag(SolrjTags.TAG_DELETE_TYPE, "deleteByIds"); - span.tag(SolrjTags.TAG_DELETE_VALUE, deleteBy.toString()); + if (deleteBy == null) { + actionName = "DELETE_BY_QUERY"; + deleteBy = ur.getDeleteQuery(); } - List deleteQuery = ur.getDeleteQuery(); - if (deleteQuery != null && !deleteQuery.isEmpty()) { - span.tag(SolrjTags.TAG_DELETE_TYPE, "deleteByQuery"); - span.tag(SolrjTags.TAG_DELETE_VALUE, deleteQuery.toString()); + if (deleteBy != null) { + span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); + span.tag(SolrjTags.TAG_DELETE_VALUE, deleteBy.toString()); } } else { span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); span.tag(SolrjTags.TAG_DOCS_SIZE, String.valueOf(documents.size())); span.tag(SolrjTags.TAG_COMMIT_WITHIN, String.valueOf(update.getCommitWithin())); } + } else { + span = getSpan(collection, request.getPath(), "", instance.getRemotePeer()); } } else { actionName = action.name(); if (action == AbstractUpdateRequest.ACTION.COMMIT) { span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); - - span.tag(SolrjTags.TAG_COMMIT, "true"); span.tag(SolrjTags.TAG_SOFT_COMMIT, params.get(UpdateParams.SOFT_COMMIT, "")); } else { span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); - - span.tag(SolrjTags.TAG_OPTIMIZE, "true"); span.tag(SolrjTags.TAG_MAX_OPTIMIZE_SEGMENTS, params.get(UpdateParams.MAX_OPTIMIZE_SEGMENTS, "1")); } } - span.tag(SolrjTags.TAG_ACTION, actionName); } else if (request instanceof QueryRequest) { String operatorName = String.format("solrJ/%s%s", collection, request.getPath()); span = ContextManager.createExitSpan(operatorName, instance.getRemotePeer()) .setComponent(ComponentsDefine.SOLRJ) .setLayer(SpanLayer.DB); + + span.tag(SolrjTags.TAG_SORT_BY, params.get(CommonParams.SORT, "")); + span.tag(SolrjTags.TAG_START, params.get(CommonParams.START, "0")); + span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, request.getPath())); } if (null == span) return; - span.tag(SolrjTags.TAG_PATH, request.getPath()); span.tag(SolrjTags.TAG_COLLECTION, collection); - span.tag(SolrjTags.TAG_METHOD, request.getMethod().name()); - span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, request.getPath())); - - ContextManager.getRuntimeContext().put("context", new Context()); } @Override @@ -145,29 +138,20 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA Class[] argumentsTypes, Object ret) throws Throwable { if (!ContextManager.isActive()) return ret; - try { - final Context context = ContextManager.getRuntimeContext().get("context", Context.class); - final long elapse = System.currentTimeMillis() - context.getStartTime(); - - AbstractSpan span = ContextManager.activeSpan(); - NamedList response = (NamedList) ret; - if (response != null) { - NamedList header = (NamedList) response.get("responseHeader"); - if (header != null) { - span.tag(SolrjTags.TAG_STATUS, String.valueOf(header.get("status"))); - span.tag(SolrjTags.TAG_Q_TIME, String.valueOf(header.get("QTime"))); - } - SolrDocumentList list = (SolrDocumentList) response.get("response"); - if (list != null) { - span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); - } + AbstractSpan span = ContextManager.activeSpan(); + NamedList response = (NamedList) ret; + if (response != null) { + NamedList header = (NamedList) response.get("responseHeader"); + if (header != null) { + span.tag(SolrjTags.TAG_STATUS, String.valueOf(header.get("status"))); + span.tag(SolrjTags.TAG_Q_TIME, String.valueOf(header.get("QTime"))); + } + SolrDocumentList list = (SolrDocumentList) response.get("response"); + if (list != null) { + span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); } - SolrjTags.addHttpResponse(span, context); - SolrjTags.addElapseTime(span, elapse); - } finally { - ContextManager.stopSpan(); - ContextManager.getRuntimeContext().remove("context"); } + ContextManager.stopSpan(); return ret; } 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 index 14536ac33de5..d6c00b566265 100644 --- 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 @@ -17,7 +17,6 @@ */ package org.apache.skywalking.apm.plugin.solrj; -import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpUriRequest; import org.apache.skywalking.apm.agent.core.context.CarrierItem; import org.apache.skywalking.apm.agent.core.context.ContextCarrier; @@ -25,7 +24,6 @@ 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.solrj.commons.Context; import java.lang.reflect.Method; @@ -49,11 +47,6 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { - if (ContextManager.isActive()) { - CloseableHttpResponse response = (CloseableHttpResponse) ret; - Context context = ContextManager.getRuntimeContext().get("context", Context.class); - context.withHttpResponse(response.getStatusLine().getStatusCode(), response.getEntity()); - } return ret; } diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java deleted file mode 100644 index ce9241bc9482..000000000000 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/commons/Context.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -package org.apache.skywalking.apm.plugin.solrj.commons; - -import org.apache.http.Header; -import org.apache.http.HttpEntity; - -public class Context { - private long contentLength = 0; - private String contentType = ""; - private String contentEncoding = ""; - private int statusCode = -1; - - private long startTime = 0; - - public Context() { - startTime = System.currentTimeMillis(); - } - - public final void withHttpResponse(int statusCode, HttpEntity entity) { - Header header = null; - header = entity.getContentEncoding(); - if (header != null) { - this.contentEncoding = header.toString(); - } - header = entity.getContentType(); - if (header != null) { - this.contentType = header.toString(); - } - - this.statusCode = statusCode; - this.contentLength = entity.getContentLength(); - } - - public long getContentLength() { - return contentLength; - } - - public String getContentType() { - return contentType; - } - - public String getContentEncoding() { - return contentEncoding; - } - - public int getStatusCode() { - return statusCode; - } - - public long getStartTime() { - return startTime; - } -} 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 index 39637cdac752..3040b850b529 100644 --- 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 @@ -18,52 +18,22 @@ package org.apache.skywalking.apm.plugin.solrj.commons; import org.apache.skywalking.apm.agent.core.context.tag.StringTag; -import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; public class SolrjTags { + public static StringTag TAG_QT = new StringTag("qt"); + public static StringTag TAG_COLLECTION = new StringTag("collection"); - // public static StringTag DB_TYPE = new StringTag(1, "db.type"); - public static StringTag TAG_QT = new StringTag(1,"qt"); - public static StringTag TAG_PATH = new StringTag(2, "path"); - public static StringTag TAG_COLLECTION = new StringTag(3, "collection"); - public static StringTag TAG_ACTION = new StringTag(4, "action"); - public static StringTag TAG_METHOD = new StringTag(5, "method"); - public static StringTag TAG_COMMIT_WITHIN = new StringTag(6, "commitWithin"); - public static StringTag TAG_STATUS = new StringTag(7, "status"); - public static StringTag TAG_Q_TIME = new StringTag(8, "QTime"); - public static StringTag TAG_NUM_FOUND = new StringTag(9, "numFound"); + 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_STATUS_CODE = new StringTag(10, "statusCode"); - public static StringTag TAG_ELAPSE_TIME = new StringTag(11, "elapseTime"); - - public static StringTag TAG_CONTENT_TYPE = new StringTag(12, "contentType"); - public static StringTag TAG_CONTENT_LENGTH = new StringTag(13, "contentLength"); - public static StringTag TAG_CONTENT_ENCODING = new StringTag(14, "contentEncoding"); - - public static StringTag TAG_COMMIT = new StringTag(15, "commit"); - public static StringTag TAG_SOFT_COMMIT = new StringTag(16, "softCommit"); - - public static StringTag TAG_OPTIMIZE = new StringTag(17, "optimize"); - public static StringTag TAG_MAX_OPTIMIZE_SEGMENTS = new StringTag(18, "maxOptimizeSegs"); - - public static StringTag TAG_DELETE_TYPE = new StringTag(19, "delete.type"); - public static StringTag TAG_DELETE_VALUE = new StringTag(20, "delete.by"); - public static StringTag TAG_DOCS_SIZE = new StringTag(21, "docsSize"); - - - public static void addElapseTime(AbstractSpan span, long eTime) { - span.tag(TAG_ELAPSE_TIME, Long.toString(eTime)); - } - - public static void addHttpResponse(AbstractSpan span, Context context) { - span.tag(TAG_CONTENT_TYPE, context.getContentType()); - span.tag(TAG_CONTENT_ENCODING, context.getContentEncoding()); - - span.tag(TAG_STATUS_CODE, Integer.toString(context.getStatusCode())); - span.tag(TAG_CONTENT_LENGTH, Long.toString(context.getContentLength())); - } - - + public static StringTag TAG_DOCS_SIZE = new StringTag("docsSize"); + public static StringTag TAG_DELETE_VALUE = new StringTag("delete.by"); } From aa68f8299d863d1d192fe96b1ee1325d48dccfe4 Mon Sep 17 00:00:00 2001 From: daming Date: Mon, 27 May 2019 22:29:16 +0800 Subject: [PATCH 14/20] add test cases --- .../solrj/SolrClientInterceptorTest.java | 368 ++++++++++++++++++ 1 file changed, 368 insertions(+) create mode 100644 apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptorTest.java 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..5764b6f1a665 --- /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,368 @@ +/* + * 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.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.SolrDocument; +import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.SolrInputDocument; +import org.apache.solr.common.StringUtils; +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 header; + + @Before + public void setup() throws Exception { + builder = new HttpSolrClient.Builder().withBaseSolrUrl("http://solr-server:8983/solr/collection"); + enhancedInstance = new EnhanceHttpSolrClient(builder); + + when(instance.getCollection()).thenReturn("collection"); + when(instance.getRemotePeer()).thenReturn("solr-server:8983"); + enhancedInstance.setSkyWalkingDynamicField(instance); + + header = new NamedList(); + header.add("status", 0); + header.add("QTime", 5); + } + + + @Test + public void testConstructor() throws Throwable { + arguments = new Object[] { builder }; + interceptor.onConstruct(enhancedInstance, arguments); + SolrjInstance instance = (SolrjInstance) enhancedInstance.getSkyWalkingDynamicField(); + Assert.assertEquals(instance.getRemotePeer(), "solr-server:8983"); + Assert.assertEquals(instance.getCollection(), "collection"); + } + + + @Test + public void testUpdateWithAdd() throws Throwable { + UpdateRequest request = new UpdateRequest(); + List docs = Lists.newArrayList(); + for (int start=0; start<100; start++) { + SolrInputDocument doc = new SolrInputDocument(); + doc.addField("id", start); + docs.add(doc); + } + arguments = new Object[] { + request.add(docs), + null, + collection + }; + interceptor.beforeMethod(enhancedInstance, method, arguments, argumentType, null); + interceptor.afterMethod(enhancedInstance, method, arguments, argumentType, getResponse()); + + List segments = segmentStorage.getTraceSegments(); + Assert.assertEquals(segments.size(), 1); + + List spans = SegmentHelper.getSpans(segments.get(0)); + Assert.assertEquals(spans.size(), 1); + + AbstractTracingSpan span = spans.get(0); + SpanAssert.assertTag(span, 0, "100"); + SpanAssert.assertTag(span, 1, "-1"); + spanCommonAssert(span, 2,"solrJ/collection/update/ADD"); + } + + @Test + public void testUpdateWithCommit() throws Throwable { + final boolean softCommit = false; + AbstractUpdateRequest request = (new UpdateRequest()).setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true, false); + arguments = new Object[]{ + request, + null, + collection + }; + interceptor.beforeMethod(enhancedInstance, method, arguments, argumentType, null); + interceptor.afterMethod(enhancedInstance, method, arguments, argumentType, getResponse()); + + List segments = segmentStorage.getTraceSegments(); + Assert.assertEquals(segments.size(), 1); + + List spans = SegmentHelper.getSpans(segments.get(0)); + Assert.assertEquals(spans.size(), 1); + + AbstractTracingSpan span = spans.get(0); + SpanAssert.assertTag(span, 0, String.valueOf(softCommit)); + spanCommonAssert(span, 1, "solrJ/collection/update/COMMIT"); + } + + @Test + public void testUpdateWithOptimize() throws Throwable { + final int maxSegments = 1; + AbstractUpdateRequest request = (new UpdateRequest()).setAction(AbstractUpdateRequest.ACTION.OPTIMIZE, false, true, maxSegments); + arguments = new Object[]{ + request, + null, + collection + }; + interceptor.beforeMethod(enhancedInstance, method, arguments, argumentType, null); + interceptor.afterMethod(enhancedInstance, method, arguments, argumentType, getResponse()); + + List segments = segmentStorage.getTraceSegments(); + List spans = SegmentHelper.getSpans(segments.get(0)); + + Assert.assertEquals(segments.size(), 1); + Assert.assertEquals(spans.size(), 1); + + AbstractTracingSpan span = spans.get(0); + SpanAssert.assertTag(span, 0, String.valueOf(maxSegments)); + spanCommonAssert(span, 1, "solrJ/collection/update/OPTIMIZE"); + } + + @Test + public void testQuery() throws Throwable { + QueryRequest request = new QueryRequest(); + arguments = new Object[] { + request, + null, + collection + }; + interceptor.beforeMethod(enhancedInstance, method, arguments, argumentType, null); + interceptor.afterMethod(enhancedInstance, method, arguments, argumentType, getQueryResponse()); + + List segments = segmentStorage.getTraceSegments(); + List spans = SegmentHelper.getSpans(segments.get(0)); + + Assert.assertEquals(segments.size(), 1); + Assert.assertEquals(spans.size(), 1); + + AbstractTracingSpan span = spans.get(0); + querySpanAssert(span, "/select", 100); + spanCommonAssert(span, 3, "solrJ/collection/select"); + } + + @Test + public void testGet() throws Throwable { + ModifiableSolrParams reqParams = new ModifiableSolrParams(); + if (StringUtils.isEmpty(reqParams.get("qt"))) { + reqParams.set("qt", new String[]{"/get"}); + } + reqParams.set("ids", new String[] {"99", "98"}); + QueryRequest request = new QueryRequest(reqParams); + + arguments = new Object[] { + request, + null, + collection + }; + interceptor.beforeMethod(enhancedInstance, method, arguments, argumentType, null); + interceptor.afterMethod(enhancedInstance, method, arguments, argumentType, getGetResponse()); + + List segments = segmentStorage.getTraceSegments(); + List spans = SegmentHelper.getSpans(segments.get(0)); + Assert.assertEquals(segments.size(), 1); + Assert.assertEquals(spans.size(), 1); + + AbstractTracingSpan span = spans.get(0); + querySpanAssert(span, "/get", 1); + spanCommonAssert(span, 3, "solrJ/collection/get"); + } + + @Test + public void testDeleteById() throws Throwable { + UpdateRequest request = new UpdateRequest(); + arguments = new Object[] { + request.deleteById("12"), + null, + collection + }; + interceptor.beforeMethod(enhancedInstance, method, arguments, argumentType, null); + interceptor.afterMethod(enhancedInstance, method, arguments, argumentType, getResponse()); + + List segments = segmentStorage.getTraceSegments(); + List spans = SegmentHelper.getSpans(segments.get(0)); + + Assert.assertEquals(segments.size(), 1); + Assert.assertEquals(spans.size(), 1); + + AbstractTracingSpan span = spans.get(0); + SpanAssert.assertTag(span, 0, "[12]"); + spanCommonAssert(span, 1, "solrJ/collection/update/DELETE_BY_IDS"); + } + + @Test + public void testDeleteByQuery() throws Throwable { + UpdateRequest request = new UpdateRequest(); + arguments = new Object[] { + request.deleteByQuery("id:[2 TO 5]"), + null, + collection + }; + interceptor.beforeMethod(enhancedInstance, method, arguments, argumentType, null); + interceptor.afterMethod(enhancedInstance, method, arguments, argumentType, getResponse()); + + List segments = segmentStorage.getTraceSegments(); + List spans = SegmentHelper.getSpans(segments.get(0)); + + Assert.assertEquals(segments.size(), 1); + Assert.assertEquals(spans.size(), 1); + + AbstractTracingSpan span = spans.get(0); + SpanAssert.assertTag(span, 0, "[id:[2 TO 5]]"); + spanCommonAssert(span, 1,"solrJ/collection/update/DELETE_BY_QUERY"); + } + + private void SegmentCommonAssert(List segments) { + Assert.assertEquals(segments.size(), 1); + TraceSegment segment = segments.get(0); + } + + private void querySpanAssert(AbstractSpan span, String qt, int numFound) { + SpanAssert.assertTag(span, 0, ""); + SpanAssert.assertTag(span, 1, "0"); + SpanAssert.assertTag(span, 2, qt); + SpanAssert.assertTag(span, 6, String.valueOf(numFound)); + SpanAssert.assertTagSize(span, 7); + } + + private void spanCommonAssert(AbstractSpan span, int start, String operationName) { + SpanAssert.assertComponent(span, ComponentsDefine.SOLRJ); + SpanAssert.assertOccurException(span, false); + SpanAssert.assertLogSize(span, 0); + SpanAssert.assertLayer(span, SpanLayer.DB); + + SpanAssert.assertTag(span, start, "collection"); + SpanAssert.assertTag(span, start + 1, "0"); + SpanAssert.assertTag(span, start + 2, "5"); + + Assert.assertEquals(span.getOperationName(), operationName); + } + + private NamedList getResponse() { + NamedList response = new NamedList(); + response.add("responseHeader", header); + return response; + } + + private NamedList getQueryResponse() { + NamedList response = new NamedList(); + response.add("responseHeader", header); + SolrDocumentList list = new SolrDocumentList(); + list.setStart(0); + list.setNumFound(100); + list.setMaxScore(.0f); + + for (int start=0; start<10; start++) { + SolrDocument doc = new SolrDocument(); + doc.addField("id", start); + doc.addField("_version", 1634676349644832768L); + list.add(doc); + } + response.add("response", list); + return response; + } + + private NamedList getGetResponse() { + NamedList response = new NamedList(); + response.add("responseHeader", header); + SolrDocumentList list = new SolrDocumentList(); + list.setStart(0); + list.setNumFound(1); + list.setMaxScore(.0f); + + SolrDocument doc = new SolrDocument(); + doc.addField("id", 1); + doc.addField("_version", 1634676349644832768L); + list.add(doc); + + response.add("response", list); + return response; + } + + class EnhanceHttpSolrClient extends HttpSolrClient implements EnhancedInstance { + Object value = null; + + protected EnhanceHttpSolrClient(Builder builder) { + super(builder); + } + + @Override + public Object getSkyWalkingDynamicField() { + return value; + } + + @Override + public void setSkyWalkingDynamicField(Object value) { + this.value = value; + } + } + +} \ No newline at end of file From 447da95848f5b09cbe9b8dbd5aad90f47fd315cb Mon Sep 17 00:00:00 2001 From: daming Date: Tue, 28 May 2019 01:59:22 +0800 Subject: [PATCH 15/20] fix validation fail --- .../apm/plugin/solrj/SolrClientInterceptorTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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 index 5764b6f1a665..77a2f4c7a39c 100644 --- 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 @@ -104,7 +104,7 @@ public void setup() throws Exception { @Test public void testConstructor() throws Throwable { - arguments = new Object[] { builder }; + arguments = new Object[] {builder}; interceptor.onConstruct(enhancedInstance, arguments); SolrjInstance instance = (SolrjInstance) enhancedInstance.getSkyWalkingDynamicField(); Assert.assertEquals(instance.getRemotePeer(), "solr-server:8983"); @@ -116,7 +116,7 @@ public void testConstructor() throws Throwable { public void testUpdateWithAdd() throws Throwable { UpdateRequest request = new UpdateRequest(); List docs = Lists.newArrayList(); - for (int start=0; start<100; start++) { + for (int start = 0; start < 100; start++) { SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", start); docs.add(doc); @@ -320,7 +320,7 @@ private NamedList getQueryResponse() { list.setNumFound(100); list.setMaxScore(.0f); - for (int start=0; start<10; start++) { + for (int start = 0; start < 10; start++) { SolrDocument doc = new SolrDocument(); doc.addField("id", start); doc.addField("_version", 1634676349644832768L); From 2404c78e4edcc4441f14c0e62e0789a8e21ee12a Mon Sep 17 00:00:00 2001 From: daming Date: Tue, 28 May 2019 22:20:04 +0800 Subject: [PATCH 16/20] add solrj-plugin into component-libraries & Supported-list --- docs/en/setup/service-agent/java-agent/Supported-list.md | 1 + .../server-core/src/test/resources/component-libraries.yml | 7 +++++++ .../src/main/resources/component-libraries.yml | 7 +++++++ 3 files changed, 15 insertions(+) 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 ee6a003cf6f2..aab08c89e58b 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -53,6 +53,7 @@ * [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 + * [SolrJ](https://lucene.apache.org/solr) 7.0.0-7.7.1 * Service Discovery * [Netflix Eureka](https://github.com/Netflix/eureka) * Distributed Coordination diff --git a/oap-server/server-core/src/test/resources/component-libraries.yml b/oap-server/server-core/src/test/resources/component-libraries.yml index 97733d80264d..86d29e520613 100644 --- a/oap-server/server-core/src/test/resources/component-libraries.yml +++ b/oap-server/server-core/src/test/resources/component-libraries.yml @@ -198,6 +198,12 @@ spring-cloud-gateway: RESTEasy: id: 62 languages: Java +SolrJ: + id: 63 + languages: Java +Solr: + id: 64 + languages: Java # .NET/.NET Core components # [3000, 4000) for C#/.NET only @@ -295,3 +301,4 @@ Component-Server-Mappings: Pomelo.EntityFrameworkCore.MySql: Mysql Npgsql.EntityFrameworkCore.PostgreSQL: PostgreSQL transport-client: Elasticsearch + SolrJ: Solr diff --git a/oap-server/server-starter/src/main/resources/component-libraries.yml b/oap-server/server-starter/src/main/resources/component-libraries.yml index 4d9598842b57..87e213f1ad7e 100644 --- a/oap-server/server-starter/src/main/resources/component-libraries.yml +++ b/oap-server/server-starter/src/main/resources/component-libraries.yml @@ -216,6 +216,12 @@ spring-cloud-gateway: RESTEasy: id: 62 languages: Java +SolrJ: + id: 63 + languages: Java +Solr: + id: 64 + languages: Java # .NET/.NET Core components # [3000, 4000) for C#/.NET only @@ -315,3 +321,4 @@ Component-Server-Mappings: Pomelo.EntityFrameworkCore.MySql: Mysql Npgsql.EntityFrameworkCore.PostgreSQL: PostgreSQL transport-client: Elasticsearch + SolrJ: Solr From d3ce6413e8719807633dd4c62d214069c75a799f Mon Sep 17 00:00:00 2001 From: daming Date: Wed, 29 May 2019 17:21:20 +0800 Subject: [PATCH 17/20] to trace all patch to avoid recheck status of span --- .../plugin/solrj/SolrClientInterceptor.java | 51 ++++++++++--------- 1 file changed, 28 insertions(+), 23 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java index ed6c97b841c0..0f46738eef2f 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -43,6 +43,7 @@ import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; +import java.util.ArrayList; import java.util.List; public class SolrClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { @@ -79,56 +80,50 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr if ("/update".equals(request.getPath())) { AbstractUpdateRequest update = (AbstractUpdateRequest) request; - String actionName = "ADD"; AbstractUpdateRequest.ACTION action = update.getAction(); if (action == null) { if (update instanceof UpdateRequest) { UpdateRequest ur = (UpdateRequest) update; List documents = ur.getDocuments(); if (documents == null) { - actionName = "DELETE_BY_IDS"; + String actionName = "DELETE_BY_IDS"; List deleteBy = ur.getDeleteById(); if (deleteBy == null) { actionName = "DELETE_BY_QUERY"; deleteBy = ur.getDeleteQuery(); } - if (deleteBy != null) { - span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); - span.tag(SolrjTags.TAG_DELETE_VALUE, deleteBy.toString()); + if (deleteBy == null) { + deleteBy = new ArrayList(); } - } else { span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); + span.tag(SolrjTags.TAG_DELETE_VALUE, deleteBy.toString()); + } else { + span = getSpan(collection, request.getPath(), "ADD", instance.getRemotePeer()); span.tag(SolrjTags.TAG_DOCS_SIZE, String.valueOf(documents.size())); span.tag(SolrjTags.TAG_COMMIT_WITHIN, String.valueOf(update.getCommitWithin())); } } else { - span = getSpan(collection, request.getPath(), "", instance.getRemotePeer()); + span = getSpan(collection, request.getPath(), instance.getRemotePeer()); } } else { - actionName = action.name(); if (action == AbstractUpdateRequest.ACTION.COMMIT) { - span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); + span = getSpan(collection, request.getPath(), action.name(), instance.getRemotePeer()); span.tag(SolrjTags.TAG_SOFT_COMMIT, params.get(UpdateParams.SOFT_COMMIT, "")); } else { - span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); + span = getSpan(collection, request.getPath(), action.name(), instance.getRemotePeer()); span.tag(SolrjTags.TAG_MAX_OPTIMIZE_SEGMENTS, params.get(UpdateParams.MAX_OPTIMIZE_SEGMENTS, "1")); } } } else if (request instanceof QueryRequest) { - String operatorName = String.format("solrJ/%s%s", collection, request.getPath()); - span = ContextManager.createExitSpan(operatorName, instance.getRemotePeer()) - .setComponent(ComponentsDefine.SOLRJ) - .setLayer(SpanLayer.DB); + span = getSpan(collection, request.getPath(), instance.getRemotePeer()); span.tag(SolrjTags.TAG_SORT_BY, params.get(CommonParams.SORT, "")); span.tag(SolrjTags.TAG_START, params.get(CommonParams.START, "0")); span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, request.getPath())); + } else { + span = getSpan(collection, request.getPath(), instance.getRemotePeer()); } - - if (null == span) - return; - span.tag(SolrjTags.TAG_COLLECTION, collection); } @@ -136,21 +131,24 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr @SuppressWarnings("unchecked") public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { - if (!ContextManager.isActive()) return ret; + if (!ContextManager.isActive()) { + return ret; + } AbstractSpan span = ContextManager.activeSpan(); - NamedList response = (NamedList) ret; - if (response != null) { - NamedList header = (NamedList) response.get("responseHeader"); + NamedList result = (NamedList) ret; + if (result != null) { + NamedList header = (NamedList) result.get("responseHeader"); if (header != null) { span.tag(SolrjTags.TAG_STATUS, String.valueOf(header.get("status"))); span.tag(SolrjTags.TAG_Q_TIME, String.valueOf(header.get("QTime"))); } - SolrDocumentList list = (SolrDocumentList) response.get("response"); + SolrDocumentList list = (SolrDocumentList) result.get("response"); if (list != null) { span.tag(SolrjTags.TAG_NUM_FOUND, String.valueOf(list.getNumFound())); } } + ContextManager.stopSpan(); return ret; } @@ -169,6 +167,13 @@ private static final AbstractSpan getSpan(String collection, String path, String .setLayer(SpanLayer.DB); } + private static final AbstractSpan getSpan(String collection, String path, String remotePeer) { + String operatorName = String.format("solrJ/%s%s", collection, path); + return ContextManager.createExitSpan(operatorName, remotePeer) + .setComponent(ComponentsDefine.SOLRJ) + .setLayer(SpanLayer.DB); + } + private static final String getCollection(SolrjInstance instance, Object argument) { if (null == argument) { return instance.getCollection(); From 57d76d37d4c27ffa7fd788d24cdc81d9d189bc4c Mon Sep 17 00:00:00 2001 From: daming Date: Fri, 31 May 2019 14:02:07 +0800 Subject: [PATCH 18/20] remove unnecessary properites --- apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml | 3 --- 1 file changed, 3 deletions(-) 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 index f94a053bbf04..31b931ade3bb 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/pom.xml @@ -32,9 +32,6 @@ UTF-8 - 1.6 - ${java.version} - ${java.version} 7.7.1 From a310a945ebca984cf6e7c3f0a05c851363e789aa Mon Sep 17 00:00:00 2001 From: daming Date: Mon, 3 Jun 2019 19:24:52 +0800 Subject: [PATCH 19/20] remove unnecessary tags --- .../apm/agent/core/conf/Config.java | 12 ++ .../plugin/solrj/SolrClientInterceptor.java | 97 ++++++++++----- .../solrj/SolrClientInterceptorTest.java | 116 +++++++++++++----- 3 files changed, 168 insertions(+), 57 deletions(-) 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..a1e4f81dccc3 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,17 @@ 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/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java index 0f46738eef2f..5c4d69a22bfb 100644 --- a/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/solrj-7.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/solrj/SolrClientInterceptor.java @@ -17,7 +17,9 @@ */ package org.apache.skywalking.apm.plugin.solrj; +import org.apache.skywalking.apm.agent.core.conf.Config; import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; @@ -33,6 +35,7 @@ import org.apache.solr.client.solrj.request.QueryRequest; import org.apache.solr.client.solrj.request.UpdateRequest; import org.apache.solr.common.SolrDocumentList; +import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.CommonParams; import org.apache.solr.common.params.ModifiableSolrParams; @@ -44,9 +47,11 @@ import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; public class SolrClientInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { + private static final String DB_TYPE = "Solr"; @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { @@ -76,13 +81,14 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr SolrParams params = getParams(request.getParams()); String collection = getCollection(instance, allArguments[2]); - AbstractSpan span = null; if ("/update".equals(request.getPath())) { AbstractUpdateRequest update = (AbstractUpdateRequest) request; AbstractUpdateRequest.ACTION action = update.getAction(); if (action == null) { if (update instanceof UpdateRequest) { + AbstractSpan span = null; + UpdateRequest ur = (UpdateRequest) update; List documents = ur.getDocuments(); if (documents == null) { @@ -96,35 +102,48 @@ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allAr if (deleteBy == null) { deleteBy = new ArrayList(); } - span = getSpan(collection, request.getPath(), actionName, instance.getRemotePeer()); - span.tag(SolrjTags.TAG_DELETE_VALUE, deleteBy.toString()); + String operator = getOperatorNameWithAction(collection, request.getPath(), actionName); + span = getSpan(operator, instance.getRemotePeer()); + if (Config.Plugin.SolrJ.TRACE_STATEMENT) { + span.tag(Tags.DB_STATEMENT, deleteBy.toString()); + } } else { - span = getSpan(collection, request.getPath(), "ADD", instance.getRemotePeer()); - span.tag(SolrjTags.TAG_DOCS_SIZE, String.valueOf(documents.size())); - span.tag(SolrjTags.TAG_COMMIT_WITHIN, String.valueOf(update.getCommitWithin())); + String operator = getOperatorNameWithAction(collection, request.getPath(), "ADD"); + span = getSpan(operator, instance.getRemotePeer()); + if (Config.Plugin.SolrJ.TRACE_STATEMENT) { + span.tag(SolrjTags.TAG_DOCS_SIZE, String.valueOf(documents.size())); + } + } + if (Config.Plugin.SolrJ.TRACE_OPS_PARAMS) { + span.tag(SolrjTags.TAG_COMMIT_WITHIN, String.valueOf(ur.getCommitWithin())); } } else { - span = getSpan(collection, request.getPath(), instance.getRemotePeer()); + getSpan(getOperatorName(collection, request.getPath()), instance.getRemotePeer()); } } else { - if (action == AbstractUpdateRequest.ACTION.COMMIT) { - span = getSpan(collection, request.getPath(), action.name(), instance.getRemotePeer()); - span.tag(SolrjTags.TAG_SOFT_COMMIT, params.get(UpdateParams.SOFT_COMMIT, "")); - } else { - span = getSpan(collection, request.getPath(), action.name(), instance.getRemotePeer()); - span.tag(SolrjTags.TAG_MAX_OPTIMIZE_SEGMENTS, params.get(UpdateParams.MAX_OPTIMIZE_SEGMENTS, "1")); + String operator = getOperatorNameWithAction(collection, request.getPath(), action.name()); + AbstractSpan span = getSpan(operator, instance.getRemotePeer()); + + if (Config.Plugin.SolrJ.TRACE_OPS_PARAMS) { + if (action == AbstractUpdateRequest.ACTION.COMMIT) { + span.tag(SolrjTags.TAG_SOFT_COMMIT, params.get(UpdateParams.SOFT_COMMIT, "")); + } else { + span.tag(SolrjTags.TAG_MAX_OPTIMIZE_SEGMENTS, params.get(UpdateParams.MAX_OPTIMIZE_SEGMENTS, "1")); + } } } } else if (request instanceof QueryRequest) { - span = getSpan(collection, request.getPath(), instance.getRemotePeer()); + AbstractSpan span = getSpan(getOperatorName(collection, request.getPath()), instance.getRemotePeer()); - span.tag(SolrjTags.TAG_SORT_BY, params.get(CommonParams.SORT, "")); span.tag(SolrjTags.TAG_START, params.get(CommonParams.START, "0")); span.tag(SolrjTags.TAG_QT, params.get(CommonParams.QT, request.getPath())); + + if (Config.Plugin.SolrJ.TRACE_STATEMENT) { + span.tag(Tags.DB_STATEMENT, toQueryString(params)); + } } else { - span = getSpan(collection, request.getPath(), instance.getRemotePeer()); + getSpan(getOperatorName(collection, request.getPath()), instance.getRemotePeer()); } - span.tag(SolrjTags.TAG_COLLECTION, collection); } @Override @@ -136,11 +155,11 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA } AbstractSpan span = ContextManager.activeSpan(); - NamedList result = (NamedList) ret; - if (result != null) { + if (ret != null) { + NamedList result = (NamedList) ret; NamedList header = (NamedList) result.get("responseHeader"); + if (header != null) { - span.tag(SolrjTags.TAG_STATUS, String.valueOf(header.get("status"))); span.tag(SolrjTags.TAG_Q_TIME, String.valueOf(header.get("QTime"))); } SolrDocumentList list = (SolrDocumentList) result.get("response"); @@ -156,22 +175,29 @@ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allA @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { if (ContextManager.isActive()) { - ContextManager.activeSpan().errorOccurred().log(t); + AbstractSpan span = ContextManager.activeSpan(); + int code = 500; + if (t instanceof SolrException) { + code = ((SolrException) t).code(); + } + span.tag(SolrjTags.TAG_STATUS, String.valueOf(code)); + span.errorOccurred().log(t); } } - private static final AbstractSpan getSpan(String collection, String path, String action, String remotePeer) { - String operatorName = String.format("solrJ/%s%s/%s", collection, path, action); + private static final AbstractSpan getSpan(String operatorName, String remotePeer) { return ContextManager.createExitSpan(operatorName, remotePeer) .setComponent(ComponentsDefine.SOLRJ) - .setLayer(SpanLayer.DB); + .setLayer(SpanLayer.DB) + .tag(Tags.DB_TYPE, DB_TYPE); } - private static final AbstractSpan getSpan(String collection, String path, String remotePeer) { - String operatorName = String.format("solrJ/%s%s", collection, path); - return ContextManager.createExitSpan(operatorName, remotePeer) - .setComponent(ComponentsDefine.SOLRJ) - .setLayer(SpanLayer.DB); + private static final String getOperatorNameWithAction(String collection, String path, String action) { + return String.format("solrJ/%s%s/%s", collection, path, action); + } + + private static final String getOperatorName(String collection, String path) { + return String.format("solrJ/%s%s", collection, path); } private static final String getCollection(SolrjInstance instance, Object argument) { @@ -187,4 +213,17 @@ private static final SolrParams getParams(SolrParams params) { } return params; } + + private static final String toQueryString(SolrParams params) { + final StringBuilder sb = new StringBuilder(128); + boolean first = true; + for (final Iterator it = params.getParameterNamesIterator(); it.hasNext();) { + final String name = it.next(); + for (String val : params.getParams(name)) { + sb.append(first ? '?' : '&').append(name).append('=').append(val); + first = false; + } + } + return sb.toString(); + } } 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 index 77a2f4c7a39c..c7311a8c6b88 100644 --- 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 @@ -19,6 +19,7 @@ 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; @@ -34,10 +35,7 @@ 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.SolrDocument; -import org.apache.solr.common.SolrDocumentList; -import org.apache.solr.common.SolrInputDocument; -import org.apache.solr.common.StringUtils; +import org.apache.solr.common.*; import org.apache.solr.common.params.ModifiableSolrParams; import org.apache.solr.common.util.NamedList; import org.junit.Assert; @@ -99,6 +97,9 @@ public void setup() throws Exception { header = new NamedList(); header.add("status", 0); header.add("QTime", 5); + +// Config.Plugin.SolrJ.TRACE_STATEMENT = true; +// Config.Plugin.SolrJ.TRACE_OPS_PARAMS = true; } @@ -136,9 +137,14 @@ public void testUpdateWithAdd() throws Throwable { Assert.assertEquals(spans.size(), 1); AbstractTracingSpan span = spans.get(0); - SpanAssert.assertTag(span, 0, "100"); - SpanAssert.assertTag(span, 1, "-1"); - spanCommonAssert(span, 2,"solrJ/collection/update/ADD"); + int pox = 0; + if (Config.Plugin.SolrJ.TRACE_STATEMENT) { + SpanAssert.assertTag(span, ++pox, "100"); + } + if (Config.Plugin.SolrJ.TRACE_OPS_PARAMS) { + SpanAssert.assertTag(span, ++pox, "-1"); + } + spanCommonAssert(span, pox,"solrJ/collection/update/ADD"); } @Test @@ -159,9 +165,12 @@ public void testUpdateWithCommit() throws Throwable { List spans = SegmentHelper.getSpans(segments.get(0)); Assert.assertEquals(spans.size(), 1); + int start = 0; AbstractTracingSpan span = spans.get(0); - SpanAssert.assertTag(span, 0, String.valueOf(softCommit)); - spanCommonAssert(span, 1, "solrJ/collection/update/COMMIT"); + if (Config.Plugin.SolrJ.TRACE_OPS_PARAMS) { + SpanAssert.assertTag(span, ++start, String.valueOf(softCommit)); + } + spanCommonAssert(span, start, "solrJ/collection/update/COMMIT"); } @Test @@ -183,8 +192,11 @@ public void testUpdateWithOptimize() throws Throwable { Assert.assertEquals(spans.size(), 1); AbstractTracingSpan span = spans.get(0); - SpanAssert.assertTag(span, 0, String.valueOf(maxSegments)); - spanCommonAssert(span, 1, "solrJ/collection/update/OPTIMIZE"); + int start = 0; + if (Config.Plugin.SolrJ.TRACE_OPS_PARAMS) { + SpanAssert.assertTag(span, ++start, String.valueOf(maxSegments)); + } + spanCommonAssert(span, start, "solrJ/collection/update/OPTIMIZE"); } @Test @@ -195,6 +207,7 @@ public void testQuery() throws Throwable { null, collection }; + interceptor.beforeMethod(enhancedInstance, method, arguments, argumentType, null); interceptor.afterMethod(enhancedInstance, method, arguments, argumentType, getQueryResponse()); @@ -205,8 +218,7 @@ public void testQuery() throws Throwable { Assert.assertEquals(spans.size(), 1); AbstractTracingSpan span = spans.get(0); - querySpanAssert(span, "/select", 100); - spanCommonAssert(span, 3, "solrJ/collection/select"); + querySpanAssert(span, "/select", 100, "solrJ/collection/select"); } @Test @@ -232,8 +244,7 @@ public void testGet() throws Throwable { Assert.assertEquals(spans.size(), 1); AbstractTracingSpan span = spans.get(0); - querySpanAssert(span, "/get", 1); - spanCommonAssert(span, 3, "solrJ/collection/get"); + querySpanAssert(span, "/get", 1, "solrJ/collection/get"); } @Test @@ -254,8 +265,7 @@ public void testDeleteById() throws Throwable { Assert.assertEquals(spans.size(), 1); AbstractTracingSpan span = spans.get(0); - SpanAssert.assertTag(span, 0, "[12]"); - spanCommonAssert(span, 1, "solrJ/collection/update/DELETE_BY_IDS"); + spanDeleteAssert(span, "solrJ/collection/update/DELETE_BY_IDS", "[12]"); } @Test @@ -276,21 +286,52 @@ public void testDeleteByQuery() throws Throwable { Assert.assertEquals(spans.size(), 1); AbstractTracingSpan span = spans.get(0); - SpanAssert.assertTag(span, 0, "[id:[2 TO 5]]"); - spanCommonAssert(span, 1,"solrJ/collection/update/DELETE_BY_QUERY"); + spanDeleteAssert(span, "solrJ/collection/update/DELETE_BY_QUERY", "[id:[2 TO 5]]"); } - private void SegmentCommonAssert(List segments) { + @Test + public void testException() throws Throwable { + QueryRequest request = new QueryRequest(); + arguments = new Object[] { + request, + null, + collection + }; + NamedList response = new NamedList(); + NamedList header = new NamedList(); + header.add("status", 500); + header.add("QTime", 5); + response.add("responseHeader", header); + + interceptor.beforeMethod(enhancedInstance, method, arguments, argumentType, null); + interceptor.handleMethodException(enhancedInstance, method, arguments, argumentType, + new SolrException(SolrException.ErrorCode.SERVER_ERROR, "for test", new Exception())); + interceptor.afterMethod(enhancedInstance, method, arguments, argumentType, response); + + List segments = segmentStorage.getTraceSegments(); + List spans = SegmentHelper.getSpans(segments.get(0)); + Assert.assertEquals(segments.size(), 1); - TraceSegment segment = segments.get(0); + Assert.assertEquals(spans.size(), 1); + + AbstractTracingSpan span = spans.get(0); + SpanAssert.assertOccurException(span, true); } - private void querySpanAssert(AbstractSpan span, String qt, int numFound) { - SpanAssert.assertTag(span, 0, ""); + + + private void querySpanAssert(AbstractSpan span, String qt, int numFound, String operationName) { + Assert.assertEquals(span.getOperationName(), operationName); + SpanAssert.assertTag(span, 0, "Solr"); SpanAssert.assertTag(span, 1, "0"); SpanAssert.assertTag(span, 2, qt); - SpanAssert.assertTag(span, 6, String.valueOf(numFound)); - SpanAssert.assertTagSize(span, 7); + + int start = 3; + if (Config.Plugin.SolrJ.TRACE_STATEMENT) { + start++; + } + SpanAssert.assertTag(span, start++, "5"); + SpanAssert.assertTag(span, start++, String.valueOf(numFound)); } private void spanCommonAssert(AbstractSpan span, int start, String operationName) { @@ -299,13 +340,32 @@ private void spanCommonAssert(AbstractSpan span, int start, String operationName SpanAssert.assertLogSize(span, 0); SpanAssert.assertLayer(span, SpanLayer.DB); - SpanAssert.assertTag(span, start, "collection"); - SpanAssert.assertTag(span, start + 1, "0"); - SpanAssert.assertTag(span, start + 2, "5"); + SpanAssert.assertTag(span, 0, "Solr"); + SpanAssert.assertTag(span, start + 1, "5"); Assert.assertEquals(span.getOperationName(), operationName); } + private void spanDeleteAssert(AbstractSpan span, String operationName, String statement) { + Assert.assertEquals(span.getOperationName(), operationName); + SpanAssert.assertComponent(span, ComponentsDefine.SOLRJ); + SpanAssert.assertOccurException(span, false); + SpanAssert.assertLogSize(span, 0); + SpanAssert.assertLayer(span, SpanLayer.DB); + + SpanAssert.assertTag(span, 0, "Solr"); + + int start = 0; + if (Config.Plugin.SolrJ.TRACE_STATEMENT) { + SpanAssert.assertTag(span, ++start, statement); + } + if (Config.Plugin.SolrJ.TRACE_OPS_PARAMS) { + SpanAssert.assertTag(span, ++start, "-1"); + } + + SpanAssert.assertTag(span, start + 1, "5"); + } + private NamedList getResponse() { NamedList response = new NamedList(); response.add("responseHeader", header); From 74b1fc79c1b3b1a082e87bc79bcfc48731a26927 Mon Sep 17 00:00:00 2001 From: daming Date: Tue, 4 Jun 2019 14:18:04 +0800 Subject: [PATCH 20/20] Add the config to document of setup --- docs/en/setup/service-agent/java-agent/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md index a14cd44b786b..9b727d5d2a24 100644 --- a/docs/en/setup/service-agent/java-agent/README.md +++ b/docs/en/setup/service-agent/java-agent/README.md @@ -82,6 +82,8 @@ property key | Description | Default | `plugin.elasticsearch.trace_dsl`|If true, trace all the DSL(Domain Specific Language) in ElasticSearch access, default is false.|`false`| `plugin.springmvc.use_qualified_name_as_endpoint_name`|If true, the fully qualified method name will be used as the endpoint name instead of the request URL, default is false.|`false`| `plugin.toolit.use_qualified_name_as_operation_name`|If true, the fully qualified method name will be used as the operation name instead of the given operation name, default is false.|`false`| +`plugin.solrj.trace_statement`|If true, trace all the query parameters(include deleteByIds and deleteByQuery) in Solr query request, default is false.|`false`| +`plugin.solrj.trace_ops_params`|If true, trace all the operation parameters in Solr request, default is false.|`false`| ## Optional Plugins Java agent plugins are all pluggable. Optional plugins could be provided in `optional-plugins` folder under agent or 3rd party repositores.