From b3959202df421c5bb82bbfc3312c4f71dc54d849 Mon Sep 17 00:00:00 2001 From: oatiz <2278966200@qq.com> Date: Wed, 22 Aug 2018 20:23:43 +0800 Subject: [PATCH] [Agent] Provide plugin for Elasticsearch 5.x (#1500) * [Agent] Provide plugin for Elasticsearch 5.x Add [Agent] Elasticsearch transport client plugin fix component name add elasticsearch component add elasticSearch component into component-libraries.yml * update support list * update PlainListenableActionFutureInterceptor.java * fix set span attributes * clear runtimeContext * remove extra plugins --- .../main/resources/component-libraries.yml | 9 +- .../trace/component/ComponentsDefine.java | 7 +- .../apm/agent/core/conf/Config.java | 5 + .../elasticsearch-5.x-plugin/pom.xml | 51 ++++++ .../v5/ActionRequestBuilderInterceptor.java | 65 ++++++++ .../plugin/elasticsearch/v5/Constants.java | 46 ++++++ .../v5/ElasticSearchEnhanceInfo.java | 98 +++++++++++ ...lainListenableActionFutureInterceptor.java | 70 ++++++++ .../TransportActionNodeProxyInterceptor.java | 77 +++++++++ .../v5/TransportProxyClientInterceptor.java | 156 ++++++++++++++++++ .../apm/plugin/elasticsearch/v5/Util.java | 35 ++++ .../ActionRequestBuilderInstrumentation.java | 64 +++++++ ...ListenableActionFutureInstrumentation.java | 73 ++++++++ ...ansportActionNodeProxyInstrumentation.java | 73 ++++++++ .../TransportProxyClientInstrumentation.java | 88 ++++++++++ .../src/main/resources/skywalking-plugin.def | 20 +++ apm-sniffer/apm-sdk-plugin/pom.xml | 1 + docs/Supported-list.md | 2 + 18 files changed, 936 insertions(+), 4 deletions(-) create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/pom.xml create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/ActionRequestBuilderInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/Constants.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/ElasticSearchEnhanceInfo.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/PlainListenableActionFutureInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/TransportActionNodeProxyInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/TransportProxyClientInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/Util.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/ActionRequestBuilderInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/PlainListenableActionFutureInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/TransportActionNodeProxyInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/TransportProxyClientInstrumentation.java create mode 100644 apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/resources/skywalking-plugin.def diff --git a/apm-collector/apm-collector-boot/src/main/resources/component-libraries.yml b/apm-collector/apm-collector-boot/src/main/resources/component-libraries.yml index 141918f988..7291c7f7e2 100644 --- a/apm-collector/apm-collector-boot/src/main/resources/component-libraries.yml +++ b/apm-collector/apm-collector-boot/src/main/resources/component-libraries.yml @@ -165,6 +165,13 @@ activemq-producer: activemq-consumer: id: 46 languages: Java +Elasticsearch: + id: 47 + languages: Java +transport-client: + id: 48 + languages: Java + # .NET/.NET Core components # [3000, 4000) for C#/.NET only AspNetCore: @@ -254,4 +261,4 @@ Component-Server-Mappings: EntityFrameworkCore.Sqlite: SQLite Pomelo.EntityFrameworkCore.MySql: Mysql Npgsql.EntityFrameworkCore.PostgreSQL: PostgreSQL - + transport-client: Elasticsearch 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 02a6730d4f..8c60442dbe 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 @@ -96,6 +96,8 @@ public class ComponentsDefine { public static final OfficialComponent ACTIVEMQ_CONSUMER = new OfficialComponent(46,"activemq-consumer"); + public static final OfficialComponent TRANSPORT_CLIENT = new OfficialComponent(48, "transport-client"); + private static ComponentsDefine INSTANCE = new ComponentsDefine(); private String[] components; @@ -105,7 +107,7 @@ public class ComponentsDefine { } public ComponentsDefine() { - components = new String[47]; + components = new String[49]; addComponent(TOMCAT); addComponent(HTTPCLIENT); addComponent(DUBBO); @@ -141,8 +143,7 @@ public class ComponentsDefine { addComponent(SOFARPC); addComponent(ACTIVEMQ_PRODUCER); addComponent(ACTIVEMQ_CONSUMER); - - + addComponent(TRANSPORT_CLIENT); } private void addComponent(OfficialComponent component) { diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java index 893d1aa923..54949e281e 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 @@ -164,5 +164,10 @@ public class Config { */ public static boolean TRACE_PARAM = false; } + + public static class Elasticsearch { + + public static boolean TRACE_DSL = false; + } } } diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/pom.xml new file mode 100644 index 0000000000..cdcab79f7a --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/pom.xml @@ -0,0 +1,51 @@ + + + + + apm-sdk-plugin + org.apache.skywalking + 5.0.0-RC-SNAPSHOT + + 4.0.0 + + apm-elasticsearch-5.x-plugin + jar + + elasticsearch-5.x-plugin + http://maven.apache.org + + + UTF-8 + 1.8 + ${java.version} + ${java.version} + + + + + org.elasticsearch.client + transport + 5.6.6 + provided + + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/ActionRequestBuilderInterceptor.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/ActionRequestBuilderInterceptor.java new file mode 100644 index 0000000000..880b364420 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/ActionRequestBuilderInterceptor.java @@ -0,0 +1,65 @@ +/* + * 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.elasticsearch.v5; + +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.InstanceConstructorInterceptor; +import org.elasticsearch.client.transport.TransportClient; + +import static org.apache.skywalking.apm.plugin.elasticsearch.v5.Constants.ES_ENHANCE_INFO; + +/** + * @author oatiz. + */ +public class ActionRequestBuilderInterceptor implements InstanceConstructorInterceptor { + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + ElasticSearchEnhanceInfo enhanceInfo = new ElasticSearchEnhanceInfo(); + + parseClientInfo(allArguments[0], enhanceInfo); + + ContextManager.getRuntimeContext().put(ES_ENHANCE_INFO, enhanceInfo); + } + + private void parseClientInfo(Object client, ElasticSearchEnhanceInfo enhanceInfo) { + + if (client instanceof TransportClient) { + TransportClient transportClient = (TransportClient) client; + + StringBuilder builder = new StringBuilder(); + for (int i = 0; i < transportClient.transportAddresses().size(); i++) { + if (i != transportClient.transportAddresses().size() - 1) { + builder.append(transportClient.transportAddresses().get(i).toString()).append(","); + } else { + builder.append(transportClient.transportAddresses().get(i).toString()); + } + } + + enhanceInfo.setTransportAddress(builder.toString()); + } else { + // avoid NPE + enhanceInfo.setTransportAddress(""); + } + + + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/Constants.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/Constants.java new file mode 100644 index 0000000000..45aed756d2 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/Constants.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.elasticsearch.v5; + +/** + * @author oatiz. + */ +class Constants { + + static final String DB_TYPE = "Elasticsearch"; + + static final String ELASTICSEARCH_DB_OP_PREFIX = "Elasticsearch/"; + + static final String ES_ENHANCE_INFO = "es_enhance_info"; + + static final String BASE_FUTURE_METHOD = "actionGet"; + + static final String ES_NODE = "node.address"; + + static final String ES_INDEX = "es.indices"; + + static final String ES_TYPE = "es.types"; + + static final String ES_TOOK_MILLIS = "es.took_millis"; + + static final String ES_TOTAL_HITS = "es.total_hits"; + + static final String ES_INGEST_TOOK_MILLIS = "es.ingest_took_millis"; + +} diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/ElasticSearchEnhanceInfo.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/ElasticSearchEnhanceInfo.java new file mode 100644 index 0000000000..1edcd7b290 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/ElasticSearchEnhanceInfo.java @@ -0,0 +1,98 @@ +/* + * 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.elasticsearch.v5; + +/** + * @author oatiz. + */ +public class ElasticSearchEnhanceInfo { + /** + * elasticsearch host and port + */ + private String transportAddress; + /** + * elasticsearch cluster name + */ + private String clusterName; + /** + * elasticsearch indices + */ + private String indices; + /** + * elasticsearch types + */ + private String types; + /** + * operation type: INDEX, CREATE, UPDATE, DELETE, BULK-bulkNum, defaultActionName + */ + private String opType; + /** + * source dsl + */ + private String source; + + public String getTransportAddress() { + return transportAddress; + } + + public void setTransportAddress(String transportAddress) { + this.transportAddress = transportAddress; + } + + public String getClusterName() { + return clusterName; + } + + public void setClusterName(String clusterName) { + this.clusterName = clusterName; + } + + public String getIndices() { + return indices; + } + + public void setIndices(String indices) { + this.indices = indices; + } + + public String getTypes() { + return types; + } + + public void setTypes(String types) { + this.types = types; + } + + public String getOpType() { + return opType; + } + + public void setOpType(String opType) { + this.opType = opType; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/PlainListenableActionFutureInterceptor.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/PlainListenableActionFutureInterceptor.java new file mode 100644 index 0000000000..016a2aba0b --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/PlainListenableActionFutureInterceptor.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.elasticsearch.v5; + +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.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.elasticsearch.action.bulk.BulkResponse; +import org.elasticsearch.action.search.SearchResponse; + +import java.lang.reflect.Method; + +import static org.apache.skywalking.apm.plugin.elasticsearch.v5.Constants.*; + +/** + * @author oatiz. + */ +public class PlainListenableActionFutureInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + AbstractSpan span = ContextManager.createLocalSpan(ELASTICSEARCH_DB_OP_PREFIX + BASE_FUTURE_METHOD); + span.setComponent(ComponentsDefine.TRANSPORT_CLIENT); + Tags.DB_TYPE.set(span, DB_TYPE); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + AbstractSpan span = ContextManager.activeSpan(); + if (ret instanceof SearchResponse) { + SearchResponse response = (SearchResponse) ret; + span.tag(ES_TOOK_MILLIS, Long.toString(response.getTookInMillis())); + span.tag(ES_TOTAL_HITS, Long.toString(response.getHits().getTotalHits())); + } else if (ret instanceof BulkResponse) { + BulkResponse response = (BulkResponse) ret; + span.tag(ES_TOOK_MILLIS, Long.toString(response.getTookInMillis())); + span.tag(ES_INGEST_TOOK_MILLIS, Long.toString(response.getIngestTookInMillis())); + } + ContextManager.stopSpan(); + 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/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/TransportActionNodeProxyInterceptor.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/TransportActionNodeProxyInterceptor.java new file mode 100644 index 0000000000..9f3a866d3a --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/TransportActionNodeProxyInterceptor.java @@ -0,0 +1,77 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.elasticsearch.v5; + +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; +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.elasticsearch.cluster.node.DiscoveryNode; + +import java.lang.reflect.Method; + +import static org.apache.skywalking.apm.agent.core.conf.Config.Plugin.Elasticsearch.TRACE_DSL; +import static org.apache.skywalking.apm.plugin.elasticsearch.v5.Constants.*; +import static org.apache.skywalking.apm.plugin.elasticsearch.v5.Util.wrapperNullStringValue; + +/** + * @author oatiz. + */ +public class TransportActionNodeProxyInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + ElasticSearchEnhanceInfo enhanceInfo = (ElasticSearchEnhanceInfo) ContextManager.getRuntimeContext().get(ES_ENHANCE_INFO); + + String opType = allArguments[1].getClass().getSimpleName(); + String operationName = ELASTICSEARCH_DB_OP_PREFIX + opType; + AbstractSpan span = ContextManager.createExitSpan(operationName, enhanceInfo.getTransportAddress()); + span.setComponent(ComponentsDefine.TRANSPORT_CLIENT); + Tags.DB_TYPE.set(span, DB_TYPE); + Tags.DB_INSTANCE.set(span, enhanceInfo.getClusterName()); + if (TRACE_DSL) { + Tags.DB_STATEMENT.set(span, enhanceInfo.getSource()); + } + span.tag(ES_NODE, ((DiscoveryNode) allArguments[0]).getAddress().toString()); + span.tag(ES_INDEX, wrapperNullStringValue(enhanceInfo.getIndices())); + span.tag(ES_TYPE, wrapperNullStringValue(enhanceInfo.getTypes())); + SpanLayer.asDB(span); + ContextManager.getRuntimeContext().remove(ES_ENHANCE_INFO); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + ContextManager.stopSpan(); + 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/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/TransportProxyClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/TransportProxyClientInterceptor.java new file mode 100644 index 0000000000..76b713a96b --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/TransportProxyClientInterceptor.java @@ -0,0 +1,156 @@ +/* + * 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.elasticsearch.v5; + +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.logging.api.ILog; +import org.apache.skywalking.apm.agent.core.logging.api.LogManager; +import 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.util.StringUtil; +import org.elasticsearch.action.delete.DeleteRequest; +import org.elasticsearch.action.get.GetRequest; +import org.elasticsearch.action.index.IndexRequest; +import org.elasticsearch.action.search.SearchRequest; +import org.elasticsearch.action.update.UpdateRequest; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.xcontent.XContentFactory; + +import java.io.IOException; +import java.lang.reflect.Method; + +import static org.apache.skywalking.apm.agent.core.conf.Config.Plugin.Elasticsearch.TRACE_DSL; +import static org.apache.skywalking.apm.plugin.elasticsearch.v5.Constants.ES_ENHANCE_INFO; +import static org.apache.skywalking.apm.plugin.elasticsearch.v5.Util.wrapperNullStringValue; + +/** + * @author oatiz. + */ +public class TransportProxyClientInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor { + + private static final ILog logger = LogManager.getLogger(TransportProxyClientInterceptor.class); + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + Settings settings = (Settings) allArguments[0]; + String clusterName = settings.get("cluster.name"); + objInst.setSkyWalkingDynamicField(wrapperNullStringValue(clusterName)); + } + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + ElasticSearchEnhanceInfo enhanceInfo = (ElasticSearchEnhanceInfo) ContextManager.getRuntimeContext().get(ES_ENHANCE_INFO); + enhanceInfo.setClusterName((String) objInst.getSkyWalkingDynamicField()); + parseRequestInfo(allArguments[1], enhanceInfo); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + ContextManager.activeSpan().errorOccurred().log(t); + } + + private void parseRequestInfo(Object request, ElasticSearchEnhanceInfo enhanceInfo) { + // search request + if (request instanceof SearchRequest) { + parseSearchRequest(request, enhanceInfo); + return; + } + // get request + if (request instanceof GetRequest) { + parseGetRequest(request, enhanceInfo); + return; + } + // index request + if (request instanceof IndexRequest) { + parseIndexRequest(request, enhanceInfo); + return; + } + // update request + if (request instanceof UpdateRequest) { + parseUpdateRequest(request, enhanceInfo); + return; + } + // delete request + if (request instanceof DeleteRequest) { + parseDeleteRequest(request, enhanceInfo); + } + } + + private void parseSearchRequest(Object request, ElasticSearchEnhanceInfo enhanceInfo) { + SearchRequest searchRequest = (SearchRequest) request; + enhanceInfo.setIndices(StringUtil.join(',', searchRequest.indices())); + enhanceInfo.setTypes(StringUtil.join(',', searchRequest.types())); + if (TRACE_DSL) { + enhanceInfo.setSource(null == searchRequest.source() ? "" : searchRequest.source().toString()); + } + } + + private void parseGetRequest(Object request, ElasticSearchEnhanceInfo enhanceInfo) { + GetRequest getRequest = (GetRequest) request; + enhanceInfo.setIndices(StringUtil.join(',', getRequest.indices())); + enhanceInfo.setTypes(getRequest.type()); + if (TRACE_DSL) { + enhanceInfo.setSource(getRequest.toString()); + } + } + + private void parseIndexRequest(Object request, ElasticSearchEnhanceInfo enhanceInfo) { + IndexRequest indexRequest = (IndexRequest) request; + enhanceInfo.setIndices(StringUtil.join(',', indexRequest.indices())); + enhanceInfo.setTypes(indexRequest.type()); + if (TRACE_DSL) { + enhanceInfo.setSource(indexRequest.toString()); + } + } + + private void parseUpdateRequest(Object request, ElasticSearchEnhanceInfo enhanceInfo) { + UpdateRequest updateRequest = (UpdateRequest) request; + enhanceInfo.setIndices(StringUtil.join(',', updateRequest.indices())); + enhanceInfo.setTypes(updateRequest.type()); + if (TRACE_DSL) { + String updateDsl = ""; + try { + updateDsl = updateRequest.toXContent(XContentFactory.jsonBuilder(), null).string(); + } catch (IOException e) { + logger.warn("trace update request dsl error: ", e); + } + enhanceInfo.setSource(updateDsl); + } + } + + private void parseDeleteRequest(Object request, ElasticSearchEnhanceInfo enhanceInfo) { + DeleteRequest deleteRequest = (DeleteRequest) request; + enhanceInfo.setIndices(StringUtil.join(',', deleteRequest.indices())); + enhanceInfo.setTypes(deleteRequest.type()); + if (TRACE_DSL) { + enhanceInfo.setSource(deleteRequest.toString()); + } + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/Util.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/Util.java new file mode 100644 index 0000000000..293ed1a36f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/Util.java @@ -0,0 +1,35 @@ +/* + * 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.elasticsearch.v5; + +import static org.apache.skywalking.apm.util.StringUtil.isEmpty; + +/** + * @author oatiz. + */ +class Util { + + static String wrapperNullStringValue(String value) { + if (isEmpty(value)) { + return ""; + } + return value; + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/ActionRequestBuilderInstrumentation.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/ActionRequestBuilderInstrumentation.java new file mode 100644 index 0000000000..b10c0f2bc3 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/ActionRequestBuilderInstrumentation.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.elasticsearch.v5.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * @author oatiz. + */ +public class ActionRequestBuilderInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.apache.skywalking.apm.plugin.elasticsearch.v5.ActionRequestBuilderInterceptor"; + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[]{ + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override + public String getConstructorInterceptor() { + return ENHANCE_CLASS; + } + } + }; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[0]; + } + + @Override + protected ClassMatch enhanceClass() { + return byName("org.elasticsearch.action.ActionRequestBuilder"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/PlainListenableActionFutureInstrumentation.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/PlainListenableActionFutureInstrumentation.java new file mode 100644 index 0000000000..a77b590a34 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/PlainListenableActionFutureInstrumentation.java @@ -0,0 +1,73 @@ +/* + * 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.elasticsearch.v5.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * @author oatiz. + */ +public class PlainListenableActionFutureInstrumentation extends ClassEnhancePluginDefine { + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("actionGet"); + } + + @Override + public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.elasticsearch.v5.PlainListenableActionFutureInterceptor"; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { + return new StaticMethodsInterceptPoint[0]; + } + + @Override + protected ClassMatch enhanceClass() { + return byName("org.elasticsearch.action.support.PlainListenableActionFuture"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/TransportActionNodeProxyInstrumentation.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/TransportActionNodeProxyInstrumentation.java new file mode 100644 index 0000000000..9eb69512c7 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/TransportActionNodeProxyInstrumentation.java @@ -0,0 +1,73 @@ +/* + * 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.elasticsearch.v5.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * @author oatiz. + */ +public class TransportActionNodeProxyInstrumentation extends ClassEnhancePluginDefine { + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("execute"); + } + + @Override + public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.elasticsearch.v5.TransportActionNodeProxyInterceptor"; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { + return new StaticMethodsInterceptPoint[0]; + } + + @Override + protected ClassMatch enhanceClass() { + return byName("org.elasticsearch.action.TransportActionNodeProxy"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/TransportProxyClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/TransportProxyClientInstrumentation.java new file mode 100644 index 0000000000..b3fa40ebef --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/elasticsearch/v5/define/TransportProxyClientInstrumentation.java @@ -0,0 +1,88 @@ +/* + * 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.elasticsearch.v5.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * @author oatiz. + */ +public class TransportProxyClientInstrumentation extends ClassEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.apache.skywalking.apm.plugin.elasticsearch.v5.TransportProxyClientInterceptor"; + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[]{ + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override + public String getConstructorInterceptor() { + return ENHANCE_CLASS; + } + } + }; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("execute"); + } + + @Override + public String getMethodsInterceptor() { + return ENHANCE_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { + return new StaticMethodsInterceptPoint[0]; + } + + @Override + protected ClassMatch enhanceClass() { + return byName("org.elasticsearch.client.transport.TransportProxyClient"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000..7cb6d6c80b --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/elasticsearch-5.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,20 @@ +# 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. + +elasticsearch-5.x=org.apache.skywalking.apm.plugin.elasticsearch.v5.define.ActionRequestBuilderInstrumentation +elasticsearch-5.x=org.apache.skywalking.apm.plugin.elasticsearch.v5.define.TransportProxyClientInstrumentation +elasticsearch-5.x=org.apache.skywalking.apm.plugin.elasticsearch.v5.define.TransportActionNodeProxyInstrumentation +elasticsearch-5.x=org.apache.skywalking.apm.plugin.elasticsearch.v5.define.PlainListenableActionFutureInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 50979f9a59..2b4b763390 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -57,6 +57,7 @@ servicecomb-plugin hystrix-1.x-plugin sofarpc-plugin + elasticsearch-5.x-plugin activemq-5.x-plugin pom diff --git a/docs/Supported-list.md b/docs/Supported-list.md index 945b2be2c4..243d698875 100644 --- a/docs/Supported-list.md +++ b/docs/Supported-list.md @@ -41,6 +41,8 @@ * Memcached Client * [Spymemcached](https://github.com/couchbase/spymemcached) 2.x * [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 * Service Discovery * [Netflix Eureka](https://github.com/Netflix/eureka) * Spring Ecosystem -- GitLab