mirror of https://github.com/longtai-cn/hippo4j
Complete the agent of springboot1.x version in config mode. (#1215)
parent
e188855997
commit
f1321052c1
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.registry;
|
||||
|
||||
import cn.hippo4j.agent.core.logging.api.ILog;
|
||||
import cn.hippo4j.agent.core.logging.api.LogManager;
|
||||
import cn.hippo4j.common.config.ExecutorProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
@Data
|
||||
public class AgentThreadPoolExecutorHolder {
|
||||
|
||||
private static final ILog LOGGER = LogManager.getLogger(AgentThreadPoolExecutorHolder.class);
|
||||
|
||||
public static final AgentThreadPoolExecutorHolder EMPTY = new AgentThreadPoolExecutorHolder();
|
||||
|
||||
private String executorName;
|
||||
|
||||
private ThreadPoolExecutor executor;
|
||||
|
||||
private ExecutorProperties properties;
|
||||
|
||||
public AgentThreadPoolExecutorHolder() {
|
||||
}
|
||||
|
||||
public AgentThreadPoolExecutorHolder(String executorName, ThreadPoolExecutor executor, ExecutorProperties properties) {
|
||||
this.executorName = executorName;
|
||||
this.executor = executor;
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this == EMPTY;
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.registry;
|
||||
|
||||
import cn.hippo4j.agent.core.logging.api.ILog;
|
||||
import cn.hippo4j.agent.core.logging.api.LogManager;
|
||||
import cn.hippo4j.common.config.ExecutorProperties;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
||||
public class AgentThreadPoolInstanceRegistry {
|
||||
|
||||
private static final ILog LOGGER = LogManager.getLogger(AgentThreadPoolInstanceRegistry.class);
|
||||
|
||||
private final Map<String, AgentThreadPoolExecutorHolder> holderMap = new ConcurrentHashMap<>();
|
||||
|
||||
private volatile static AgentThreadPoolInstanceRegistry INSTANCE;
|
||||
|
||||
private AgentThreadPoolInstanceRegistry() {
|
||||
}
|
||||
|
||||
public static AgentThreadPoolInstanceRegistry getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
synchronized (AgentThreadPoolInstanceRegistry.class) {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new AgentThreadPoolInstanceRegistry();
|
||||
}
|
||||
}
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public Map<String, AgentThreadPoolExecutorHolder> getHolderMap() {
|
||||
return holderMap;
|
||||
}
|
||||
|
||||
public void putHolder(String executorName, ThreadPoolExecutor executor, ExecutorProperties properties) {
|
||||
AgentThreadPoolExecutorHolder holder = new AgentThreadPoolExecutorHolder(executorName, executor, properties);
|
||||
holderMap.put(executorName, holder);
|
||||
}
|
||||
|
||||
public AgentThreadPoolExecutorHolder getHolder(String executorName) {
|
||||
return Optional.ofNullable(holderMap.get(executorName)).orElse(AgentThreadPoolExecutorHolder.EMPTY);
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
public interface AgentThreadPoolConstants {
|
||||
|
||||
String TOMCAT_NAME_PREFIX = "namePrefix";
|
||||
String DUBBO_NAME_PREFIX = "mPrefix";
|
||||
String DUBBO_THREAD_NAME = "DubboServerHandler";
|
||||
String THREAD_POOL_NAME_DUBBO = "dubbo";
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import cn.hippo4j.agent.core.logging.api.ILog;
|
||||
import cn.hippo4j.agent.core.logging.api.LogManager;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
public class ExecutorNameUtil {
|
||||
|
||||
private static final ILog LOGGER = LogManager.getLogger(ExecutorNameUtil.class);
|
||||
|
||||
public static boolean isTomcatExecutor(Object threadFactory) {
|
||||
try {
|
||||
if ("org.apache.tomcat.util.threads.TaskThreadFactory".equals(threadFactory.getClass().getName())) {
|
||||
Field namePrefixField = threadFactory.getClass().getDeclaredField(AgentThreadPoolConstants.TOMCAT_NAME_PREFIX);
|
||||
namePrefixField.setAccessible(true);
|
||||
String namePrefix = (String) namePrefixField.get(threadFactory);
|
||||
if (RegexUtil.isTomcatNameMatch(namePrefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("Fail to put tomcat executor", t);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -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 cn.hippo4j.agent.core.util;
|
||||
|
||||
import cn.hippo4j.agent.core.logging.api.ILog;
|
||||
import cn.hippo4j.agent.core.logging.api.LogManager;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ReflectUtil {
|
||||
|
||||
private static final ILog LOGGER = LogManager.getLogger(ReflectUtil.class);
|
||||
|
||||
public static List<Field> getStaticFieldsFromType(Class<?> clazz, Class<?> declaredType) {
|
||||
Field[] fields = clazz.getFields();
|
||||
List<Field> result = new ArrayList<>();
|
||||
for (Field field : fields) {
|
||||
if (field.getType().isAssignableFrom(declaredType) &&
|
||||
Modifier.isStatic(field.getModifiers())) {
|
||||
result.add(field);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.util;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class RegexUtil {
|
||||
|
||||
private static final String TOMCAT_NAME_PATTERN_STRING = "http\\S+nio\\S+-exec-";
|
||||
private static final Pattern TOMCAT_NAME_PATTERN = Pattern.compile(TOMCAT_NAME_PATTERN_STRING);
|
||||
|
||||
public static boolean isTomcatNameMatch(String executorName) {
|
||||
return TOMCAT_NAME_PATTERN.matcher(executorName).find();
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>cn.hippo4j</groupId>
|
||||
<artifactId>hippo4j-agent-plugin</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>apollo-plugin</artifactId>
|
||||
|
||||
<properties>
|
||||
<apollo.version>1.9.1</apollo.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.ctrip.framework.apollo</groupId>
|
||||
<artifactId>apollo-client</artifactId>
|
||||
<version>${apollo.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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.apollo;
|
||||
|
||||
import cn.hippo4j.agent.core.plugin.interceptor.enhance.EnhancedInstance;
|
||||
import cn.hippo4j.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
|
||||
import com.ctrip.framework.apollo.ConfigChangeListener;
|
||||
import com.ctrip.framework.apollo.ConfigFile;
|
||||
import com.ctrip.framework.apollo.ConfigService;
|
||||
import com.ctrip.framework.apollo.core.enums.ConfigFileFormat;
|
||||
import com.ctrip.framework.apollo.internals.DefaultConfig;
|
||||
import com.ctrip.framework.apollo.model.ConfigChange;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class DefaultConfigConstructorInterceptor implements InstanceConstructorInterceptor {
|
||||
|
||||
@Override
|
||||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable {
|
||||
}
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.apollo.boot;
|
||||
|
||||
import cn.hippo4j.agent.core.boot.BootService;
|
||||
import cn.hippo4j.agent.core.boot.DefaultImplementor;
|
||||
|
||||
@DefaultImplementor
|
||||
public class ApolloPluginBootService 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 {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.apollo.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 cn.hippo4j.agent.core.plugin.match.NameMatch;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.any;
|
||||
|
||||
public class ApolloInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String ENHANCE_CLASS = "com.ctrip.framework.apollo.internals.DefaultConfig";
|
||||
|
||||
private static final String CONSTRUCTOR_INTERCEPT_CLASS = "cn.hippo4j.agent.plugin.apollo.DefaultConfigConstructorInterceptor";
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return NameMatch.byName(ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[]{
|
||||
new ConstructorInterceptPoint() {
|
||||
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return CONSTRUCTOR_INTERCEPT_CLASS;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[0];
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
||||
cn.hippo4j.agent.plugin.apollo.boot.ApolloPluginBootService
|
@ -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.
|
||||
|
||||
apollo-plugin=cn.hippo4j.agent.plugin.apollo.define.ApolloInstrumentation
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.SpringBootConfig;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ApolloSpringBootProperties {
|
||||
|
||||
|
||||
public static class Spring {
|
||||
|
||||
public static class Dynamic {
|
||||
|
||||
@SpringBootConfig(root = ApolloSpringBootProperties.class)
|
||||
public static class Thread_Pool {
|
||||
|
||||
@SpringBootConfig(root = ApolloSpringBootProperties.class)
|
||||
public static class Apollo {
|
||||
|
||||
public static List<String> NAMESPACE = Arrays.asList("application");
|
||||
}
|
||||
|
||||
public static String CONFIG_FILE_TYPE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.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.SpringEnvironmentSupport;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class EventPublishingRunListenerEnvironmentPreparedInterceptor implements InstanceMethodsAroundInterceptor {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(EventPublishingRunListenerEnvironmentPreparedInterceptor.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 {
|
||||
ConfigurableEnvironment environment = (ConfigurableEnvironment) allArguments[0];
|
||||
SpringEnvironmentSupport.disableNonAgentSwitch(environment);
|
||||
LOGGER.info("[Hippo4j-Agent] Switch off in non-Agent mode.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, Throwable t) {
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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 org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class SpringEnvironmentSupport {
|
||||
|
||||
public static void disableNonAgentSwitch(ConfigurableEnvironment environment) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put("spring.dynamic.thread-pool.enable", false); // Switch off in non-Agent mode
|
||||
MapPropertySource propertySource = new MapPropertySource("Hippo4j-Agent-Properties", map);
|
||||
environment.getPropertySources().addFirst(propertySource);
|
||||
}
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>cn.hippo4j</groupId>
|
||||
<artifactId>hippo4j-agent-plugin</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>thread-pool-plugin</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.hippo4j</groupId>
|
||||
<artifactId>hippo4j-core</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.thread.pool;
|
||||
|
||||
import cn.hippo4j.agent.core.conf.Config;
|
||||
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.InstanceConstructorInterceptor;
|
||||
import cn.hippo4j.agent.core.registry.AgentThreadPoolInstanceRegistry;
|
||||
import cn.hippo4j.agent.core.util.CollectionUtil;
|
||||
import cn.hippo4j.agent.core.util.ReflectUtil;
|
||||
import cn.hippo4j.agent.core.util.StringUtil;
|
||||
import cn.hippo4j.common.config.ExecutorProperties;
|
||||
import cn.hippo4j.common.executor.support.BlockingQueueTypeEnum;
|
||||
import cn.hippo4j.common.executor.support.RejectedPolicyTypeEnum;
|
||||
import cn.hippo4j.common.model.register.DynamicThreadPoolRegisterParameter;
|
||||
import cn.hippo4j.common.model.register.DynamicThreadPoolRegisterWrapper;
|
||||
import cn.hippo4j.common.model.register.notify.DynamicThreadPoolRegisterCoreNotifyParameter;
|
||||
import cn.hippo4j.common.toolkit.BooleanUtil;
|
||||
import cn.hippo4j.core.executor.DynamicThreadPoolWrapper;
|
||||
import cn.hippo4j.core.executor.manage.GlobalThreadPoolManage;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class ThreadPoolExecutorConstructorMethodInterceptor implements InstanceConstructorInterceptor {
|
||||
|
||||
private static final ILog LOGGER = LogManager.getLogger(ThreadPoolExecutorConstructorMethodInterceptor.class);
|
||||
|
||||
private static final List<String> EXCLUDE_STACK_TRACE_ELEMENT_CLASS_PREFIX = Arrays.asList("java", "cn.hippo4j.agent");
|
||||
|
||||
@Override
|
||||
public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable {
|
||||
|
||||
List<StackTraceElement> stackTraceElements = getStackTraceElements();
|
||||
if (CollectionUtil.isEmpty(stackTraceElements)) {
|
||||
return;
|
||||
}
|
||||
StackTraceElement declaredClassStackTraceElement = stackTraceElements.get(0);
|
||||
String declaredClassName = declaredClassStackTraceElement.getClassName();
|
||||
List<Field> staticFieldsFromType = ReflectUtil.getStaticFieldsFromType(Class.forName(declaredClassName),
|
||||
ThreadPoolExecutor.class);
|
||||
for (Field field : staticFieldsFromType) {
|
||||
try {
|
||||
Object value = field.get(null);
|
||||
if (value != null) {
|
||||
String threadPoolId = declaredClassName + "#" + field.getName();
|
||||
ThreadPoolExecutor executor = (ThreadPoolExecutor) field.get(null);
|
||||
register(threadPoolId, executor);
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
LOGGER.error(String.format("ExecutorNameUtil, register thread pool error. ClassName=[%s], ThreadPoolFieldName=[%s]",
|
||||
objInst.getClass().getName(), field.getName()), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void register(String threadPoolId, ThreadPoolExecutor executor) {
|
||||
// build parameter info.
|
||||
ExecutorProperties executorProperties = ExecutorProperties.builder()
|
||||
.threadPoolId(threadPoolId)
|
||||
.corePoolSize(executor.getCorePoolSize())
|
||||
.maximumPoolSize(executor.getMaximumPoolSize())
|
||||
.allowCoreThreadTimeOut(BooleanUtil.toBoolean(String.valueOf(executor.allowsCoreThreadTimeOut())))
|
||||
.keepAliveTime(executor.getKeepAliveTime(TimeUnit.MILLISECONDS))
|
||||
.blockingQueue(BlockingQueueTypeEnum.getBlockingQueueTypeEnumByName(executor.getQueue().getClass().getSimpleName()).getName())
|
||||
.queueCapacity(executor.getQueue().remainingCapacity())
|
||||
.threadNamePrefix(threadPoolId)
|
||||
.rejectedHandler(RejectedPolicyTypeEnum.getRejectedPolicyTypeEnumByName(executor.getRejectedExecutionHandler().getClass().getSimpleName()).getName())
|
||||
.executeTimeOut(10000L)
|
||||
.build();
|
||||
|
||||
// register executor.
|
||||
AgentThreadPoolInstanceRegistry.getInstance().putHolder(threadPoolId, executor, executorProperties);
|
||||
|
||||
}
|
||||
|
||||
private List<StackTraceElement> getStackTraceElements() {
|
||||
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
|
||||
int i;
|
||||
for (i = 0; i < stackTraceElements.length; i++) {
|
||||
String fullClassName = stackTraceElements[i].getClassName();
|
||||
if (isBusinessStackTraceClassName(fullClassName)) {
|
||||
if (isExcludeThreadPoolClass(fullClassName)) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<StackTraceElement> result = new ArrayList<>(3); // Find up to three layers
|
||||
for (int j = 0; i < stackTraceElements.length && j < 3; i++, j++) {
|
||||
String fullClassName = stackTraceElements[i].getClassName();
|
||||
if (isExcludeThreadPoolClass(fullClassName)) {
|
||||
break;
|
||||
} else {
|
||||
result.add(stackTraceElements[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private boolean isBusinessStackTraceClassName(String className) {
|
||||
for (String prefix : EXCLUDE_STACK_TRACE_ELEMENT_CLASS_PREFIX) {
|
||||
if (className.startsWith(prefix)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
private boolean isExcludeThreadPoolClass(String className) {
|
||||
if (StringUtil.isBlank(className)) {
|
||||
return true;
|
||||
}
|
||||
List<String> excludePackagePrefix = Config.Plugin.ThreadPool.EXCLUDE_PACKAGE_PREFIX;
|
||||
for (String excludePrefix : excludePackagePrefix) {
|
||||
if (className.startsWith(excludePrefix)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package cn.hippo4j.agent.plugin.thread.pool.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 cn.hippo4j.agent.core.plugin.match.NameMatch;
|
||||
import net.bytebuddy.description.method.MethodDescription;
|
||||
import net.bytebuddy.matcher.ElementMatcher;
|
||||
|
||||
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
|
||||
|
||||
public class ThreadPoolExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
|
||||
|
||||
private static final String ENHANCE_CLASS = "java.util.concurrent.ThreadPoolExecutor";
|
||||
|
||||
private static final String CONSTRUCTOR_INTERCEPT_CLASS = "cn.hippo4j.agent.plugin.thread.pool.ThreadPoolExecutorConstructorMethodInterceptor";
|
||||
|
||||
private static final int CONSTRUCTOR_INTERCEPT_PARAMETER_LENGTH = 7;
|
||||
|
||||
@Override
|
||||
protected ClassMatch enhanceClass() {
|
||||
return NameMatch.byName(ENHANCE_CLASS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBootstrapInstrumentation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* The constructor method that only intercepts all parameters prevents repeated interception.
|
||||
*/
|
||||
@Override
|
||||
public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
|
||||
return new ConstructorInterceptPoint[]{
|
||||
new ConstructorInterceptPoint() {
|
||||
|
||||
@Override
|
||||
public ElementMatcher<MethodDescription> getConstructorMatcher() {
|
||||
return takesArguments(CONSTRUCTOR_INTERCEPT_PARAMETER_LENGTH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConstructorInterceptor() {
|
||||
return CONSTRUCTOR_INTERCEPT_CLASS;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
|
||||
return new InstanceMethodsInterceptPoint[0];
|
||||
}
|
||||
}
|
@ -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.
|
||||
|
||||
thread-pool-plugin=cn.hippo4j.agent.plugin.thread.pool.define.ThreadPoolExecutorInstrumentation
|
Loading…
Reference in new issue