From c1bea7a6bf63be9f2ab6f778b37bea491194e878 Mon Sep 17 00:00:00 2001 From: yanrongzhen Date: Sun, 30 Apr 2023 09:57:12 +0800 Subject: [PATCH] Complete the configuration analysis of SpringBoot 1.x and 2.x versions with spring-boot agent plugins. (#1207) * Remove dependency-reduced-pom.xml from the agent core module. * Complete the configuration analysis of SpringBoot 1.x and 2.x versions through spring-boot agent plugins. --- .../dependency-reduced-pom.xml | 235 ------------------ .../agent/core/boot/SpringBootConfig.java | 33 +++ .../boot/SpringBootConfigInitializer.java | 83 +++++++ .../core/plugin/loader/AgentClassLoader.java | 11 +- hippo4j-agent/hippo4j-agent-plugin/pom.xml | 85 ++++++- .../spring-plugins/pom.xml | 50 ++++ .../spring-boot-1.x-plugin/pom.xml | 33 +++ .../EventPublishingFinishedInterceptor.java | 58 +++++ ...tPublishingRunListenerInstrumentation.java | 68 +++++ .../src/main/resources/hippo4j-plugin.def | 17 ++ .../spring-boot-2.x-plugin/pom.xml | 33 +++ .../v2/EventPublishingStartedInterceptor.java | 50 ++++ ...tPublishingRunListenerInstrumentation.java | 68 +++++ .../src/main/resources/hippo4j-plugin.def | 17 ++ .../spring-plugin-common/pom.xml | 22 ++ .../spring/common/SpringPropertiesLoader.java | 66 +++++ hippo4j-agent/pom.xml | 3 - .../state/ThreadPoolRunStateHandlerTest.java | 4 +- 18 files changed, 690 insertions(+), 246 deletions(-) delete mode 100644 hippo4j-agent/hippo4j-agent-core/dependency-reduced-pom.xml create mode 100644 hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/boot/SpringBootConfig.java create mode 100644 hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/boot/SpringBootConfigInitializer.java create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/pom.xml create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/pom.xml create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/EventPublishingFinishedInterceptor.java create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/define/EventPublishingRunListenerInstrumentation.java create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/resources/hippo4j-plugin.def create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/pom.xml create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/EventPublishingStartedInterceptor.java create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/define/EventPublishingRunListenerInstrumentation.java create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/resources/hippo4j-plugin.def create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/pom.xml create mode 100644 hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/SpringPropertiesLoader.java diff --git a/hippo4j-agent/hippo4j-agent-core/dependency-reduced-pom.xml b/hippo4j-agent/hippo4j-agent-core/dependency-reduced-pom.xml deleted file mode 100644 index 427411d8..00000000 --- a/hippo4j-agent/hippo4j-agent-core/dependency-reduced-pom.xml +++ /dev/null @@ -1,235 +0,0 @@ - - - - hippo4j-agent - cn.hippo4j - ${revision} - - 4.0.0 - hippo4j-agent-core - - - - kr.motd.maven - os-maven-plugin - ${os-maven-plugin.version} - - - initialize - - detect - - - - - - maven-shade-plugin - - - package - - shade - - - - - net.bytebuddy:byte-buddy:jar: - com.google.errorprone:error_prone_annotations:jar: - com.google.code.findbugs:jsr305:jar: - com.google.android:annotations:jar: - com.google.api.grpc:proto-google-common-protos:jar: - org.checkerframework:checker-compat-qual:jar: - org.codehaus.mojo:animal-sniffer-annotations:jar: - - - - - ${shade.com.google.source} - ${shade.com.google.target} - - - ${shade.io.grpc.source} - ${shade.io.grpc.target} - - - ${shade.io.netty.source} - ${shade.io.netty.target} - - - ${shade.io.opencensus.source} - ${shade.io.opencensus.target} - - - ${shade.io.perfmark.source} - ${shade.io.perfmark.target} - - - ${shade.org.slf4j.source} - ${shade.org.slf4j.target} - - - - - com.google.protobuf:protobuf-java - - google/protobuf/*.proto - google/protobuf/compiler/*.proto - - - - - - - - - - - - - - - net.bytebuddy - byte-buddy - 1.12.13 - compile - - - org.projectlombok - lombok - 1.18.20 - provided - - - net.bytebuddy - byte-buddy-agent - 1.12.13 - test - - - com.github.tomakehurst - wiremock - 2.16.0 - test - - - jackson-annotations - com.fasterxml.jackson.core - - - jackson-core - com.fasterxml.jackson.core - - - jackson-databind - com.fasterxml.jackson.core - - - jetty-server - org.eclipse.jetty - - - jetty-servlet - org.eclipse.jetty - - - jetty-servlets - org.eclipse.jetty - - - jetty-webapp - org.eclipse.jetty - - - guava - com.google.guava - - - httpclient - org.apache.httpcomponents - - - xmlunit-core - org.xmlunit - - - xmlunit-legacy - org.xmlunit - - - json-path - com.jayway.jsonpath - - - slf4j-api - org.slf4j - - - jopt-simple - net.sf.jopt-simple - - - junit - junit - - - commons-lang3 - org.apache.commons - - - zjsonpatch - com.flipkart.zjsonpatch - - - handlebars - com.github.jknack - - - - - com.github.stefanbirkner - system-rules - 1.18.0 - test - - - junit - junit - - - junit-dep - junit - - - - - org.openjdk.jmh - jmh-generator-annprocess - 1.33 - test - - - jmh-core - org.openjdk.jmh - - - - - - ${shade.package}.${shade.io.grpc.source} - ${shade.package}.${shade.org.slf4j.source} - ${shade.package}.${shade.io.opencensus.source} - io.netty - ${shade.package}.${shade.io.perfmark.source} - com.google - 1.18.0 - io.grpc - org.slf4j - io.opencensus - io.perfmark - 1.4.1.Final - UTF-8 - ${shade.package}.${shade.io.netty.source} - 2.0.7.Final - ${shade.package}.${shade.com.google.source} - - diff --git a/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/boot/SpringBootConfig.java b/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/boot/SpringBootConfig.java new file mode 100644 index 00000000..bfdebf59 --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/boot/SpringBootConfig.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 cn.hippo4j.agent.core.boot; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +public @interface SpringBootConfig { + + /** + * @return Class as the root to do config initialization. + */ + Class root(); +} diff --git a/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/boot/SpringBootConfigInitializer.java b/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/boot/SpringBootConfigInitializer.java new file mode 100644 index 00000000..66d148a8 --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/boot/SpringBootConfigInitializer.java @@ -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. + */ + +package cn.hippo4j.agent.core.boot; + +import cn.hippo4j.agent.core.logging.api.ILog; +import cn.hippo4j.agent.core.logging.api.LogManager; +import cn.hippo4j.agent.core.util.ConfigInitializer; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Properties; +import java.util.Set; + +public class SpringBootConfigInitializer { + + private static final ILog LOG = LogManager.getLogger(SpringBootConfigInitializer.class); + + private static final Set> SPRING_BOOT_CONFIG_LIST = Collections.synchronizedSet(new HashSet<>()); + + private static final long MAX_CACHE_TIME = 30L * 60L * 1000L; // half an hour. + + private static final int MAX_CACHE_SIZE = 1000; + + private static long PROPERTIES_LOAD_TIME; + + private static Properties SPRING_PROPERTIES = null; + + private SpringBootConfigInitializer() { + + } + + public static synchronized void initializeConfig(SpringBootConfig springBootConfig) { + if (SPRING_PROPERTIES != null) { + try { + LOG.info("initialize Spring Config Class {}.", springBootConfig.root()); + ConfigInitializer.initialize(SPRING_PROPERTIES, springBootConfig.root()); + } catch (Throwable e) { + LOG.error(e, "Failed to set the agent settings {} to Config={} ", SPRING_PROPERTIES, springBootConfig.root()); + } + } + boolean isStarting = PROPERTIES_LOAD_TIME == 0L; + boolean overtime = System.currentTimeMillis() - PROPERTIES_LOAD_TIME > MAX_CACHE_TIME; + boolean oversize = SPRING_BOOT_CONFIG_LIST.size() > MAX_CACHE_SIZE; + // avoid memory leak. + if (isStarting || (!oversize && !overtime)) { + SPRING_BOOT_CONFIG_LIST.add(springBootConfig.root()); + } else { + LOG.warn("spirng Config Class is skipped {}.", springBootConfig.root()); + } + } + + public static synchronized void setSpringProperties(Properties properties) { + if (properties != null && (SPRING_PROPERTIES == null || properties.size() > SPRING_PROPERTIES.size())) { + LOG.info("set Spring Config Properties before : {}.", SPRING_PROPERTIES); + SPRING_PROPERTIES = properties; + LOG.info("set Spring Config Properties after : {}.", SPRING_PROPERTIES); + PROPERTIES_LOAD_TIME = System.currentTimeMillis(); + } + for (Class clazz : SPRING_BOOT_CONFIG_LIST) { + try { + LOG.info("initialize Spring Config Class in loop {}.", clazz); + ConfigInitializer.initialize(SPRING_PROPERTIES, clazz); + } catch (Throwable e) { + LOG.error(e, "Failed to set the agent Config={} from settings {}", clazz, properties); + } + } + } +} diff --git a/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/plugin/loader/AgentClassLoader.java b/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/plugin/loader/AgentClassLoader.java index 0539c9a7..5a8094fc 100644 --- a/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/plugin/loader/AgentClassLoader.java +++ b/hippo4j-agent/hippo4j-agent-core/src/main/java/cn/hippo4j/agent/core/plugin/loader/AgentClassLoader.java @@ -17,9 +17,7 @@ package cn.hippo4j.agent.core.plugin.loader; -import cn.hippo4j.agent.core.boot.AgentPackageNotFoundException; -import cn.hippo4j.agent.core.boot.AgentPackagePath; -import cn.hippo4j.agent.core.boot.PluginConfig; +import cn.hippo4j.agent.core.boot.*; import cn.hippo4j.agent.core.conf.Config; import cn.hippo4j.agent.core.conf.SnifferConfigInitializer; import cn.hippo4j.agent.core.logging.api.ILog; @@ -169,6 +167,13 @@ public class AgentClassLoader extends ClassLoader { SnifferConfigInitializer.initializeConfig(pluginConfig.root()); } + final SpringBootConfig springBootConfig = loadedClass.getAnnotation(SpringBootConfig.class); + if (springBootConfig != null) { + // Set up the plugin config when loaded by spring environment is prepared, just scan in here. + // Agent class loader just loaded limited classes in the plugin jar(s), so the cost of this + // isAssignableFrom would be also very limited. + SpringBootConfigInitializer.initializeConfig(springBootConfig); + } return loadedClass; } diff --git a/hippo4j-agent/hippo4j-agent-plugin/pom.xml b/hippo4j-agent/hippo4j-agent-plugin/pom.xml index a7663a2a..dc1770b1 100644 --- a/hippo4j-agent/hippo4j-agent-plugin/pom.xml +++ b/hippo4j-agent/hippo4j-agent-plugin/pom.xml @@ -10,11 +10,92 @@ hippo4j-agent-plugin + pom + + spring-plugins + - 8 - 8 UTF-8 + + net.bytebuddy + ${shade.package}.${shade.net.bytebuddy.source} + + ${project.build.directory}${sdk.plugin.related.dir}/../../../hippo4j-agent + + ${agent.package.dest.dir}/plugins + + 1.0b3 + 1.8.1 + + + + maven-shade-plugin + + + package + + shade + + + false + true + true + true + + + ${shade.net.bytebuddy.source} + ${shade.net.bytebuddy.target} + + + + + + + + maven-antrun-plugin + + + package + + run + + + + + + + + + + + + + + + + + + + ant-contrib + ant-contrib + ${ant-contrib.version} + + + ant + ant + + + + + org.apache.ant + ant-nodeps + ${ant-nodeps.version} + + + + + \ No newline at end of file diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/pom.xml b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/pom.xml new file mode 100644 index 00000000..1d85f539 --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + cn.hippo4j + hippo4j-agent-plugin + ${revision} + + + spring-plugins + pom + + spring-boot-1.x-plugin + spring-boot-2.x-plugin + spring-plugin-common + + + + UTF-8 + /.. + + + + + + cn.hippo4j + spring-plugin-common + ${project.version} + + + + + + + cn.hippo4j + hippo4j-agent-core + ${project.version} + provided + + + net.bytebuddy + byte-buddy + ${bytebuddy.version} + provided + + + + \ No newline at end of file diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/pom.xml b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/pom.xml new file mode 100644 index 00000000..d52b781c --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + cn.hippo4j + spring-plugins + ${revision} + + + spring-boot-1.x-plugin + + + 1.5.22.RELEASE + + + + + cn.hippo4j + spring-plugin-common + provided + + + + org.springframework.boot + spring-boot-autoconfigure + ${spring.boot.version} + provided + + + + \ No newline at end of file diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/EventPublishingFinishedInterceptor.java b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/EventPublishingFinishedInterceptor.java new file mode 100644 index 00000000..c7dc072f --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/EventPublishingFinishedInterceptor.java @@ -0,0 +1,58 @@ +/* + * 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 cn.hippo4j.agent.plugin.spring.boot.v1; + +import cn.hippo4j.agent.core.boot.SpringBootConfigInitializer; +import cn.hippo4j.agent.core.logging.api.ILog; +import cn.hippo4j.agent.core.logging.api.LogManager; +import cn.hippo4j.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import cn.hippo4j.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import cn.hippo4j.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import cn.hippo4j.agent.plugin.spring.common.SpringPropertiesLoader; +import org.springframework.context.ConfigurableApplicationContext; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.EnumerablePropertySource; +import org.springframework.core.env.PropertySource; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +public class EventPublishingFinishedInterceptor implements InstanceMethodsAroundInterceptor { + + private static final ILog LOGGER = LogManager.getLogger(EventPublishingFinishedInterceptor.class); + + @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 { + ConfigurableApplicationContext context = (ConfigurableApplicationContext) allArguments[0]; + SpringPropertiesLoader.loadSpringProperties(context.getEnvironment()); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/define/EventPublishingRunListenerInstrumentation.java b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/define/EventPublishingRunListenerInstrumentation.java new file mode 100644 index 00000000..7a0e7953 --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v1/define/EventPublishingRunListenerInstrumentation.java @@ -0,0 +1,68 @@ +/* + * 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 cn.hippo4j.agent.plugin.spring.boot.v1.define; + +import cn.hippo4j.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import cn.hippo4j.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import cn.hippo4j.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import cn.hippo4j.agent.core.plugin.match.ClassMatch; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static cn.hippo4j.agent.core.plugin.match.NameMatch.byName; + +public class EventPublishingRunListenerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.springframework.boot.context.event.EventPublishingRunListener"; + + private static final String EVENT_PUBLISHING_FINISHED_INTERCEPTOR = "cn.hippo4j.agent.plugin.spring.boot.v1.EventPublishingFinishedInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + + @Override + public ElementMatcher getMethodsMatcher() { + return named("finished"); + } + + @Override + public String getMethodsInterceptor() { + return EVENT_PUBLISHING_FINISHED_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/resources/hippo4j-plugin.def b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/resources/hippo4j-plugin.def new file mode 100644 index 00000000..8bb37e3a --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-1.x-plugin/src/main/resources/hippo4j-plugin.def @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +spring-boot-1.x=cn.hippo4j.agent.plugin.spring.boot.v1.define.EventPublishingRunListenerInstrumentation \ No newline at end of file diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/pom.xml b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/pom.xml new file mode 100644 index 00000000..bf7b5712 --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/pom.xml @@ -0,0 +1,33 @@ + + + 4.0.0 + + cn.hippo4j + spring-plugins + ${revision} + + + spring-boot-2.x-plugin + jar + + + 2.3.2.RELEASE + + + + + cn.hippo4j + spring-plugin-common + provided + + + + org.springframework.boot + spring-boot-autoconfigure + ${spring.boot.version} + provided + + + \ No newline at end of file diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/EventPublishingStartedInterceptor.java b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/EventPublishingStartedInterceptor.java new file mode 100644 index 00000000..762b63a7 --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/EventPublishingStartedInterceptor.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 cn.hippo4j.agent.plugin.spring.boot.v2; + +import cn.hippo4j.agent.core.logging.api.ILog; +import cn.hippo4j.agent.core.logging.api.LogManager; +import cn.hippo4j.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import cn.hippo4j.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import cn.hippo4j.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import cn.hippo4j.agent.plugin.spring.common.SpringPropertiesLoader; +import org.springframework.context.ConfigurableApplicationContext; + +import java.lang.reflect.Method; + +public class EventPublishingStartedInterceptor implements InstanceMethodsAroundInterceptor { + + private static final ILog LOGGER = LogManager.getLogger(EventPublishingStartedInterceptor.class); + + @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 { + ConfigurableApplicationContext context = (ConfigurableApplicationContext) allArguments[0]; + SpringPropertiesLoader.loadSpringProperties(context.getEnvironment()); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/define/EventPublishingRunListenerInstrumentation.java b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/define/EventPublishingRunListenerInstrumentation.java new file mode 100644 index 00000000..c3e46ed6 --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/java/cn/hippo4j/agent/plugin/spring/boot/v2/define/EventPublishingRunListenerInstrumentation.java @@ -0,0 +1,68 @@ +/* + * 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 cn.hippo4j.agent.plugin.spring.boot.v2.define; + +import cn.hippo4j.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import cn.hippo4j.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import cn.hippo4j.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import cn.hippo4j.agent.core.plugin.match.ClassMatch; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static cn.hippo4j.agent.core.plugin.match.NameMatch.byName; + +public class EventPublishingRunListenerInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.springframework.boot.context.event.EventPublishingRunListener"; + + private static final String EVENT_PUBLISHING_FINISHED_INTERCEPTOR = "cn.hippo4j.agent.plugin.spring.boot.v2.EventPublishingStartedInterceptor"; + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } + + @Override + public ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + + @Override + public ElementMatcher getMethodsMatcher() { + return named("started"); + } + + @Override + public String getMethodsInterceptor() { + return EVENT_PUBLISHING_FINISHED_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/resources/hippo4j-plugin.def b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/resources/hippo4j-plugin.def new file mode 100644 index 00000000..8dad75ea --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-boot-2.x-plugin/src/main/resources/hippo4j-plugin.def @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +spring-boot-2.x=cn.hippo4j.agent.plugin.spring.boot.v2.define.EventPublishingRunListenerInstrumentation \ No newline at end of file diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/pom.xml b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/pom.xml new file mode 100644 index 00000000..f6ea99a8 --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + + cn.hippo4j + spring-plugins + ${revision} + + + spring-plugin-common + + + + org.springframework + spring-core + provided + + + + \ No newline at end of file diff --git a/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/SpringPropertiesLoader.java b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/SpringPropertiesLoader.java new file mode 100644 index 00000000..485a7669 --- /dev/null +++ b/hippo4j-agent/hippo4j-agent-plugin/spring-plugins/spring-plugin-common/src/main/java/cn/hippo4j/agent/plugin/spring/common/SpringPropertiesLoader.java @@ -0,0 +1,66 @@ +/* + * 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 cn.hippo4j.agent.plugin.spring.common; + +import cn.hippo4j.agent.core.boot.SpringBootConfigInitializer; +import cn.hippo4j.agent.core.logging.api.ILog; +import cn.hippo4j.agent.core.logging.api.LogManager; +import org.springframework.core.env.ConfigurableEnvironment; +import org.springframework.core.env.EnumerablePropertySource; +import org.springframework.core.env.PropertySource; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Properties; + +public class SpringPropertiesLoader { + + private static final ILog LOGGER = LogManager.getLogger(SpringPropertiesLoader.class); + + public static void loadSpringProperties(ConfigurableEnvironment environment) { + Iterator> iterator = environment.getPropertySources().iterator(); + Properties properties = new Properties(); + List> propertySourceList = new ArrayList<>(); + while (iterator.hasNext()) { + propertySourceList.add(iterator.next()); + } + for (int i = propertySourceList.size() - 1; i >= 0; i--) { + PropertySource propertySource = propertySourceList.get(i); + if (!(propertySource instanceof EnumerablePropertySource)) { + LOGGER.warn("Skip propertySource[{}] because {} not enumerable.", propertySource.getName(), propertySource.getClass()); + continue; + } + LOGGER.info("Load propertySource[{}] into SpringProperties.", propertySource.getName()); + EnumerablePropertySource enumerablePropertySource = (EnumerablePropertySource) propertySource; + String[] keys = enumerablePropertySource.getPropertyNames(); + for (String key : keys) { + Object value = null; + try { + value = enumerablePropertySource.getProperty(key); + if (value != null) { + properties.put(key.toLowerCase(), value.toString()); + } + } catch (Throwable e) { + LOGGER.warn("Put property to spring properties failed, key=[{}], value=[{}]", key, value); + } + } + } + SpringBootConfigInitializer.setSpringProperties(properties); + } +} diff --git a/hippo4j-agent/pom.xml b/hippo4j-agent/pom.xml index 42774e4f..5eac2289 100644 --- a/hippo4j-agent/pom.xml +++ b/hippo4j-agent/pom.xml @@ -221,9 +221,6 @@ 1.8 - - 3.6 - diff --git a/hippo4j-core/src/test/java/cn/hippo4j/core/executor/state/ThreadPoolRunStateHandlerTest.java b/hippo4j-core/src/test/java/cn/hippo4j/core/executor/state/ThreadPoolRunStateHandlerTest.java index ada71ae0..25e0df8d 100644 --- a/hippo4j-core/src/test/java/cn/hippo4j/core/executor/state/ThreadPoolRunStateHandlerTest.java +++ b/hippo4j-core/src/test/java/cn/hippo4j/core/executor/state/ThreadPoolRunStateHandlerTest.java @@ -66,8 +66,7 @@ public class ThreadPoolRunStateHandlerTest { "Allocation: ", ByteConvertUtil.getPrintSize(used), " / Maximum available: ", - ByteConvertUtil.getPrintSize(max) - ); + ByteConvertUtil.getPrintSize(max)); String ipAddress = "127.0.0.1"; @@ -124,4 +123,3 @@ public class ThreadPoolRunStateHandlerTest { } } -