diff --git a/CHANGES.md b/CHANGES.md index da8a191f2..7898f75a8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -17,6 +17,7 @@ Release Notes. * Fix OracleURLParser ignoring actual port when :SID is absent. * Change gRPC instrumentation point to fix plugin not working for server side. * Fix servicecomb plugin trace break. +* Adapt Armeria's plugins to the latest version 1.22.x #### Documentation * Update docs of Tracing APIs, reorganize the API docs into six parts. diff --git a/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/pom.xml new file mode 100644 index 000000000..4995f2094 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/pom.xml @@ -0,0 +1,43 @@ + + + + + + apm-armeria-plugins + org.apache.skywalking + 8.15.0-SNAPSHOT + + 4.0.0 + + apm-armeria-1.0.x-plugin + apm-armeria-1.0.x-plugin + + jar + SkyWalking Agent Plugin for Armeria 1.0.x+ + + + + com.linecorp.armeria + armeria + 1.0.0 + provided + + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/AbstractArmeriaClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/AbstractArmeriaClientInterceptor.java new file mode 100644 index 000000000..840de227a --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/AbstractArmeriaClientInterceptor.java @@ -0,0 +1,95 @@ +/* + * 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.armeria; + +import com.linecorp.armeria.client.Clients; +import com.linecorp.armeria.common.HttpMethod; +import com.linecorp.armeria.common.HttpRequest; +import com.linecorp.armeria.common.util.SafeCloseable; +import io.netty.util.AsciiString; +import org.apache.skywalking.apm.agent.core.context.CarrierItem; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.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 java.lang.reflect.Method; +import java.net.URI; + +public abstract class AbstractArmeriaClientInterceptor implements InstanceMethodsAroundInterceptor { + private static final String KEY_SAFE_CLOSEABLE = "SAFE_CLOSEABLE"; + + protected abstract URI getUri(EnhancedInstance objInst); + + protected abstract HttpMethod getHttpMethod(Object[] allArguments); + + protected abstract String getPath(Object[] allArguments); + + protected abstract HttpRequest getHttpRequest(Object[] allArguments); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) { + URI uri = getUri(objInst); + HttpMethod httpMethod = getHttpMethod(allArguments); + String path = getPath(allArguments); + + final ContextCarrier contextCarrier = new ContextCarrier(); + final String remotePeer = uri.getPort() > 0 ? uri.getHost() + ":" + uri.getPort() : uri.getHost(); + + final AbstractSpan exitSpan = ContextManager.createExitSpan(path, contextCarrier, remotePeer); + + exitSpan.setComponent(ComponentsDefine.ARMERIA); + exitSpan.setLayer(SpanLayer.HTTP); + Tags.HTTP.METHOD.set(exitSpan, httpMethod.name()); + + ContextManager.getRuntimeContext().put(KEY_SAFE_CLOSEABLE, Clients.withHeaders(builder -> { + for (CarrierItem item = contextCarrier.items(); item.hasNext(); ) { + item = item.next(); + builder.add(AsciiString.of(item.getHeadKey()), item.getHeadValue()); + } + })); + } + + @Override + public Object afterMethod(final EnhancedInstance objInst, final Method method, final Object[] allArguments, + final Class[] argumentsTypes, final Object ret) { + HttpRequest req = getHttpRequest(allArguments); + if (req != null && ContextManager.isActive()) { + ContextManager.stopSpan(); + } + + SafeCloseable safeCloseable = ContextManager.getRuntimeContext().get(KEY_SAFE_CLOSEABLE, SafeCloseable.class); + if (safeCloseable != null) { + safeCloseable.close(); + } + return ret; + } + + @Override + public void handleMethodException(final EnhancedInstance objInst, final Method method, final Object[] allArguments, + final Class[] argumentsTypes, final Throwable t) { + if (ContextManager.isActive()) { + ContextManager.activeSpan().log(t); + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/Armeria100ClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/Armeria100ClientInterceptor.java new file mode 100644 index 000000000..6bed5f1d3 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/Armeria100ClientInterceptor.java @@ -0,0 +1,50 @@ +/* + * 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.armeria; + +import com.linecorp.armeria.client.UserClient; +import com.linecorp.armeria.common.HttpMethod; +import com.linecorp.armeria.common.HttpRequest; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; + +import java.net.URI; + +public class Armeria100ClientInterceptor extends AbstractArmeriaClientInterceptor { + + @Override + protected URI getUri(EnhancedInstance objInst) { + UserClient userClient = (UserClient) objInst; + return userClient.uri(); + } + + @Override + protected HttpMethod getHttpMethod(Object[] allArguments) { + return (HttpMethod) allArguments[2]; + } + + @Override + protected String getPath(Object[] allArguments) { + return (String) allArguments[3]; + } + + @Override + protected HttpRequest getHttpRequest(Object[] allArguments) { + return (HttpRequest) allArguments[6]; + } + +} diff --git a/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/define/Armeria100ClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/define/Armeria100ClientInstrumentation.java new file mode 100644 index 000000000..be380ce4e --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/define/Armeria100ClientInstrumentation.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.armeria.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.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * Instruments Armeria client 1.0.x + */ +public class Armeria100ClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "com.linecorp.armeria.client.UserClient"; + private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.armeria.Armeria100ClientInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("execute").and(takesArgument(0, named("com.linecorp.armeria.common.SessionProtocol"))).and(takesArgument(1, named("com.linecorp.armeria.client.endpoint.EndpointGroup"))).and(takesArgument(2, named("com.linecorp.armeria.common.HttpMethod"))).and(takesArgument(3, named("java.lang.String"))).and(takesArgument(4, named("java.lang.String"))).and(takesArgument(5, named("java.lang.String"))); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected String[] witnessClasses() { + return new String[]{"com.linecorp.armeria.common.AbstractHttpHeadersBuilder"}; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..eb757ee8b --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/apm-armeria-1.0.x-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +armeria-100=org.apache.skywalking.apm.plugin.armeria.define.Armeria100ClientInstrumentation \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/pom.xml b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/pom.xml new file mode 100644 index 000000000..e2bd0eb57 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/apm-armeria-plugins/pom.xml @@ -0,0 +1,39 @@ + + + + + + apm-sdk-plugin + org.apache.skywalking + 8.15.0-SNAPSHOT + + 4.0.0 + pom + apm-armeria-plugins + apm-armeria-plugins + + + apm-armeria-1.0.x-plugin + + + + UTF-8 + /.. + + + \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/armeria-0.85.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/Armeria085ServerInterceptor.java b/apm-sniffer/apm-sdk-plugin/armeria-0.85.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/Armeria085ServerInterceptor.java index 4f219503e..8a5f32796 100644 --- a/apm-sniffer/apm-sdk-plugin/armeria-0.85.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/Armeria085ServerInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/armeria-0.85.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/armeria/Armeria085ServerInterceptor.java @@ -17,10 +17,9 @@ package org.apache.skywalking.apm.plugin.armeria; -import com.linecorp.armeria.common.DefaultHttpRequest; import com.linecorp.armeria.common.HttpHeaders; +import com.linecorp.armeria.common.HttpRequest; import io.netty.util.AsciiString; -import java.lang.reflect.Method; 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; @@ -32,13 +31,15 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceM import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import java.lang.reflect.Method; + @SuppressWarnings("unused") // actually used public class Armeria085ServerInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(final EnhancedInstance objInst, final Method method, final Object[] allArguments, final Class[] argumentsTypes, final MethodInterceptResult result) { - DefaultHttpRequest httpRequest = (DefaultHttpRequest) allArguments[1]; + HttpRequest httpRequest = (HttpRequest) allArguments[1]; HttpHeaders headers = httpRequest.headers(); ContextCarrier carrier = new ContextCarrier(); diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index e5cddd3ab..d6c5434c1 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -127,6 +127,7 @@ nats-2.14.x-2.15.x-plugin jedis-plugins impala-jdbc-2.6.x-plugin + apm-armeria-plugins pom diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md index aeea1528c..f19b227e8 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -4,6 +4,7 @@ - armeria-085 - armeria-086 - armeria-098 +- armeria-100 - async-http-client-2.x - avro-1.x - brpc-java 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 4b8973828..1bc0ada50 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -59,7 +59,7 @@ metrics based on the tracing data. * [gRPC](https://github.com/grpc/grpc-java) 1.x * [Apache ServiceComb Java Chassis](https://github.com/apache/servicecomb-java-chassis) 1.x, 2.x * [SOFARPC](https://github.com/alipay/sofa-rpc) 5.4.0 - * [Armeria](https://github.com/line/armeria) 0.63.0 -> 0.98.0 + * [Armeria](https://github.com/line/armeria) 0.63.0 -> 1.22.0 * [Apache Avro](http://avro.apache.org) 1.7.0 - 1.8.x * [Finagle](https://github.com/twitter/finagle) 6.44.0 -> 20.1.0 (6.25.0 -> 6.44.0 not tested) * [Brpc-Java](https://github.com/baidu/brpc-java) 2.3.7 -> 3.0.5 diff --git a/test/plugin/scenarios/armeria-0.96plus-scenario/src/main/java/org/apache/skywalking/apm/testcase/armeria/ServerApplication.java b/test/plugin/scenarios/armeria-0.96plus-scenario/src/main/java/org/apache/skywalking/apm/testcase/armeria/ServerApplication.java index 93b7bfbe3..7244f391c 100644 --- a/test/plugin/scenarios/armeria-0.96plus-scenario/src/main/java/org/apache/skywalking/apm/testcase/armeria/ServerApplication.java +++ b/test/plugin/scenarios/armeria-0.96plus-scenario/src/main/java/org/apache/skywalking/apm/testcase/armeria/ServerApplication.java @@ -20,17 +20,18 @@ package org.apache.skywalking.apm.testcase.armeria; import com.linecorp.armeria.common.HttpResponse; import com.linecorp.armeria.server.Server; import com.linecorp.armeria.server.ServerBuilder; -import java.util.concurrent.CompletableFuture; -import javax.annotation.PostConstruct; import org.springframework.stereotype.Component; +import javax.annotation.PostConstruct; +import java.util.concurrent.CompletableFuture; + @Component public class ServerApplication { private static final String SUCCESS = "Success"; @PostConstruct public void init() { - ServerBuilder sb = new ServerBuilder().http(8085) + ServerBuilder sb = Server.builder().http(8085) .service("/healthCheck", (ctx, res) -> HttpResponse.of(SUCCESS)) .service("/greet/{name}", (ctx, res) -> HttpResponse.of("Hello %s~", ctx.pathParam("name"))); diff --git a/test/plugin/scenarios/armeria-0.96plus-scenario/support-version.list b/test/plugin/scenarios/armeria-0.96plus-scenario/support-version.list index 0fbfc1d46..0a1e2fa46 100644 --- a/test/plugin/scenarios/armeria-0.96plus-scenario/support-version.list +++ b/test/plugin/scenarios/armeria-0.96plus-scenario/support-version.list @@ -14,6 +14,30 @@ # See the License for the specific language governing permissions and # limitations under the License. +1.22.0 +1.21.0 +1.20.0 +1.19.0 +1.18.0 +1.17.0 +1.16.0 +1.15.0 +1.14.0 +1.13.0 +1.12.0 +1.11.0 +1.10.0 +1.9.0 +1.8.0 +1.7.0 +1.6.0 +1.5.0 +1.4.0 +1.3.0 +1.2.0 +1.1.0 +1.0.0 +0.99.0 0.98.0 0.97.0 0.96.0