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..f31f73148e 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.clear(); + // 设置该artifact的Sermant状态为false,非运行状态 SermantManager.updateSermantStatus(artifactCache, false); } diff --git a/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CheckEnhanceCommandExecutor.java b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CheckEnhanceCommandExecutor.java new file mode 100644 index 0000000000..0dfabf6a21 --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/command/CheckEnhanceCommandExecutor.java @@ -0,0 +1,62 @@ +/* + * 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 CheckEnhanceCommandExecutor implements CommandExecutor { + private static final Logger LOGGER = LoggerFactory.getLogger(); + + @Override + public void execute(String args) { + LOGGER.log(Level.INFO, "========== print plugin =========="); + for (Map.Entry entry : PluginManager.getPluginMap().entrySet()) { + LOGGER.log(Level.INFO, entry.getKey() + ":" + entry.getValue().getVersion()); + } + LOGGER.log(Level.INFO, "========== print enhance class and method =========="); + Map> enhancement = EnhanceInfoManager.getEnhancement(); + if (MapUtils.isEmpty(enhancement)) { + LOGGER.log(Level.INFO, "enhancement map is empty."); + return; + } + for (Map.Entry> enhancemantEntry : enhancement.entrySet()) { + Set methodDescSet = enhancemantEntry.getValue(); + if (CollectionUtils.isEmpty(methodDescSet)) { + continue; + } + for (String methodDesc : methodDescSet) { + LOGGER.log(Level.INFO, enhancemantEntry.getKey() + " " + methodDesc); + } + } + } +} 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..61d6e6d7b0 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_ENHANCE("CHECK-ENHANCE"); + 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..9776a391ba 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_ENHANCE.getValue(), new CheckEnhanceCommandExecutor()); } /** 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..9f6f825d09 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; @@ -105,6 +106,9 @@ public static void uninstall(Set pluginNames) { AdviserScheduler.unLock(adviceKey); } + // 清除增强信息 + EnhanceInfoManager.removePluginEnhancement(plugin); + // 取消字节码增强 ByteEnhanceManager.unEnhanceDynamicPlugin(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..346774c8bc --- /dev/null +++ b/sermant-agentcore/sermant-agentcore-core/src/main/java/com/huaweicloud/sermant/core/plugin/agent/info/EnhanceInfoManager.java @@ -0,0 +1,113 @@ +/* + * 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; + } + + public static void setEnhancement(Map> enhancement) { + EnhanceInfoManager.enhancement = enhancement; + } + + /** + * 添加拦截器信息 + * + * @param interceptorList 拦截器列表 + * @param plugin 插件 + * @param className 类名 + * @param methodName 方法名 + */ + public static void addMethodDesc(Plugin plugin, List interceptorList, String className, + String methodName) { + if (MapUtils.isEmpty(enhancement)) { + enhancement = new HashMap<>(); + } + String enhancementKey = combinePluginInfo(plugin); + Set methodDesc = enhancement.computeIfAbsent(enhancementKey, key -> new HashSet<>()); + if (!StringUtils.isEmpty(className) && !StringUtils.isEmpty(methodName)) { + methodDesc.add(combineEnhanceInfo(interceptorList, className, methodName)); + } + } + + /** + * 卸载插件时清除该插件的增强信息 + * + * @param plugin 插件 + */ + public static void removePluginEnhancement(Plugin plugin) { + if (enhancement != null) { + enhancement.remove(combinePluginInfo(plugin)); + } + } + + /** + * 清理缓存的增强信息 + */ + public static void clear() { + if (enhancement != null) { + enhancement.clear(); + } + } + + /** + * 拼接插件信息 + */ + private static String combinePluginInfo(Plugin plugin) { + return plugin.getName() + ":" + plugin.getVersion(); + } + + /** + * 拼接增强信息 + */ + private static String combineEnhanceInfo(List interceptors, String className, String methodName) { + StringBuilder result = new StringBuilder("\tinterceptors: "); + int len = interceptors.size(); + for (int i = 0; i < len; i++) { + result.append(interceptors.get(i).getClass().getCanonicalName()); + if (i != len - 1) { + result.append(" & "); + } + } + result.append("\tenhance: "); + result.append(className).append("::").append(methodName); + return result.toString(); + } +} 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..65eb584c6b 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,6 +19,7 @@ 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; @@ -69,6 +70,9 @@ protected Builder resolve(Builder builder, InDefinedShape methodDesc, List createdInterceptorForAdviceKey.add(interceptor.getClass().getCanonicalName()); } } + EnhanceInfoManager.addMethodDesc(plugin, interceptors, + methodDesc.getDeclaringType().getCanonicalName(), + methodDesc.getActualName()); if (checkAdviceLock(adviceKey)) { return builder.visit(Advice.to(templateCls).on(ElementMatchers.is(methodDesc))); }