Skip to content

Commit c020951

Browse files
committed
Add elasticsearch-java 7.15.x support and fix CI
- Add RestClientTransportV1Instrumentation for 7.15.x where RestClientTransport is in co.elastic.clients.base.rest_client (moved to co.elastic.clients.transport.rest_client in 7.16+) - Add TransportPerformRequestV1Interceptor that derives operation names from request class names since Endpoint.id() doesn't exist in 7.15.x - Add separate elasticsearch-java-7.15.x-scenario test (JDK 8) - Remove 7.15.x from main scenario (incompatible imports) - Fix JDK17 workflow: run elasticsearch-java-9.x-scenario instead of duplicating the main scenario
1 parent 63257da commit c020951

16 files changed

Lines changed: 743 additions & 4 deletions

File tree

.github/workflows/plugins-jdk17-test.1.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ jobs:
8181
- spring-scheduled-6.x-scenario
8282
- caffeine-3.x-scenario
8383
- lettuce-webflux-6x-scenario
84-
- elasticsearch-java-scenario
84+
- elasticsearch-java-9.x-scenario
8585
steps:
8686
- uses: actions/checkout@v2
8787
with:

.github/workflows/plugins-test.2.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ jobs:
9898
- rocketmq-scenario
9999
- rocketmq-5-grpc-scenario
100100
- elasticsearch-java-scenario
101+
- elasticsearch-java-7.15.x-scenario
101102
steps:
102103
- uses: actions/checkout@v2
103104
with:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.elasticsearch.java.define;
20+
21+
import net.bytebuddy.description.method.MethodDescription;
22+
import net.bytebuddy.matcher.ElementMatcher;
23+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
24+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
25+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
26+
import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
27+
28+
import static net.bytebuddy.matcher.ElementMatchers.named;
29+
import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
30+
import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
31+
32+
/**
33+
* Enhance {@code co.elastic.clients.base.rest_client.RestClientTransport}
34+
* for elasticsearch-java 7.15.x where RestClientTransport was in the
35+
* {@code co.elastic.clients.base.rest_client} package (moved to
36+
* {@code co.elastic.clients.transport.rest_client} in 7.16.0+).
37+
*/
38+
public class RestClientTransportV1Instrumentation extends ClassInstanceMethodsEnhancePluginDefine {
39+
40+
private static final String ENHANCE_CLASS = "co.elastic.clients.base.rest_client.RestClientTransport";
41+
42+
private static final String CONSTRUCTOR_INTERCEPTOR =
43+
"org.apache.skywalking.apm.plugin.elasticsearch.java.interceptor.RestClientTransportConstructorInterceptor";
44+
45+
private static final String PERFORM_REQUEST_INTERCEPTOR =
46+
"org.apache.skywalking.apm.plugin.elasticsearch.java.interceptor.TransportPerformRequestV1Interceptor";
47+
48+
@Override
49+
protected String[] witnessClasses() {
50+
return new String[] {ENHANCE_CLASS};
51+
}
52+
53+
@Override
54+
protected ClassMatch enhanceClass() {
55+
return byName(ENHANCE_CLASS);
56+
}
57+
58+
@Override
59+
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
60+
return new ConstructorInterceptPoint[] {
61+
new ConstructorInterceptPoint() {
62+
@Override
63+
public ElementMatcher<MethodDescription> getConstructorMatcher() {
64+
return takesArgumentWithType(0, "org.elasticsearch.client.RestClient");
65+
}
66+
67+
@Override
68+
public String getConstructorInterceptor() {
69+
return CONSTRUCTOR_INTERCEPTOR;
70+
}
71+
}
72+
};
73+
}
74+
75+
@Override
76+
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
77+
return new InstanceMethodsInterceptPoint[] {
78+
new InstanceMethodsInterceptPoint() {
79+
@Override
80+
public ElementMatcher<MethodDescription> getMethodsMatcher() {
81+
return named("performRequest");
82+
}
83+
84+
@Override
85+
public String getMethodsInterceptor() {
86+
return PERFORM_REQUEST_INTERCEPTOR;
87+
}
88+
89+
@Override
90+
public boolean isOverrideArgs() {
91+
return false;
92+
}
93+
}
94+
};
95+
}
96+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*/
18+
19+
package org.apache.skywalking.apm.plugin.elasticsearch.java.interceptor;
20+
21+
import org.apache.skywalking.apm.agent.core.context.ContextManager;
22+
import org.apache.skywalking.apm.agent.core.context.tag.Tags;
23+
import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
24+
import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
25+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
26+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
27+
import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
28+
import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
29+
30+
import java.lang.reflect.Method;
31+
32+
/**
33+
* Intercept {@code co.elastic.clients.base.rest_client.RestClientTransport.performRequest()}
34+
* for elasticsearch-java 7.15.x.
35+
* <p>
36+
* In 7.15.x, the Endpoint interface ({@code co.elastic.clients.base.Endpoint}) does not have
37+
* an {@code id()} method, so the operation name is derived from the request class name.
38+
* E.g., {@code IndexRequest} → {@code Elasticsearch/index}.
39+
* <p>
40+
* Args: [0] request, [1] endpoint (co.elastic.clients.base.Endpoint)
41+
*/
42+
public class TransportPerformRequestV1Interceptor implements InstanceMethodsAroundInterceptor {
43+
44+
private static final String DB_TYPE = "Elasticsearch";
45+
private static final String REQUEST_SUFFIX = "Request";
46+
47+
@Override
48+
public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
49+
Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable {
50+
Object request = allArguments[0];
51+
String operationName = "Elasticsearch/" + deriveOperationName(request);
52+
53+
String peers = (String) objInst.getSkyWalkingDynamicField();
54+
if (peers == null || peers.isEmpty()) {
55+
peers = "Unknown";
56+
}
57+
58+
AbstractSpan span = ContextManager.createExitSpan(operationName, peers);
59+
span.setComponent(ComponentsDefine.REST_HIGH_LEVEL_CLIENT);
60+
Tags.DB_TYPE.set(span, DB_TYPE);
61+
SpanLayer.asDB(span);
62+
}
63+
64+
@Override
65+
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
66+
Class<?>[] argumentsTypes, Object ret) throws Throwable {
67+
ContextManager.stopSpan();
68+
return ret;
69+
}
70+
71+
@Override
72+
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
73+
Class<?>[] argumentsTypes, Throwable t) {
74+
ContextManager.activeSpan().log(t);
75+
ContextManager.activeSpan().errorOccurred();
76+
}
77+
78+
/**
79+
* Derive operation name from request class simple name.
80+
* E.g., IndexRequest → index, SearchRequest → search, CreateIndexRequest → create_index
81+
*/
82+
private String deriveOperationName(Object request) {
83+
String className = request.getClass().getSimpleName();
84+
if (className.endsWith(REQUEST_SUFFIX)) {
85+
className = className.substring(0, className.length() - REQUEST_SUFFIX.length());
86+
}
87+
// Convert PascalCase to snake_case
88+
StringBuilder sb = new StringBuilder();
89+
for (int i = 0; i < className.length(); i++) {
90+
char c = className.charAt(i);
91+
if (Character.isUpperCase(c) && i > 0) {
92+
sb.append('_');
93+
}
94+
sb.append(Character.toLowerCase(c));
95+
}
96+
return sb.toString();
97+
}
98+
}

apm-sniffer/apm-sdk-plugin/elasticsearch-java-plugin/src/main/resources/skywalking-plugin.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
# Elasticsearch Java client (co.elastic.clients:elasticsearch-java) 7.x-9.x
17+
# Elasticsearch Java client (co.elastic.clients:elasticsearch-java) 7.15.x-9.x
18+
elasticsearch-java=org.apache.skywalking.apm.plugin.elasticsearch.java.define.RestClientTransportV1Instrumentation
1819
elasticsearch-java=org.apache.skywalking.apm.plugin.elasticsearch.java.define.RestClientTransportInstrumentation
1920
elasticsearch-java=org.apache.skywalking.apm.plugin.elasticsearch.java.define.ElasticsearchTransportBaseInstrumentation
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#!/bin/bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
home="$(cd "$(dirname $0)"; pwd)"
20+
21+
java -jar ${agent_opts} -Dskywalking.plugin.elasticsearch.trace_dsl=true ${home}/../libs/elasticsearch-java-7.15.x-scenario.jar &
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
segmentItems:
17+
- serviceName: elasticsearch-java-7.15.x-scenario
18+
segmentSize: ge 2
19+
segments:
20+
- segmentId: not null
21+
spans:
22+
- operationName: Elasticsearch/create_index
23+
parentSpanId: 0
24+
spanId: 1
25+
spanLayer: Database
26+
startTime: nq 0
27+
endTime: nq 0
28+
componentId: 77
29+
isError: false
30+
spanType: Exit
31+
peer: not null
32+
skipAnalysis: false
33+
tags:
34+
- {key: db.type, value: Elasticsearch}
35+
- operationName: Elasticsearch/index
36+
parentSpanId: 0
37+
spanId: 2
38+
spanLayer: Database
39+
startTime: nq 0
40+
endTime: nq 0
41+
componentId: 77
42+
isError: false
43+
spanType: Exit
44+
peer: not null
45+
skipAnalysis: false
46+
tags:
47+
- {key: db.type, value: Elasticsearch}
48+
- operationName: Elasticsearch/get
49+
parentSpanId: 0
50+
spanId: 3
51+
spanLayer: Database
52+
startTime: nq 0
53+
endTime: nq 0
54+
componentId: 77
55+
isError: false
56+
spanType: Exit
57+
peer: not null
58+
skipAnalysis: false
59+
tags:
60+
- {key: db.type, value: Elasticsearch}
61+
- operationName: Elasticsearch/search
62+
parentSpanId: 0
63+
spanId: 4
64+
spanLayer: Database
65+
startTime: nq 0
66+
endTime: nq 0
67+
componentId: 77
68+
isError: false
69+
spanType: Exit
70+
peer: not null
71+
skipAnalysis: false
72+
tags:
73+
- {key: db.type, value: Elasticsearch}
74+
- operationName: Elasticsearch/delete
75+
parentSpanId: 0
76+
spanId: 5
77+
spanLayer: Database
78+
startTime: nq 0
79+
endTime: nq 0
80+
componentId: 77
81+
isError: false
82+
spanType: Exit
83+
peer: not null
84+
skipAnalysis: false
85+
tags:
86+
- {key: db.type, value: Elasticsearch}
87+
- operationName: Elasticsearch/delete_index
88+
parentSpanId: 0
89+
spanId: 6
90+
spanLayer: Database
91+
startTime: nq 0
92+
endTime: nq 0
93+
componentId: 77
94+
isError: false
95+
spanType: Exit
96+
peer: not null
97+
skipAnalysis: false
98+
tags:
99+
- {key: db.type, value: Elasticsearch}
100+
- operationName: GET:/elasticsearch-java-case/case/elasticsearch
101+
parentSpanId: -1
102+
spanId: 0
103+
startTime: nq 0
104+
endTime: nq 0
105+
spanLayer: Http
106+
isError: false
107+
spanType: Entry
108+
componentId: 1
109+
tags:
110+
- {key: url, value: not null}
111+
- {key: http.method, value: GET}
112+
- {key: http.status_code, value: '200'}
113+
skipAnalysis: 'false'
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
type: jvm
18+
entryService: http://localhost:8080/elasticsearch-java-case/case/elasticsearch
19+
healthCheck: http://localhost:8080/elasticsearch-java-case/case/healthCheck
20+
startScript: ./bin/startup.sh
21+
environment:
22+
- elasticsearch.server=elasticsearch-server:9200
23+
dependencies:
24+
elasticsearch-server:
25+
image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
26+
hostname: elasticsearch-server
27+
removeOnExit: true
28+
expose:
29+
- 9200
30+
environment:
31+
- cluster.name=docker-node
32+
- xpack.security.enabled=false
33+
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
34+
- discovery.type=single-node

0 commit comments

Comments
 (0)