diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/AgentCoreEntrance.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/AgentCoreEntrance.java index feced95bcf..a817b29c1b 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/AgentCoreEntrance.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/AgentCoreEntrance.java @@ -32,6 +32,7 @@ import com.huaweicloud.sermant.core.plugin.agent.ByteEnhanceManager; import com.huaweicloud.sermant.core.plugin.agent.adviser.AdviserInterface; import com.huaweicloud.sermant.core.plugin.agent.adviser.AdviserScheduler; +import com.huaweicloud.sermant.core.plugin.agent.info.EnhanceInfoManager; import com.huaweicloud.sermant.core.plugin.agent.template.DefaultAdviser; import com.huaweicloud.sermant.core.service.ServiceManager; import com.huaweicloud.sermant.god.common.SermantManager; @@ -157,6 +158,9 @@ public static void uninstall() { // 清理配置类 ConfigManager.shutdown(); + // 清理增强信息类 + EnhanceInfoManager.shutdown(); + // 设置该artifact的Sermant状态为false,非运行状态 SermantManager.updateSermantStatus(artifactCache, false); } diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CheckEnhancementCommandExecutor.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CheckEnhancementCommandExecutor.java new file mode 100644 index 0000000000..cb0168927e --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CheckEnhancementCommandExecutor.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.core.command; + +import com.huaweicloud.sermant.core.common.LoggerFactory; +import com.huaweicloud.sermant.core.plugin.Plugin; +import com.huaweicloud.sermant.core.plugin.PluginManager; +import com.huaweicloud.sermant.core.plugin.agent.info.EnhanceInfoManager; +import com.huaweicloud.sermant.core.utils.CollectionUtils; +import com.huaweicloud.sermant.core.utils.MapUtils; + +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * 增强信息查询命令执行器 + * + * @author tangle + * @since 2023-11-02 + */ +public class CheckEnhancementCommandExecutor implements CommandExecutor { + private static final Logger LOGGER = LoggerFactory.getLogger(); + + @Override + public void execute(String args) { + LOGGER.log(Level.INFO, "========== plugins =========="); + for (Map.Entry entry : PluginManager.getPluginMap().entrySet()) { + LOGGER.log(Level.INFO, entry.getKey() + ":" + entry.getValue().getVersion()); + } + LOGGER.log(Level.INFO, "========== enhancement =========="); + Map>> enhancement = EnhanceInfoManager.getEnhancement(); + if (MapUtils.isEmpty(enhancement)) { + LOGGER.log(Level.INFO, "no enhancement currently."); + return; + } + for (Map.Entry>> enhancemantEntry : enhancement.entrySet()) { + String pluginInfo = enhancemantEntry.getKey(); + Map> methodDescMap = enhancemantEntry.getValue(); + if (MapUtils.isEmpty(methodDescMap)) { + continue; + } + LOGGER.log(Level.INFO, pluginInfo); + for (Map.Entry> methodDescEntry : methodDescMap.entrySet()) { + String methodDesc = methodDescEntry.getKey(); + Set interceptorSet = methodDescEntry.getValue(); + if (CollectionUtils.isEmpty(interceptorSet)) { + continue; + } + LOGGER.log(Level.INFO, methodDesc + " " + interceptorSet); + } + } + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/Command.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/Command.java index 0e6384a182..b6cdf1f511 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/Command.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/Command.java @@ -34,7 +34,13 @@ public enum Command { /** * 卸载插件指令 */ - UNINSTALL_PLUGINS("UNINSTALL-PLUGINS"); + UNINSTALL_PLUGINS("UNINSTALL-PLUGINS"), + + /** + * 增强查询指令 + */ + CHECK_ENHANCEMENT("CHECK-ENHANCEMENT"); + private final String value; Command(String value) { diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CommandProcessor.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CommandProcessor.java index d685226a24..16d4bf42f1 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CommandProcessor.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CommandProcessor.java @@ -43,6 +43,7 @@ public class CommandProcessor { COMMAND_EXECUTOR_MAP.put(Command.INSTALL_PLUGINS.getValue(), new PluginsInstallCommandExecutor()); COMMAND_EXECUTOR_MAP.put(Command.UNINSTALL_AGENT.getValue(), new AgentUnInstallCommandExecutor()); COMMAND_EXECUTOR_MAP.put(Command.UNINSTALL_PLUGINS.getValue(), new PluginsUnInstallCommandExecutor()); + COMMAND_EXECUTOR_MAP.put(Command.CHECK_ENHANCEMENT.getValue(), new CheckEnhancementCommandExecutor()); } /** diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/PluginManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/PluginManager.java index 209db2bc30..af3be60838 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/PluginManager.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/PluginManager.java @@ -23,6 +23,7 @@ import com.huaweicloud.sermant.core.exception.SchemaException; import com.huaweicloud.sermant.core.plugin.agent.ByteEnhanceManager; import com.huaweicloud.sermant.core.plugin.agent.adviser.AdviserScheduler; +import com.huaweicloud.sermant.core.plugin.agent.info.EnhanceInfoManager; import com.huaweicloud.sermant.core.plugin.agent.interceptor.Interceptor; import com.huaweicloud.sermant.core.plugin.agent.template.BaseAdviseHandler; import com.huaweicloud.sermant.core.plugin.classloader.PluginClassLoader; @@ -108,6 +109,9 @@ public static void uninstall(Set pluginNames) { // 取消字节码增强 ByteEnhanceManager.unEnhanceDynamicPlugin(plugin); + // 清除增强信息 + EnhanceInfoManager.removePluginEnhancement(plugin); + // 关闭插件服务 PluginServiceManager.shutdownPluginServices(plugin); @@ -183,6 +187,10 @@ public static void initPlugins(Set pluginNames, boolean isDynamic) { } } + public static Map getPluginMap() { + return PLUGIN_MAP; + } + private static void doInitPlugin(Plugin plugin) { loadPluginLibs(plugin); loadServiceLibs(plugin); diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/agent/info/EnhanceInfoManager.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/agent/info/EnhanceInfoManager.java new file mode 100644 index 0000000000..0e50ae6db3 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/agent/info/EnhanceInfoManager.java @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2023-2023 Huawei Technologies Co., Ltd. All rights reserved. + * + * Licensed 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 com.huaweicloud.sermant.core.plugin.agent.info; + +import com.huaweicloud.sermant.core.plugin.Plugin; +import com.huaweicloud.sermant.core.plugin.agent.interceptor.Interceptor; +import com.huaweicloud.sermant.core.utils.MapUtils; +import com.huaweicloud.sermant.core.utils.StringUtils; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 存储增强信息的静态类 + * + * @author tangle + * @since 2023-11-02 + */ +public class EnhanceInfoManager { + private static Map>> enhancement; + + private EnhanceInfoManager() { + } + + public static Map>> getEnhancement() { + return enhancement; + } + + /** + * 添加拦截器信息 + * + * @param plugin 插件 + * @param interceptorList 拦截器列表 + * @param classLoader 类加载器 + * @param methodDesc 被增强方法的信息 + */ + public static void addEnhancement(Plugin plugin, List interceptorList, ClassLoader classLoader, + String methodDesc) { + if (MapUtils.isEmpty(enhancement)) { + enhancement = new HashMap<>(); + } + String enhancementKey = combinePluginInfo(plugin); + Map> methodDescMap = enhancement.computeIfAbsent(enhancementKey, key -> new HashMap<>()); + if (!StringUtils.isEmpty(methodDesc)) { + String methodDescKey = combineEnhanceInfo(methodDesc, classLoader); + Set interceptorSet = methodDescMap.computeIfAbsent(methodDescKey, key -> new HashSet<>()); + for (Interceptor interceptor : interceptorList) { + interceptorSet.add(interceptor.getClass().getCanonicalName()); + } + } + } + + /** + * 卸载插件时清除该插件的增强信息 + * + * @param plugin 插件 + */ + public static void removePluginEnhancement(Plugin plugin) { + if (enhancement != null) { + enhancement.remove(combinePluginInfo(plugin)); + } + } + + /** + * 清理缓存的增强信息 + */ + public static void shutdown() { + if (enhancement != null) { + enhancement.clear(); + } + } + + /** + * 拼接插件信息 + */ + private static String combinePluginInfo(Plugin plugin) { + return plugin.getName() + ":" + plugin.getVersion(); + } + + /** + * 拼接增强信息 + */ + private static String combineEnhanceInfo(String methodDesc, ClassLoader classLoader) { + return methodDesc + "@" + classLoader; + } +} diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/agent/transformer/ReentrantTransformer.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/agent/transformer/ReentrantTransformer.java index 67ae1013af..59ab0d5bc9 100644 --- a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/agent/transformer/ReentrantTransformer.java +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/agent/transformer/ReentrantTransformer.java @@ -19,8 +19,10 @@ import com.huaweicloud.sermant.core.plugin.Plugin; import com.huaweicloud.sermant.core.plugin.agent.adviser.AdviserScheduler; import com.huaweicloud.sermant.core.plugin.agent.declarer.InterceptDeclarer; +import com.huaweicloud.sermant.core.plugin.agent.info.EnhanceInfoManager; import com.huaweicloud.sermant.core.plugin.agent.interceptor.Interceptor; import com.huaweicloud.sermant.core.plugin.agent.template.BaseAdviseHandler; +import com.huaweicloud.sermant.core.plugin.agent.template.MethodKeyCreator; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.method.MethodDescription.InDefinedShape; @@ -69,6 +71,8 @@ protected Builder resolve(Builder builder, InDefinedShape methodDesc, List createdInterceptorForAdviceKey.add(interceptor.getClass().getCanonicalName()); } } + EnhanceInfoManager.addEnhancement(plugin, interceptors, classLoader, + MethodKeyCreator.getMethodDescKey(methodDesc)); if (checkAdviceLock(adviceKey)) { return builder.visit(Advice.to(templateCls).on(ElementMatchers.is(methodDesc))); }