diff --git a/.github/workflows/plugins-jdk17-test.0.yaml b/.github/workflows/plugins-jdk17-test.0.yaml index 45edcbac48..d496c158ab 100644 --- a/.github/workflows/plugins-jdk17-test.0.yaml +++ b/.github/workflows/plugins-jdk17-test.0.yaml @@ -59,6 +59,8 @@ jobs: matrix: case: - jdk17-with-gson-scenario +# TODO: We can't test it just yet, because it requires a Skywalking release +# - resttemplate-6.x-scenario steps: - uses: actions/checkout@v2 with: diff --git a/CHANGES.md b/CHANGES.md index ab70ca9621..2d624fa5ef 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ Release Notes. * Report the agent version to OAP as an instance attribute * Polish jedis-4.x-plugin to change command to lowercase, which is consistent with jedis-2.x-3.x-plugin * Add micronauthttpclient,micronauthttpserver,memcached,ehcache,guavacache,jedis,redisson plugin config properties to agent.config +* Add [Micrometer Observation](https://github.com/micrometer-metrics/micrometer/) support * Add tags `mq.message.keys` and `mq.message.tags` for RocketMQ producer span #### Documentation diff --git a/apm-application-toolkit/apm-toolkit-micrometer-1.10/pom.xml b/apm-application-toolkit/apm-toolkit-micrometer-1.10/pom.xml new file mode 100644 index 0000000000..2fea532c5c --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-micrometer-1.10/pom.xml @@ -0,0 +1,65 @@ + + + + + apm-application-toolkit + org.apache.skywalking + 8.14.0-SNAPSHOT + + 4.0.0 + + apm-toolkit-micrometer-1.10 + jar + + http://maven.apache.org + + + 1.10.2 + 1.0.0 + + + + + org.apache.skywalking + apm-toolkit-micrometer-registry + ${project.version} + + + io.micrometer + micrometer-observation + ${micrometer-core.version} + + + io.micrometer + micrometer-core + ${micrometer-core.version} + + + io.micrometer + context-propagation + ${context-propagation.version} + + + io.micrometer + micrometer-test + ${micrometer-core.version} + test + + + diff --git a/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingContextSnapshotThreadLocalAccessor.java b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingContextSnapshotThreadLocalAccessor.java new file mode 100644 index 0000000000..0de5923eb4 --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingContextSnapshotThreadLocalAccessor.java @@ -0,0 +1,55 @@ +/* + * 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.toolkit.micrometer.observation; + +import io.micrometer.context.ThreadLocalAccessor; + +/** + * A {@link ThreadLocalAccessor} to put and restore current {@code ContextSnapshot} from APM agent. + */ +public class SkywalkingContextSnapshotThreadLocalAccessor implements ThreadLocalAccessor { + + /** + * Key under which ContextSnapshot is being registered. + */ + public static final String KEY = "skywalking.contextsnapshot"; + + @Override + public Object key() { + return KEY; + } + + // Type will be ContextSnapshot + @Override + public Object getValue() { + return null; + } + + // Object to set will be ContextSnapshot + @Override + public void setValue(Object value) { + + } + + @Override + public void reset() { + + } + +} diff --git a/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingDefaultTracingHandler.java b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingDefaultTracingHandler.java new file mode 100644 index 0000000000..ccf9662c7f --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingDefaultTracingHandler.java @@ -0,0 +1,59 @@ +/* + * 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.toolkit.micrometer.observation; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.ObservationHandler; + +public class SkywalkingDefaultTracingHandler implements ObservationHandler { + @Override + public boolean supportsContext(final Observation.Context context) { + return true; + } + + @Override + public void onStart(final Observation.Context context) { + + } + + @Override + public void onError(final Observation.Context context) { + + } + + @Override + public void onEvent(final Observation.Event event, final Observation.Context context) { + + } + + @Override + public void onScopeOpened(final Observation.Context context) { + + } + + @Override + public void onScopeClosed(final Observation.Context context) { + + } + + @Override + public void onStop(final Observation.Context context) { + + } +} diff --git a/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingMeterHandler.java b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingMeterHandler.java new file mode 100644 index 0000000000..066a181708 --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingMeterHandler.java @@ -0,0 +1,29 @@ +/* + * 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.toolkit.micrometer.observation; + +import io.micrometer.core.instrument.observation.DefaultMeterObservationHandler; +import org.apache.skywalking.apm.meter.micrometer.SkywalkingMeterRegistry; + +public class SkywalkingMeterHandler extends DefaultMeterObservationHandler { + + public SkywalkingMeterHandler(SkywalkingMeterRegistry meterRegistry) { + super(meterRegistry); + } +} diff --git a/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingReceiverTracingHandler.java b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingReceiverTracingHandler.java new file mode 100644 index 0000000000..fe32c88940 --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingReceiverTracingHandler.java @@ -0,0 +1,60 @@ +/* + * 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.toolkit.micrometer.observation; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.transport.ReceiverContext; + +public class SkywalkingReceiverTracingHandler implements ObservationHandler> { + @Override + public boolean supportsContext(final Observation.Context context) { + return context instanceof ReceiverContext; + } + + @Override + public void onStart(final ReceiverContext context) { + + } + + @Override + public void onError(final ReceiverContext context) { + + } + + @Override + public void onEvent(final Observation.Event event, final ReceiverContext context) { + + } + + @Override + public void onScopeOpened(final ReceiverContext context) { + + } + + @Override + public void onScopeClosed(final ReceiverContext context) { + + } + + @Override + public void onStop(final ReceiverContext context) { + + } +} diff --git a/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingSenderTracingHandler.java b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingSenderTracingHandler.java new file mode 100644 index 0000000000..c16e8debed --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingSenderTracingHandler.java @@ -0,0 +1,60 @@ +/* + * 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.toolkit.micrometer.observation; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.transport.SenderContext; + +public class SkywalkingSenderTracingHandler implements ObservationHandler> { + @Override + public boolean supportsContext(final Observation.Context context) { + return context instanceof SenderContext; + } + + @Override + public void onStart(final SenderContext context) { + + } + + @Override + public void onError(final SenderContext context) { + + } + + @Override + public void onEvent(final Observation.Event event, final SenderContext context) { + + } + + @Override + public void onScopeOpened(final SenderContext context) { + + } + + @Override + public void onScopeClosed(final SenderContext context) { + + } + + @Override + public void onStop(final SenderContext context) { + + } +} diff --git a/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/resources/META-INF/services/io.micrometer.context.ThreadLocalAccessor b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/resources/META-INF/services/io.micrometer.context.ThreadLocalAccessor new file mode 100644 index 0000000000..94b4d89dd0 --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/main/resources/META-INF/services/io.micrometer.context.ThreadLocalAccessor @@ -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. + +org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingContextSnapshotThreadLocalAccessor diff --git a/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/test/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingMeterHandlerTests.java b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/test/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingMeterHandlerTests.java new file mode 100644 index 0000000000..df8115a3de --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-micrometer-1.10/src/test/java/org/apache/skywalking/apm/toolkit/micrometer/observation/SkywalkingMeterHandlerTests.java @@ -0,0 +1,47 @@ +/* + * 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.toolkit.micrometer.observation; + +import io.micrometer.core.tck.MeterRegistryAssert; +import io.micrometer.observation.Observation; +import io.micrometer.observation.tck.TestObservationRegistry; +import org.apache.skywalking.apm.meter.micrometer.SkywalkingMeterRegistry; +import org.junit.Test; + +public class SkywalkingMeterHandlerTests { + SkywalkingMeterRegistry meterRegistry = new SkywalkingMeterRegistry(); + + SkywalkingMeterHandler handler = new SkywalkingMeterHandler(meterRegistry); + + TestObservationRegistry observationRegistry = TestObservationRegistry.create(); + + @Test + public void testCreateTimer() { + observationRegistry.observationConfig().observationHandler(handler); + + Observation.createNotStarted("foo", observationRegistry) + .observe(() -> { + + }); + + MeterRegistryAssert.assertThat(meterRegistry) + .hasMeterWithName("foo") + .hasMeterWithName("foo.active"); + } +} diff --git a/apm-application-toolkit/pom.xml b/apm-application-toolkit/pom.xml index 19314a30b9..8d2baea6d0 100644 --- a/apm-application-toolkit/pom.xml +++ b/apm-application-toolkit/pom.xml @@ -34,6 +34,7 @@ apm-toolkit-trace apm-toolkit-meter apm-toolkit-micrometer-registry + apm-toolkit-micrometer-1.10 apm-toolkit-kafka apm-toolkit-webflux 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 f8a578466f..283d642c34 100755 --- 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 @@ -231,4 +231,6 @@ public class ComponentsDefine { public static final OfficialComponent IMPALA_JDBC_DRIVER = new OfficialComponent(133, "Impala-jdbc-driver"); + public static final OfficialComponent MICROMETER = new OfficialComponent(141, "Micrometer"); + } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/pom.xml b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/pom.xml new file mode 100644 index 0000000000..6b850e7748 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/pom.xml @@ -0,0 +1,51 @@ + + + + + apm-toolkit-activation + org.apache.skywalking + 8.14.0-SNAPSHOT + + 4.0.0 + + apm-toolkit-micrometer-activation + jar + + apm-toolkit-micrometer-activation + http://maven.apache.org + + + UTF-8 + 1.10.2 + + + + + org.apache.skywalking + apm-toolkit-micrometer-1.10 + ${project.version} + + + io.micrometer + micrometer-core + ${micrometer.version} + provided + + + diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerContextManagerThreadLocalAccessorInstrumentation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerContextManagerThreadLocalAccessorInstrumentation.java new file mode 100644 index 0000000000..25157cca8d --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerContextManagerThreadLocalAccessorInstrumentation.java @@ -0,0 +1,76 @@ +/* + * 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.toolkit.activation.micrometer; + +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 org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class MicrometerContextManagerThreadLocalAccessorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingContextSnapshotThreadLocalAccessor"; + + public static final String INTERCEPT_GET_VALUE_POINT_METHOD = "getValue"; + + public static final String INTERCEPT_SET_VALUE_POINT_METHOD = "setValue"; + + public static final String INTERCEPT_RESET_POINT_METHOD = "reset"; + public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.micrometer.MicrometerContextSnapshotThreadLocalAccessorInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.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(INTERCEPT_GET_VALUE_POINT_METHOD) + .or(named(INTERCEPT_SET_VALUE_POINT_METHOD)) + .or(named(INTERCEPT_RESET_POINT_METHOD)); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerContextSnapshotThreadLocalAccessorInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerContextSnapshotThreadLocalAccessorInterceptor.java new file mode 100644 index 0000000000..8ea6e33db8 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerContextSnapshotThreadLocalAccessorInterceptor.java @@ -0,0 +1,67 @@ +/* + * 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.toolkit.activation.micrometer; + +import java.lang.reflect.Method; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.ContextSnapshot; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingContextSnapshotThreadLocalAccessor; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +/** + * {@link MicrometerContextSnapshotThreadLocalAccessorInterceptor} define how to enhance classes + * {@link SkywalkingContextSnapshotThreadLocalAccessor}. + */ +public class MicrometerContextSnapshotThreadLocalAccessorInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + String methodName = method.getName(); + if ("getValue".equals(methodName)) { + return ContextManager.capture(); + } else if ("setValue".equals(methodName)) { + ContextSnapshot context = (ContextSnapshot) allArguments[0]; + AbstractSpan span = ContextManager.createLocalSpan("Thread"); + span.setComponent(ComponentsDefine.MICROMETER); + ContextManager.continued(context); + } else if ("reset".equals(methodName)) { + if (ContextManager.isActive()) { + ContextManager.stopSpan(); + } + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + } + +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerDefaultTracingHandlerInstrumentation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerDefaultTracingHandlerInstrumentation.java new file mode 100644 index 0000000000..2e32418eed --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerDefaultTracingHandlerInstrumentation.java @@ -0,0 +1,80 @@ +/* + * 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.toolkit.activation.micrometer; + +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 org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class MicrometerDefaultTracingHandlerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingDefaultTracingHandler"; + + public static final String INTERCEPT_START_POINT_METHOD = "onStart"; + + public static final String INTERCEPT_STOP_POINT_METHOD = "onStop"; + + public static final String INTERCEPT_ERROR_POINT_METHOD = "onError"; + + public static final String INTERCEPT_EVENT_POINT_METHOD = "onEvent"; + + public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.micrometer.MicrometerDefaultTracingHandlerInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.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(INTERCEPT_START_POINT_METHOD) + .or(named(INTERCEPT_STOP_POINT_METHOD)) + .or(named(INTERCEPT_ERROR_POINT_METHOD)) + .or(named(INTERCEPT_EVENT_POINT_METHOD)); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerDefaultTracingHandlerInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerDefaultTracingHandlerInterceptor.java new file mode 100644 index 0000000000..006c8002e4 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerDefaultTracingHandlerInterceptor.java @@ -0,0 +1,86 @@ +/* + * 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.toolkit.activation.micrometer; + +import io.micrometer.observation.Observation; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +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.toolkit.micrometer.observation.SkywalkingDefaultTracingHandler; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.apache.skywalking.apm.util.StringUtil; + +/** + * {@link MicrometerDefaultTracingHandlerInterceptor} define how to enhance classes + * {@link SkywalkingDefaultTracingHandler}. + */ +public class MicrometerDefaultTracingHandlerInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + String methodName = method.getName(); + if ("onStart".equals(methodName)) { + Observation.Context context = (Observation.Context) allArguments[0]; + AbstractSpan span = ContextManager.createLocalSpan(context.getName()); + span.setComponent(ComponentsDefine.MICROMETER); + // tags + } else if ("onStop".equals(methodName)) { + Observation.Context context = (Observation.Context) allArguments[0]; + SpanLayer spanLayer = TaggingHelper.toLayer(context.getAllKeyValues()); + AbstractSpan abstractSpan = ContextManager.activeSpan(); + abstractSpan + .setOperationName(StringUtil.isBlank( + context.getContextualName()) ? context.getName() : context.getContextualName()); + context.getAllKeyValues() + .forEach(keyValue -> abstractSpan.tag(Tags.ofKey(keyValue.getKey()), keyValue.getValue())); + if (spanLayer != null) { + abstractSpan.setLayer(spanLayer); + } + ContextManager.stopSpan(); + } else if ("onError".equals(methodName)) { + Observation.Context context = (Observation.Context) allArguments[0]; + ContextManager.activeSpan().log(context.getError()); + } else if ("onEvent".equals(methodName)) { + Observation.Event event = (Observation.Event) allArguments[0]; + Map map = new HashMap<>(); + map.put("event", event.getContextualName() != null ? event.getContextualName() : event.getName()); + ContextManager.activeSpan().log(System.currentTimeMillis(), map); + } + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + } + +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerReceiverTracingHandlerInstrumentation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerReceiverTracingHandlerInstrumentation.java new file mode 100644 index 0000000000..573356e160 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerReceiverTracingHandlerInstrumentation.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.toolkit.activation.micrometer; + +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 org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class MicrometerReceiverTracingHandlerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingReceiverTracingHandler"; + + public static final String INTERCEPT_START_POINT_METHOD = "onStart"; + + public static final String INTERCEPT_ERROR_POINT_METHOD = "onError"; + + public static final String INTERCEPT_STOP_POINT_METHOD = "onStop"; + + public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.micrometer.MicrometerReceiverTracingHandlerInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.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(INTERCEPT_START_POINT_METHOD) + .or(named(INTERCEPT_STOP_POINT_METHOD)) + .or(named(INTERCEPT_ERROR_POINT_METHOD)); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerReceiverTracingHandlerInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerReceiverTracingHandlerInterceptor.java new file mode 100644 index 0000000000..4f9ebafebd --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerReceiverTracingHandlerInterceptor.java @@ -0,0 +1,92 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.toolkit.activation.micrometer; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.transport.ReceiverContext; +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; +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.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingReceiverTracingHandler; +import org.apache.skywalking.apm.util.StringUtil; + +/** + * {@link MicrometerReceiverTracingHandlerInterceptor} define how to enhance classes + * {@link SkywalkingReceiverTracingHandler}. + */ +public class MicrometerReceiverTracingHandlerInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + String methodName = method.getName(); + if ("onStart".equals(methodName)) { + ReceiverContext context = (ReceiverContext) allArguments[0]; + final ContextCarrier contextCarrier = new ContextCarrier(); + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + next.setHeadValue(context.getGetter().get(context.getCarrier(), next.getHeadKey())); + } + AbstractSpan span = ContextManager.createEntrySpan(getOperationName(context), contextCarrier); + span.setComponent(ComponentsDefine.MICROMETER); + + } else if ("onStop".equals(methodName)) { + ReceiverContext context = (ReceiverContext) allArguments[0]; + SpanLayer spanLayer = TaggingHelper.toLayer(context.getAllKeyValues()); + AbstractSpan abstractSpan = ContextManager.activeSpan(); + abstractSpan + .setPeer(SpanHelper.tryToGetPeer(context.getRemoteServiceAddress(), context.getAllKeyValues())) + .setOperationName(getOperationName(context)); + context.getAllKeyValues() + .forEach(keyValue -> abstractSpan.tag(Tags.ofKey(keyValue.getKey()), keyValue.getValue())); + if (spanLayer != null) { + abstractSpan.setLayer(spanLayer); + } + ContextManager.stopSpan(); + } else if ("onError".equals(methodName)) { + Observation.Context context = (Observation.Context) allArguments[0]; + ContextManager.activeSpan().log(context.getError()); + } + } + + private static String getOperationName(final ReceiverContext context) { + return StringUtil.isBlank( + context.getContextualName()) ? context.getName() : context.getContextualName(); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerSenderTracingHandlerInstrumentation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerSenderTracingHandlerInstrumentation.java new file mode 100644 index 0000000000..d528f1e2b7 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerSenderTracingHandlerInstrumentation.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.toolkit.activation.micrometer; + +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 org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +public class MicrometerSenderTracingHandlerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + public static final String ENHANCE_CLASS = "org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingSenderTracingHandler"; + + public static final String INTERCEPT_START_POINT_METHOD = "onStart"; + + public static final String INTERCEPT_ERROR_POINT_METHOD = "onError"; + + public static final String INTERCEPT_STOP_POINT_METHOD = "onStop"; + + public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.toolkit.activation.micrometer.MicrometerSenderTracingHandlerInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return NameMatch.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(INTERCEPT_START_POINT_METHOD) + .or(named(INTERCEPT_STOP_POINT_METHOD)) + .or(named(INTERCEPT_ERROR_POINT_METHOD)); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPT_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerSenderTracingHandlerInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerSenderTracingHandlerInterceptor.java new file mode 100644 index 0000000000..1aeee1eeea --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerSenderTracingHandlerInterceptor.java @@ -0,0 +1,93 @@ +/* + * 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.toolkit.activation.micrometer; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.transport.SenderContext; +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; +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.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingSenderTracingHandler; +import org.apache.skywalking.apm.util.StringUtil; + +/** + * {@link MicrometerSenderTracingHandlerInterceptor} define how to enhance classes + * {@link SkywalkingSenderTracingHandler}. + */ +public class MicrometerSenderTracingHandlerInterceptor implements InstanceMethodsAroundInterceptor { + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + String methodName = method.getName(); + if ("onStart".equals(methodName)) { + SenderContext context = (SenderContext) allArguments[0]; + final ContextCarrier contextCarrier = new ContextCarrier(); + AbstractSpan span = ContextManager.createExitSpan( + getOperationName(context), contextCarrier, SpanHelper.tryToGetPeer(context.getRemoteServiceAddress(), context.getAllKeyValues())); + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + context.getSetter().set(context.getCarrier(), next.getHeadKey(), next.getHeadValue()); + } + span.setComponent(ComponentsDefine.MICROMETER); + } else if ("onStop".equals(methodName)) { + SenderContext context = (SenderContext) allArguments[0]; + SpanLayer spanLayer = TaggingHelper.toLayer(context.getAllKeyValues()); + AbstractSpan abstractSpan = ContextManager.activeSpan(); + abstractSpan + .setPeer(SpanHelper.tryToGetPeer(context.getRemoteServiceAddress(), context.getAllKeyValues())) + .setOperationName(getOperationName(context)); + context.getAllKeyValues() + .forEach(keyValue -> abstractSpan.tag(Tags.ofKey(keyValue.getKey()), keyValue.getValue())); + if (spanLayer != null) { + abstractSpan.setLayer(spanLayer); + } + ContextManager.stopSpan(); + } else if ("onError".equals(methodName)) { + Observation.Context context = (Observation.Context) allArguments[0]; + ContextManager.activeSpan().log(context.getError()); + } + } + + private static String getOperationName(final SenderContext context) { + return StringUtil.isBlank( + context.getContextualName()) ? context.getName() : context.getContextualName(); + } + + @Override + public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + Object ret) throws Throwable { + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + } + +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/SpanHelper.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/SpanHelper.java new file mode 100644 index 0000000000..f98fe3d82a --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/SpanHelper.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.toolkit.activation.micrometer; + +import io.micrometer.common.KeyValue; +import io.micrometer.common.KeyValues; +import java.net.URI; + +class SpanHelper { + + static String tryToGetPeer(String remoteAddress, KeyValues allKeyValues) { + if (remoteAddress != null) { + return remoteAddress; + } + String result = allKeyValues + .stream() + .filter(keyValue -> "http.url".equalsIgnoreCase( + keyValue.getKey()) || "uri".equalsIgnoreCase(keyValue.getKey()) + || keyValue.getKey().contains("uri") || keyValue.getKey().contains("url") + ) + .findFirst() + .map(KeyValue::getValue) + .orElse("unknown"); + try { + URI uri = URI.create(result); + if (uri.getHost() == null) { + return null; + } + return uri.getHost() + ":" + uri.getPort(); + } catch (Exception ex) { + return null; + } + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/TaggingHelper.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/TaggingHelper.java new file mode 100644 index 0000000000..306be5201d --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/micrometer/TaggingHelper.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.toolkit.activation.micrometer; + +import io.micrometer.common.KeyValue; +import io.micrometer.common.KeyValues; +import java.util.Locale; +import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; + +class TaggingHelper { + + private static final String DB_TAG_PREFIX = "jdbc"; + + private static final String HTTP_TAG_PREFIX = "http"; + + private static final String RPC_TAG_PREFIX = "rpc"; + + private static final String MESSAGING_TAG_PREFIX = "messaging"; + + static SpanLayer toLayer(KeyValues keyValues) { + for (KeyValue keyValue : keyValues) { + if (keyValue.getKey().toLowerCase(Locale.ROOT).startsWith(DB_TAG_PREFIX)) { + return SpanLayer.DB; + } else if (keyValue.getKey().toLowerCase(Locale.ROOT).startsWith(HTTP_TAG_PREFIX)) { + return SpanLayer.HTTP; + } else if (keyValue.getKey().toLowerCase(Locale.ROOT).startsWith(RPC_TAG_PREFIX)) { + return SpanLayer.RPC_FRAMEWORK; + } else if (keyValue.getKey().toLowerCase(Locale.ROOT).startsWith(MESSAGING_TAG_PREFIX)) { + return SpanLayer.MQ; + } + } + return null; + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/main/resources/skywalking-plugin.def new file mode 100644 index 0000000000..4554becc22 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/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. + +micrometer-1.10.x=org.apache.skywalking.apm.toolkit.activation.micrometer.MicrometerContextManagerThreadLocalAccessorInstrumentation +micrometer-1.10.x=org.apache.skywalking.apm.toolkit.activation.micrometer.MicrometerDefaultTracingHandlerInstrumentation +micrometer-1.10.x=org.apache.skywalking.apm.toolkit.activation.micrometer.MicrometerSenderTracingHandlerInstrumentation +micrometer-1.10.x=org.apache.skywalking.apm.toolkit.activation.micrometer.MicrometerReceiverTracingHandlerInstrumentation diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/AbstractTracingSpanHelper.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/AbstractTracingSpanHelper.java new file mode 100644 index 0000000000..8e87305e74 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/AbstractTracingSpanHelper.java @@ -0,0 +1,47 @@ +/* + * 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.toolkit.activation.micrometer; + +import java.util.Collections; +import java.util.List; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.apache.skywalking.apm.agent.test.helper.FieldGetter; + +// TODO: Make a commonly used utility class out of this? +public class AbstractTracingSpanHelper { + + public static List getParentFieldLogs(AbstractTracingSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "logs"); + } catch (Exception e) { + } + + return Collections.emptyList(); + } + + public static List get2LevelParentFieldLogs(AbstractTracingSpan tracingSpan) { + try { + return FieldGetter.get2LevelParentFieldValue(tracingSpan, "logs"); + } catch (Exception e) { + } + + return Collections.emptyList(); + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/ContextManagerExtendOverrideService.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/ContextManagerExtendOverrideService.java new file mode 100644 index 0000000000..ee08457247 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/ContextManagerExtendOverrideService.java @@ -0,0 +1,26 @@ +/* + * 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.toolkit.activation.micrometer; + +import org.apache.skywalking.apm.agent.core.boot.OverrideImplementor; +import org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService; + +@OverrideImplementor(ContextManagerExtendService.class) +public class ContextManagerExtendOverrideService extends ContextManagerExtendService { +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerContextSnapshotThreadLocalAccessorInterceptorTest.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerContextSnapshotThreadLocalAccessorInterceptorTest.java new file mode 100644 index 0000000000..3e3f66c844 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerContextSnapshotThreadLocalAccessorInterceptorTest.java @@ -0,0 +1,147 @@ +/* + * 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.toolkit.activation.micrometer; + +import java.lang.reflect.Method; +import java.util.List; +import org.apache.skywalking.apm.agent.core.boot.ServiceManager; +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.ContextManagerExtendService; +import org.apache.skywalking.apm.agent.core.context.ContextSnapshot; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +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.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; +import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; +import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; +import org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingContextSnapshotThreadLocalAccessor; +import org.junit.After; +import org.junit.AfterClass; +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 static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; + +@RunWith(TracingSegmentRunner.class) +public class MicrometerContextSnapshotThreadLocalAccessorInterceptorTest { + + private final Class[] argumentTypes = new Class[] {Object.class}; + private final Method get = SkywalkingContextSnapshotThreadLocalAccessor.class.getMethod("getValue"); + private final Method set = SkywalkingContextSnapshotThreadLocalAccessor.class.getMethod("setValue", Object.class); + private final Method reset = SkywalkingContextSnapshotThreadLocalAccessor.class.getMethod("reset"); + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + @SegmentStoragePoint + private SegmentStorage segmentStorage; + @Mock + private EnhancedInstance enhancedInstance; + @Mock + private MethodInterceptResult result; + private MicrometerContextSnapshotThreadLocalAccessorInterceptor interceptor; + private ContextSnapshot context; + private Object[] consumerArguments; + private AbstractSpan testSpan; + + public MicrometerContextSnapshotThreadLocalAccessorInterceptorTest() throws NoSuchMethodException { + } + + @Before + public void setUp() throws Exception { + interceptor = new MicrometerContextSnapshotThreadLocalAccessorInterceptor(); + + Config.Agent.SERVICE_NAME = "MicrometerContextSnapshotThreadLocalAccessorTestCases-APP"; + + testSpan = ContextManager.createLocalSpan("test from threadlocalaccessor test"); + context = ContextManager.capture(); + consumerArguments = new Object[] {context}; + } + + @After + public void clear() { + assertThat(ContextManager.isActive(), is(false)); + } + + @AfterClass + public static void clearAfterAll() { + // test from threadlocalaccessor test x 2 TODO: I have no idea what is going on + ContextManager.stopSpan(); + ContextManager.stopSpan(); + assertThat(ContextManager.isActive(), is(false)); + } + + @Test + public void testServiceFromPlugin() { + PluginBootService service = ServiceManager.INSTANCE.findService( + PluginBootService.class); + + Assert.assertNotNull(service); + } + + @Test + public void testServiceOverrideFromPlugin() { + ContextManagerExtendService service = ServiceManager.INSTANCE.findService(ContextManagerExtendService.class); + + Assert.assertTrue(service instanceof ContextManagerExtendOverrideService); + } + + @Test + public void testGetSetReset() throws Throwable { + ContextSnapshot contextSnapshot = (ContextSnapshot) interceptor.afterMethod( + enhancedInstance, get, new Object[0], new Class[0], result); + + ContextSnapshot currentCapturedContext = ContextManager.capture(); + assertThat(currentCapturedContext, not(equalTo(contextSnapshot))); + assertThat(currentCapturedContext.getTraceId(), equalTo(contextSnapshot.getTraceId())); + + ContextManager.stopSpan(); + + interceptor.afterMethod( + enhancedInstance, set, consumerArguments, argumentTypes, result); + + ContextManager.stopSpan(); + + assertThat(segmentStorage.getTraceSegments().size(), is(2)); + TraceSegment parent = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(parent); + assertThat(spans.size(), is(1)); + String operationName = spans.get(0).getOperationName(); + assertThat(operationName, is("test from threadlocalaccessor test")); + + TraceSegment continuedParent = segmentStorage.getTraceSegments().get(1); + assertThat(continuedParent.getRef().getParentEndpoint(), is(operationName)); + + interceptor.afterMethod( + enhancedInstance, reset, new Object[0], new Class[0], result); + + assertThat(ContextManager.isActive(), is(false)); + } + +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerDefaultTracingHandlerInterceptorTest.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerDefaultTracingHandlerInterceptorTest.java new file mode 100644 index 0000000000..9fc3f6bf58 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerDefaultTracingHandlerInterceptorTest.java @@ -0,0 +1,166 @@ +/* + * 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.toolkit.activation.micrometer; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.ObservationHandler; +import java.lang.reflect.Method; +import java.util.List; +import org.apache.skywalking.apm.agent.core.boot.ServiceManager; +import org.apache.skywalking.apm.agent.core.conf.Config; +import org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.context.util.KeyValuePair; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; +import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; +import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; +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 static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@RunWith(TracingSegmentRunner.class) +public class MicrometerDefaultTracingHandlerInterceptorTest { + + private final Observation.Context context = new Observation.Context(); + private final Observation.Event event = new Observation.Event() { + @Override + public String getContextualName() { + return "eventContextualName"; + } + + @Override + public String getName() { + return "eventName"; + } + }; + private final Object[] consumerArguments = new Object[] {context}; + private final Object[] eventArguments = new Object[] { + event, + context + }; + private final Class[] argumentTypes = new Class[] {Observation.Context.class}; + private final Class[] eventArgumentTypes = new Class[] { + Observation.Event.class, + Observation.Context.class + }; + private final Method onStart = ObservationHandler.class.getMethod("onStart", Observation.Context.class); + private final Method onStop = ObservationHandler.class.getMethod("onStop", Observation.Context.class); + private final Method onError = ObservationHandler.class.getMethod("onError", Observation.Context.class); + private final Method onEvent = ObservationHandler.class.getMethod( + "onEvent", Observation.Event.class, Observation.Context.class); + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + @SegmentStoragePoint + private SegmentStorage segmentStorage; + @Mock + private EnhancedInstance enhancedInstance; + @Mock + private MethodInterceptResult result; + private MicrometerDefaultTracingHandlerInterceptor interceptor; + + public MicrometerDefaultTracingHandlerInterceptorTest() throws NoSuchMethodException { + } + + @Before + public void setUp() throws Exception { + context.setName("name"); + context.setContextualName("contextualName"); + + interceptor = new MicrometerDefaultTracingHandlerInterceptor(); + + Config.Agent.SERVICE_NAME = "MicrometerTestCases-APP"; + } + + @Test + public void testServiceFromPlugin() { + PluginBootService service = ServiceManager.INSTANCE.findService( + PluginBootService.class); + + Assert.assertNotNull(service); + } + + @Test + public void testServiceOverrideFromPlugin() { + ContextManagerExtendService service = ServiceManager.INSTANCE.findService(ContextManagerExtendService.class); + + Assert.assertTrue(service instanceof ContextManagerExtendOverrideService); + } + + @Test + public void testDefaultStartEventStop() throws Throwable { + interceptor.beforeMethod( + enhancedInstance, onStart, consumerArguments, argumentTypes, result); + interceptor.beforeMethod( + enhancedInstance, onEvent, eventArguments, eventArgumentTypes, result); + interceptor.beforeMethod( + enhancedInstance, onStop, consumerArguments, argumentTypes, result); + + AbstractTracingSpan abstractTracingSpan = onlySpan(); + assertThat(abstractTracingSpan.getOperationName(), equalTo("contextualName")); + List logs = AbstractTracingSpanHelper.getParentFieldLogs(abstractTracingSpan); + assertThat(logs.size(), is(1)); + LogDataEntity logDataEntity = logs.get(0); + assertThat(logDataEntity.getLogs().size(), is(1)); + KeyValuePair keyValuePair = logDataEntity.getLogs().get(0); + assertThat(keyValuePair.getKey(), equalTo("event")); + assertThat(keyValuePair.getValue(), equalTo("eventContextualName")); + } + + @Test + public void testDefaultStartExceptionStop() throws Throwable { + interceptor.beforeMethod( + enhancedInstance, onStart, consumerArguments, argumentTypes, result); + context.setError(new RuntimeException("BOOM")); + interceptor.beforeMethod( + enhancedInstance, onError, consumerArguments, argumentTypes, result); + interceptor.beforeMethod( + enhancedInstance, onStop, consumerArguments, argumentTypes, result); + + AbstractTracingSpan abstractTracingSpan = onlySpan(); + assertThat(abstractTracingSpan.getOperationName(), equalTo("contextualName")); + List logs = AbstractTracingSpanHelper.getParentFieldLogs(abstractTracingSpan); + assertThat(logs.size(), is(1)); + assertThat(logs.get(0).getLogs().size(), is(4)); // 4 events represent an exception + KeyValuePair errorLog = logs.get(0).getLogs().get(0); + assertThat(errorLog.getKey(), equalTo("event")); + assertThat(errorLog.getValue(), equalTo("error")); + } + + private AbstractTracingSpan onlySpan() { + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + AbstractTracingSpan abstractTracingSpan = spans.get(0); + return abstractTracingSpan; + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerReceiverTracingHandlerInterceptorTest.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerReceiverTracingHandlerInterceptorTest.java new file mode 100644 index 0000000000..440e632f8d --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerReceiverTracingHandlerInterceptorTest.java @@ -0,0 +1,138 @@ +/* + * 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.toolkit.activation.micrometer; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.transport.ReceiverContext; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.skywalking.apm.agent.core.boot.ServiceManager; +import org.apache.skywalking.apm.agent.core.conf.Config; +import org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.context.util.KeyValuePair; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; +import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; +import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; +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 static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@RunWith(TracingSegmentRunner.class) +public class MicrometerReceiverTracingHandlerInterceptorTest { + + private final ReceiverContext> context = new ReceiverContext<>( + (carrier, key) -> carrier.get(key)); + private final Object[] consumerArguments = new Object[] {context}; + private final Class[] argumentTypes = new Class[] {ReceiverContext.class}; + private final Method onStart = ObservationHandler.class.getMethod("onStart", Observation.Context.class); + private final Method onStop = ObservationHandler.class.getMethod("onStop", Observation.Context.class); + private final Method onError = ObservationHandler.class.getMethod("onError", Observation.Context.class); + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + @SegmentStoragePoint + private SegmentStorage segmentStorage; + @Mock + private EnhancedInstance enhancedInstance; + @Mock + private MethodInterceptResult result; + private MicrometerReceiverTracingHandlerInterceptor interceptor; + + public MicrometerReceiverTracingHandlerInterceptorTest() throws NoSuchMethodException { + } + + @Before + public void setUp() throws Exception { + context.setName("name"); + context.setContextualName("contextualName"); + Map map = new HashMap<>(); + map.put( + "sw8", + "1-Njc3OTM1ZDM4ZTFiNDAwMzk3NDU4MjI2OTM4YWU3MmIuMS4xNjY5NjM5MDI1ODE1MDAwMQ==-Njc3OTM1ZDM4ZTFiNDAwMzk3NDU4MjI2OTM4YWU3MmIuMS4xNjY5NjM5MDI1ODE1MDAwMA==-0-TWljcm9tZXRlclJlY2VpdmVyVGVzdENhc2VzLUFQUA==-YWU5YWZkM2YxMDg0NGYzMzg1MGZlOGQwYzRkNzYwYTdAMTAuMTUuMTguMTE1-Y29udGV4dHVhbE5hbWU=-aHR0cDovL2xvY2FsaG9zdDo4MDgw" + ); + map.put("sw8-correlation", ""); + map.put("sw8-x", "0- "); + context.setCarrier(map); + + interceptor = new MicrometerReceiverTracingHandlerInterceptor(); + + Config.Agent.SERVICE_NAME = "MicrometerReceiverTestCases-APP"; + } + + @Test + public void testServiceFromPlugin() { + PluginBootService service = ServiceManager.INSTANCE.findService( + PluginBootService.class); + + Assert.assertNotNull(service); + } + + @Test + public void testServiceOverrideFromPlugin() { + ContextManagerExtendService service = ServiceManager.INSTANCE.findService(ContextManagerExtendService.class); + + Assert.assertTrue(service instanceof ContextManagerExtendOverrideService); + } + + @Test + public void testDefaultStartExceptionStop() throws Throwable { + interceptor.beforeMethod( + enhancedInstance, onStart, consumerArguments, argumentTypes, result); + context.setError(new RuntimeException("BOOM")); + interceptor.beforeMethod( + enhancedInstance, onError, consumerArguments, argumentTypes, result); + interceptor.beforeMethod( + enhancedInstance, onStop, consumerArguments, argumentTypes, result); + + AbstractTracingSpan abstractTracingSpan = onlySpan(); + assertThat(abstractTracingSpan.getOperationName(), equalTo("contextualName")); + assertThat(abstractTracingSpan.isEntry(), is(true)); + List logs = AbstractTracingSpanHelper.get2LevelParentFieldLogs(abstractTracingSpan); + assertThat(logs.size(), is(1)); + assertThat(logs.get(0).getLogs().size(), is(4)); // 4 events represent an exception + KeyValuePair errorLog = logs.get(0).getLogs().get(0); + assertThat(errorLog.getKey(), equalTo("event")); + assertThat(errorLog.getValue(), equalTo("error")); + } + + private AbstractTracingSpan onlySpan() { + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + AbstractTracingSpan abstractTracingSpan = spans.get(0); + return abstractTracingSpan; + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerSenderTracingHandlerInterceptorTest.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerSenderTracingHandlerInterceptorTest.java new file mode 100644 index 0000000000..7acfed95b9 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/MicrometerSenderTracingHandlerInterceptorTest.java @@ -0,0 +1,137 @@ +/* + * 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.toolkit.activation.micrometer; + +import io.micrometer.observation.Observation; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.transport.ReceiverContext; +import io.micrometer.observation.transport.SenderContext; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.apache.skywalking.apm.agent.core.boot.ServiceManager; +import org.apache.skywalking.apm.agent.core.conf.Config; +import org.apache.skywalking.apm.agent.core.context.ContextManagerExtendService; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.context.util.KeyValuePair; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; +import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; +import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; +import org.hamcrest.CoreMatchers; +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 static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +@RunWith(TracingSegmentRunner.class) +public class MicrometerSenderTracingHandlerInterceptorTest { + + private final SenderContext> context = new SenderContext<>( + (carrier, key, value) -> carrier.put(key, value)); + private final Map carrier = new HashMap<>(); + private final Object[] consumerArguments = new Object[] {context}; + private final Class[] argumentTypes = new Class[] {ReceiverContext.class}; + private final Method onStart = ObservationHandler.class.getMethod("onStart", Observation.Context.class); + private final Method onStop = ObservationHandler.class.getMethod("onStop", Observation.Context.class); + private final Method onError = ObservationHandler.class.getMethod("onError", Observation.Context.class); + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + @SegmentStoragePoint + private SegmentStorage segmentStorage; + @Mock + private EnhancedInstance enhancedInstance; + @Mock + private MethodInterceptResult result; + private MicrometerSenderTracingHandlerInterceptor interceptor; + + public MicrometerSenderTracingHandlerInterceptorTest() throws NoSuchMethodException { + } + + @Before + public void setUp() throws Exception { + context.setName("name"); + context.setContextualName("contextualName"); + context.setCarrier(carrier); + context.setRemoteServiceAddress("http://localhost:8080"); + + interceptor = new MicrometerSenderTracingHandlerInterceptor(); + + Config.Agent.SERVICE_NAME = "MicrometerSenderTestCases-APP"; + } + + @Test + public void testServiceFromPlugin() { + PluginBootService service = ServiceManager.INSTANCE.findService( + PluginBootService.class); + + Assert.assertNotNull(service); + } + + @Test + public void testServiceOverrideFromPlugin() { + ContextManagerExtendService service = ServiceManager.INSTANCE.findService(ContextManagerExtendService.class); + + Assert.assertTrue(service instanceof ContextManagerExtendOverrideService); + } + + @Test + public void testDefaultStartExceptionStop() throws Throwable { + interceptor.beforeMethod( + enhancedInstance, onStart, consumerArguments, argumentTypes, result); + context.setError(new RuntimeException("BOOM")); + interceptor.beforeMethod( + enhancedInstance, onError, consumerArguments, argumentTypes, result); + interceptor.beforeMethod( + enhancedInstance, onStop, consumerArguments, argumentTypes, result); + + AbstractTracingSpan abstractTracingSpan = onlySpan(); + assertThat(abstractTracingSpan.getOperationName(), equalTo("contextualName")); + assertThat(abstractTracingSpan.isExit(), is(true)); + List logs = AbstractTracingSpanHelper.get2LevelParentFieldLogs(abstractTracingSpan); + assertThat(logs.size(), is(1)); + assertThat(logs.get(0).getLogs().size(), is(4)); // 4 events represent an exception + KeyValuePair errorLog = logs.get(0).getLogs().get(0); + assertThat(errorLog.getKey(), equalTo("event")); + assertThat(errorLog.getValue(), equalTo("error")); + assertThat( + carrier.keySet(), CoreMatchers.hasItems("sw8", "sw8-correlation", "sw8-x")); // headers got instrumented + } + + private AbstractTracingSpan onlySpan() { + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + AbstractTracingSpan abstractTracingSpan = spans.get(0); + return abstractTracingSpan; + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/PluginBootService.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/PluginBootService.java new file mode 100644 index 0000000000..48d8a4bbb4 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/java/org/apache/skywalking/apm/toolkit/activation/micrometer/PluginBootService.java @@ -0,0 +1,43 @@ +/* + * 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.toolkit.activation.micrometer; + +import org.apache.skywalking.apm.agent.core.boot.BootService; + +public class PluginBootService implements BootService { + @Override + public void prepare() throws Throwable { + + } + + @Override + public void boot() throws Throwable { + + } + + @Override + public void onComplete() throws Throwable { + + } + + @Override + public void shutdown() throws Throwable { + + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService new file mode 100644 index 0000000000..65298a217f --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-micrometer-activation/src/test/resources/META-INF/services/org.apache.skywalking.apm.agent.core.boot.BootService @@ -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. +# +# + +org.apache.skywalking.apm.toolkit.activation.micrometer.PluginBootService +org.apache.skywalking.apm.toolkit.activation.micrometer.ContextManagerExtendOverrideService diff --git a/apm-sniffer/apm-toolkit-activation/pom.xml b/apm-sniffer/apm-toolkit-activation/pom.xml index ee30825677..d89eb12f78 100644 --- a/apm-sniffer/apm-toolkit-activation/pom.xml +++ b/apm-sniffer/apm-toolkit-activation/pom.xml @@ -33,6 +33,7 @@ apm-toolkit-opentracing-activation apm-toolkit-trace-activation apm-toolkit-meter-activation + apm-toolkit-micrometer-activation apm-toolkit-webflux-activation apm-toolkit-logging-common diff --git a/docs/en/setup/service-agent/java-agent/Application-toolkit-micrometer-1.10.md b/docs/en/setup/service-agent/java-agent/Application-toolkit-micrometer-1.10.md new file mode 100644 index 0000000000..840cbb5db9 --- /dev/null +++ b/docs/en/setup/service-agent/java-agent/Application-toolkit-micrometer-1.10.md @@ -0,0 +1,32 @@ +# Observations + +* Dependency the toolkit, such as using maven or gradle +```xml + + org.apache.skywalking + apm-toolkit-micrometer-1.10 + ${skywalking.version} + +``` + +* To use the Micrometer Observation Registry with Skywalking, you need to add handlers to the registry. Skywalking comes +with dedicated `SkywalkingMeterHandler` (for metrics) and `SkywalkingSenderTracingHandler`, `SkywalkingReceiverTracingHandler` +`SkywalkingDefaultTracingHandler` (for traces). + +```java +// Here we create the Observation Registry with attached handlers +ObservationRegistry registry = ObservationRegistry.create(); +// Here we add a meter handler +registry.observationConfig() + .observationHandler(new ObservationHandler.FirstMatchingCompositeObservationHandler( + new SkywalkingMeterHandler(new SkywalkingMeterRegistry()) +); +// Here we add tracing handlers +registry.observationConfig() + .observationHandler(new ObservationHandler.FirstMatchingCompositeObservationHandler( + new SkywalkingSenderTracingHandler(), new SkywalkingReceiverTracingHandler(), + new SkywalkingDefaultTracingHandler() + )); +``` + +With such setup metrics and traces will be created for any Micrometer Observation based instrumentations. diff --git a/docs/en/setup/service-agent/java-agent/Application-toolkit-micrometer.md b/docs/en/setup/service-agent/java-agent/Application-toolkit-micrometer.md index 63e49cafaf..06de225d6a 100644 --- a/docs/en/setup/service-agent/java-agent/Application-toolkit-micrometer.md +++ b/docs/en/setup/service-agent/java-agent/Application-toolkit-micrometer.md @@ -1,3 +1,5 @@ +# Metrics + * Dependency the toolkit, such as using maven or gradle ```xml 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 748cd380cc..9d5ff07a43 100644 --- a/docs/en/setup/service-agent/java-agent/Plugin-list.md +++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md @@ -56,6 +56,7 @@ - lettuce-5.x - light4j - mariadb-2.x +- micrometer-1.10.x - memcache-2.x - mongodb-2.x - mongodb-3.x diff --git a/docs/en/setup/service-agent/java-agent/advanced-features.md b/docs/en/setup/service-agent/java-agent/advanced-features.md index 518bf51163..96302df680 100644 --- a/docs/en/setup/service-agent/java-agent/advanced-features.md +++ b/docs/en/setup/service-agent/java-agent/advanced-features.md @@ -7,7 +7,7 @@ * If you want your codes to interact with SkyWalking agent, including `getting trace id`, `setting tags`, `propagating custom data` etc.. Try [SkyWalking manual APIs](Application-toolkit-trace.md). * If you require customized metrics, try [SkyWalking Meter System Toolkit](Application-toolkit-meter.md). * If you want to continue traces across thread manually, use [across thread solution APIs](Application-toolkit-trace-cross-thread.md). - * If you want to forward MicroMeter/Spring Sleuth metrics to Meter System, use [SkyWalking MicroMeter Register](Application-toolkit-micrometer.md). + * If you want to forward Micrometer metrics / observations, use [SkyWalking Micrometer Register](Application-toolkit-micrometer.md). * If you want to use OpenTracing Java APIs, try [SkyWalking OpenTracing compatible tracer](Opentracing.md). More details you could find at http://opentracing.io * If you want to tolerate some exceptions, read [tolerate custom exception doc](How-to-tolerate-exceptions.md). * If you want to print trace context(e.g. traceId) in your logs, or collect logs, choose the log frameworks, [log4j](Application-toolkit-log4j-1.x.md), [log4j2](Application-toolkit-log4j-2.x.md), [logback](Application-toolkit-logback-1.x.md). diff --git a/docs/menu.yml b/docs/menu.yml index 13ca93a3b5..3ee510f3a7 100644 --- a/docs/menu.yml +++ b/docs/menu.yml @@ -44,8 +44,10 @@ catalog: path: "/en/setup/service-agent/java-agent/application-toolkit-meter" - name: "Across Thread Solution" path: "/en/setup/service-agent/java-agent/application-toolkit-trace-cross-thread" - - name: "MicroMeter Registry" + - name: "Micrometer Registry" path: "/en/setup/service-agent/java-agent/application-toolkit-micrometer" + - name: "Micrometer 1.10 Observation" + path: "/en/setup/service-agent/java-agent/application-toolkit-micrometer-1.10" - name: "Webflux Tracing Assistant APIs" path: "/en/setup/service-agent/java-agent/application-toolkit-webflux" - name: "Kafka Tracing Assistant APIs" diff --git a/pom.xml b/pom.xml index c58790f429..1e64fc68c9 100755 --- a/pom.xml +++ b/pom.xml @@ -391,6 +391,7 @@ ${project.build.sourceDirectory} ${project.build.testSourceDirectory} +scenarios/resttemplate-6.x-scenario **/*.properties, diff --git a/test/plugin/agent-test-tools/pom.xml b/test/plugin/agent-test-tools/pom.xml index 7238da230c..374263e7f4 100644 --- a/test/plugin/agent-test-tools/pom.xml +++ b/test/plugin/agent-test-tools/pom.xml @@ -35,7 +35,7 @@ pom - 1c0bef2dd1d828e07889302bea980b24900b0db5 + cf62c1b733fe2861229201a67b9cc0075ac3e236 ${project.basedir}/target/agent-test-tools https://github.com/apache/skywalking-agent-test-tool.git diff --git a/test/plugin/containers/tomcat-container/src/main/docker/run.sh b/test/plugin/containers/tomcat-container/src/main/docker/run.sh index 9219055478..7ec99dc966 100644 --- a/test/plugin/containers/tomcat-container/src/main/docker/run.sh +++ b/test/plugin/containers/tomcat-container/src/main/docker/run.sh @@ -57,7 +57,7 @@ export LOGS_HOME=${SCENARIO_HOME}/logs # share to catalina.sh # Speed up launch tomcat rm /usr/local/tomcat/webapps/* -rf # remove needn't app -sed -i "s%securerandom.source=file:/dev/random%securerandom.source=file:/dev/urandom%g" $JAVA_HOME/jre/lib/security/java.security +sed -i "s%securerandom.source=file:/dev/random%securerandom.source=file:/dev/urandom%g" $JAVA_HOME/jre/lib/security/java.security || echo "Failed to speed up tomcat launch - will continue" # To deploy testcase cp ${SCENARIO_HOME}/*.war /usr/local/tomcat/webapps/ diff --git a/test/plugin/run.sh b/test/plugin/run.sh index 3d3e164839..25dc8da643 100755 --- a/test/plugin/run.sh +++ b/test/plugin/run.sh @@ -33,7 +33,7 @@ num_of_testcases= container_image_version="1.0.0" base_image_java="eclipse-temurin:8-jdk" base_image_tomcat="tomcat:8.5-jdk8-openjdk" -jacoco_version="${JACOCO_VERSION:-0.8.6}" +jacoco_version="${JACOCO_VERSION:-0.8.8}" os="$(uname)" diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/bin/startup.sh b/test/plugin/scenarios/resttemplate-6.x-scenario/bin/startup.sh new file mode 100644 index 0000000000..197feca45a --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/bin/startup.sh @@ -0,0 +1,23 @@ +#!/bin/bash +# +# 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. + +home="$(cd "$(dirname $0)"; pwd)" + +export SW_EXCLUDE_PLUGINS=spring-mvc-annotation,spring-mvc-annotation-3.x,spring-mvc-annotation-4.x,spring-mvc-annotation-5.x,spring-resttemplate-4.x,tomcat-7.x/8.x,tomcat-10.x + +java -jar ${agent_opts} ${home}/../libs/resttemplate-6.x-scenario.jar & diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/resttemplate-6.x-scenario/config/expectedData.yaml new file mode 100644 index 0000000000..3f43202211 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/config/expectedData.yaml @@ -0,0 +1,83 @@ +# 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. +segmentItems: + - serviceName: resttemplate-6.x-scenario + segmentSize: ge 2 + segments: + - segmentId: not null + spans: + - operationName: http get /resttemplate/syncback + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 141 + isError: false + spanType: Entry + peer: '' + tags: + - {key: exception, value: none} + - {key: http.url, value: '/resttemplate-6.x-scenario/resttemplate/syncback'} + - {key: method, value: GET} + - {key: outcome, value: SUCCESS} + - {key: status, value: '200'} + - {key: uri, value: '/resttemplate/syncback'} + refs: + - {parentEndpoint: http.server.requests, + networkAddress: 'localhost:8080', refType: CrossProcess, parentSpanId: 1, + parentTraceSegmentId: not null, parentServiceInstance: not null, parentService: resttemplate-6.x-scenario, + traceId: not null} + skipAnalysis: 'false' + - segmentId: not null + spans: + - operationName: http get + parentSpanId: 0 + spanId: 1 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 141 + isError: false + spanType: Exit + peer: localhost:8080 + tags: + - {key: client.name, value: 'localhost'} + - {key: exception, value: none} + - {key: http.url, value: 'http://localhost:8080/resttemplate-6.x-scenario/resttemplate/syncback'} + - {key: method, value: GET} + - {key: outcome, value: SUCCESS} + - {key: status, value: '200'} + - {key: uri, value: 'http://localhost:8080/resttemplate-6.x-scenario/resttemplate/syncback'} + skipAnalysis: 'false' + - operationName: http get /resttemplate/case/resttemplate + parentSpanId: -1 + spanId: 0 + spanLayer: Http + startTime: nq 0 + endTime: nq 0 + componentId: 141 + isError: false + spanType: Entry + peer: '' + tags: + - {key: exception, value: none} + - {key: http.url, value: '/resttemplate-6.x-scenario/resttemplate/case/resttemplate'} + - {key: method, value: GET} + - {key: outcome, value: SUCCESS} + - {key: status, value: '200'} + - {key: uri, value: '/resttemplate/case/resttemplate'} + skipAnalysis: 'false' diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/configuration.yml b/test/plugin/scenarios/resttemplate-6.x-scenario/configuration.yml new file mode 100644 index 0000000000..6c36262563 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/configuration.yml @@ -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. +type: jvm +entryService: http://localhost:8080/resttemplate-6.x-scenario/resttemplate/case/resttemplate +healthCheck: http://localhost:8080/resttemplate-6.x-scenario/resttemplate/case/healthcheck +startScript: ./bin/startup.sh diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/pom.xml b/test/plugin/scenarios/resttemplate-6.x-scenario/pom.xml new file mode 100644 index 0000000000..93eeeb38f6 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/pom.xml @@ -0,0 +1,111 @@ + + + + 4.0.0 + + org.apache.skywalking + resttemplate-6.x-scenario + 6.5.0 + jar + + + UTF-8 + UTF-8 + 17 + 6.0.2 + ${test.framework.version} + 3.0.0 + + + + + + + skywalking-resttemplate-6.x-scenario + + + + org.springframework.boot + spring-boot-starter-web + ${spring-boot.version} + + + org.apache.skywalking + apm-toolkit-micrometer-1.10 + ${sw.version} + + + org.springframework + spring-webmvc + ${test.framework.version} + + + + + resttemplate-6.x-scenario + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + repackage + + + + + + maven-compiler-plugin + 3.6.0 + + ${compiler.version} + ${compiler.version} + ${project.build.sourceEncoding} + + + + org.apache.maven.plugins + maven-assembly-plugin + + + assemble + package + + single + + + + src/main/assembly/assembly.xml + + ./target/ + + + + + + + diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/assembly/assembly.xml new file mode 100644 index 0000000000..0f6f7a5529 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/assembly/assembly.xml @@ -0,0 +1,41 @@ + + + + + zip + + + + + ./bin + 0775 + + + + + + ./target/resttemplate-6.x-scenario.jar + ./libs + 0775 + + + diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/BackController.java b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/BackController.java new file mode 100644 index 0000000000..963c7f389f --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/BackController.java @@ -0,0 +1,40 @@ +/* + * 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.testcase.resttemplate; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.http.HttpHeaders; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +@RequestMapping("/resttemplate") +public class BackController { + private static final Logger LOGGER = LogManager.getLogger(BackController.class); + + @GetMapping("/syncback") + public String syncBack(@RequestHeader HttpHeaders httpHeaders) { + LOGGER.info("Got following headers " + httpHeaders); + return "Hello back"; + } + +} diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/FrontController.java b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/FrontController.java new file mode 100644 index 0000000000..eb46b9aa7c --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/FrontController.java @@ -0,0 +1,54 @@ +/* + * 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.testcase.resttemplate; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.RestTemplate; + +@RestController +@RequestMapping("/resttemplate/case") +public class FrontController { + + @Value("${server.port:8080}") + int port; + + @Autowired + private RestTemplate restTemplate; + + @GetMapping(value = "/healthcheck") + public String healthcheck() { + return "Success"; + } + + @GetMapping("/resttemplate") + public String front() { + syncRequest("http://localhost:" + port + "/resttemplate-6.x-scenario/resttemplate/syncback"); + return "Success"; + } + + private String syncRequest(String url) { + restTemplate.getForObject(url, String.class); + + return "Success"; + } +} diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ObservationConfiguration.java b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ObservationConfiguration.java new file mode 100644 index 0000000000..e171c41204 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ObservationConfiguration.java @@ -0,0 +1,87 @@ +/* + * 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.testcase.resttemplate; + +import io.micrometer.core.instrument.MeterRegistry; +import io.micrometer.core.instrument.observation.MeterObservationHandler; +import io.micrometer.observation.ObservationHandler; +import io.micrometer.observation.ObservationRegistry; +import jakarta.annotation.PreDestroy; +import java.util.List; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.skywalking.apm.meter.micrometer.SkywalkingMeterRegistry; +import org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingDefaultTracingHandler; +import org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingMeterHandler; +import org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingReceiverTracingHandler; +import org.apache.skywalking.apm.toolkit.micrometer.observation.SkywalkingSenderTracingHandler; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration(proxyBeanMethods = false) +class ObservationConfiguration { + private static final Logger LOGGER = LogManager.getLogger(ObservationConfiguration.class); + + @Bean + ObservationRegistry observationRegistry(List> handlers) { + ObservationRegistry registry = ObservationRegistry.create(); + registry.observationConfig() + .observationHandler(new ObservationHandler.FirstMatchingCompositeObservationHandler(handlers)); + registry.observationConfig() + .observationHandler(new ObservationHandler.FirstMatchingCompositeObservationHandler( + new SkywalkingSenderTracingHandler(), new SkywalkingReceiverTracingHandler(), + new SkywalkingDefaultTracingHandler() + )); + return registry; + } + + @Bean + SkywalkingMeterRegistry meterRegistry() { + return new SkywalkingMeterRegistry(); + } + + @Bean + MeterObservationHandler meterObservationHandler(SkywalkingMeterRegistry skywalkingMeterRegistry) { + return new SkywalkingMeterHandler(skywalkingMeterRegistry); + } + + @Bean + MetricsDumper metricsDumper(MeterRegistry meterRegistry) { + return new MetricsDumper(meterRegistry); + } + + static class MetricsDumper { + private final MeterRegistry meterRegistry; + + MetricsDumper(MeterRegistry meterRegistry) { + this.meterRegistry = meterRegistry; + } + + @PreDestroy + void dumpMetrics() { + LOGGER.info("==== METRICS ===="); + this.meterRegistry.getMeters() + .forEach(meter -> LOGGER.info( + " - Metric type \t[" + meter.getId().getType() + "],\tname [" + meter.getId() + .getName() + "],\ttags " + meter.getId() + .getTags() + ",\tmeasurements " + meter.measure())); + LOGGER.info("================="); + } + } +} diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ResttemplateConfiguration.java b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ResttemplateConfiguration.java new file mode 100644 index 0000000000..136929f9e9 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ResttemplateConfiguration.java @@ -0,0 +1,36 @@ +/* + * 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.testcase.resttemplate; + +import io.micrometer.observation.ObservationRegistry; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; + +@Configuration +public class ResttemplateConfiguration { + + @Bean + public RestTemplate restTemplate(ObservationRegistry observationRegistry) { + RestTemplate restTemplate = new RestTemplate(); + restTemplate.setObservationRegistry(observationRegistry); + return restTemplate; + } + +} diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ServerConfiguration.java b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ServerConfiguration.java new file mode 100644 index 0000000000..a73bad9565 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/ServerConfiguration.java @@ -0,0 +1,42 @@ +/* + * 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.testcase.resttemplate; + +import io.micrometer.observation.ObservationRegistry; +import jakarta.servlet.DispatcherType; +import java.util.Arrays; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.web.filter.ServerHttpObservationFilter; + +@Configuration +public class ServerConfiguration { + + @Bean + FilterRegistrationBean testServerHttpObservationFilter(ObservationRegistry observationRegistry) { + FilterRegistrationBean registration = new FilterRegistrationBean( + new ServerHttpObservationFilter(observationRegistry)); + registration.setOrder(Ordered.HIGHEST_PRECEDENCE + 1); + registration.setDispatcherTypes(DispatcherType.REQUEST, DispatcherType.ASYNC); + registration.setUrlPatterns(Arrays.asList("/resttemplate/syncback", "/resttemplate/case/resttemplate")); + return registration; + } +} diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/SkywalkingApplication.java b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/SkywalkingApplication.java new file mode 100644 index 0000000000..3c5584891b --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/java/org/apache/skywalking/testcase/resttemplate/SkywalkingApplication.java @@ -0,0 +1,33 @@ +/* + * 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.testcase.resttemplate; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class SkywalkingApplication { + + public static void main(String[] args) { + SpringApplication.run(SkywalkingApplication.class, args); + } + +} + + diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/resources/application.yml b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/resources/application.yml new file mode 100644 index 0000000000..dde3d2be03 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/resources/application.yml @@ -0,0 +1,21 @@ +# 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. + +server: + port: 8080 + servlet: + context-path: /resttemplate-6.x-scenario + diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/resources/log4j2.xml new file mode 100644 index 0000000000..985bd03bf3 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/src/main/resources/log4j2.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/plugin/scenarios/resttemplate-6.x-scenario/support-version.list b/test/plugin/scenarios/resttemplate-6.x-scenario/support-version.list new file mode 100644 index 0000000000..ed0abbe6d7 --- /dev/null +++ b/test/plugin/scenarios/resttemplate-6.x-scenario/support-version.list @@ -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. + +6.0.2