Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Acquire sermant enhancement information: plugins, enhancement classes, methods #1355

Merged
merged 1 commit into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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.EnhancementManager;
import com.huaweicloud.sermant.core.plugin.agent.template.DefaultAdviser;
import com.huaweicloud.sermant.core.service.ServiceManager;
import com.huaweicloud.sermant.god.common.SermantManager;
Expand Down Expand Up @@ -157,6 +158,9 @@ public static void uninstall() {
// 清理配置类
ConfigManager.shutdown();

// 清理增强信息类
EnhancementManager.shutdown();

// 设置该artifact的Sermant状态为false,非运行状态
SermantManager.updateSermantStatus(artifactCache, false);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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.EnhancementManager;
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 CheckEnhancementsCommandExecutor implements CommandExecutor {
private static final Logger LOGGER = LoggerFactory.getLogger();

@Override
public void execute(String args) {
LOGGER.log(Level.INFO, "---------- PLUGINS ----------");
for (Map.Entry<String, Plugin> entry : PluginManager.getPluginMap().entrySet()) {
LOGGER.log(Level.INFO, entry.getKey() + ":" + entry.getValue().getVersion());
}
LOGGER.log(Level.INFO, "---------- ENHANCEMENTS ----------");
Map<String, Map<String, Set<String>>> enhancement = EnhancementManager.getEnhancements();
if (MapUtils.isEmpty(enhancement)) {
LOGGER.log(Level.INFO, "No enhancement currently.");
return;
}
for (Map.Entry<String, Map<String, Set<String>>> enhancemantEntry : enhancement.entrySet()) {
Map<String, Set<String>> methodDescMap = enhancemantEntry.getValue();
if (MapUtils.isEmpty(methodDescMap)) {
continue;
}
String pluginInfo = enhancemantEntry.getKey();
LOGGER.log(Level.INFO, pluginInfo);
for (Map.Entry<String, Set<String>> methodDescEntry : methodDescMap.entrySet()) {
Set<String> interceptorSet = methodDescEntry.getValue();
if (CollectionUtils.isEmpty(interceptorSet)) {
continue;
}
String methodDesc = methodDescEntry.getKey();
LOGGER.log(Level.INFO, methodDesc + " " + interceptorSet);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 CheckEnhancementsCommandExecutor());
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.EnhancementManager;
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;
Expand Down Expand Up @@ -108,6 +109,9 @@ public static void uninstall(Set<String> pluginNames) {
// 取消字节码增强
ByteEnhanceManager.unEnhanceDynamicPlugin(plugin);

// 清除增强信息
EnhancementManager.removePluginEnhancements(plugin);

// 关闭插件服务
PluginServiceManager.shutdownPluginServices(plugin);

Expand Down Expand Up @@ -183,6 +187,10 @@ public static void initPlugins(Set<String> pluginNames, boolean isDynamic) {
}
}

public static Map<String, Plugin> getPluginMap() {
return PLUGIN_MAP;
}

private static void doInitPlugin(Plugin plugin) {
loadPluginLibs(plugin);
loadServiceLibs(plugin);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* 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.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 EnhancementManager {
private static final Map<String, Map<String, Set<String>>> ENHANCEMENTS = new HashMap<>();

private EnhancementManager() {
}

public static Map<String, Map<String, Set<String>>> getEnhancements() {
return ENHANCEMENTS;
}

/**
* 添加拦截器信息
*
* @param plugin 插件
* @param interceptorList 拦截器列表
* @param classLoader 类加载器
* @param methodDesc 被增强方法的信息
*/
public static void addEnhancements(Plugin plugin, List<Interceptor> interceptorList, ClassLoader classLoader,
String methodDesc) {
String enhancementKey = combinePluginInfo(plugin);
if (!StringUtils.isEmpty(methodDesc)) {
Map<String, Set<String>> methodDescMap = ENHANCEMENTS.computeIfAbsent(enhancementKey,
key -> new HashMap<>());
String methodDescKey = combineEnhanceInfo(methodDesc, classLoader);
Set<String> interceptorSet = methodDescMap.computeIfAbsent(methodDescKey, key -> new HashSet<>());
for (Interceptor interceptor : interceptorList) {
interceptorSet.add(interceptor.getClass().getCanonicalName());
}
}
}

/**
* 卸载插件时清除该插件的增强信息
*
* @param plugin 插件
*/
public static void removePluginEnhancements(Plugin plugin) {
ENHANCEMENTS.remove(combinePluginInfo(plugin));
}

/**
* 清理缓存的增强信息
*/
public static void shutdown() {
ENHANCEMENTS.clear();
}

/**
* 拼接插件信息
*/
private static String combinePluginInfo(Plugin plugin) {
return plugin.getName() + ":" + plugin.getVersion();
}

/**
* 拼接增强信息
*/
private static String combineEnhanceInfo(String methodDesc, ClassLoader classLoader) {
return methodDesc + "@" + classLoader;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.EnhancementManager;
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;
Expand Down Expand Up @@ -69,6 +71,8 @@ protected Builder<?> resolve(Builder<?> builder, InDefinedShape methodDesc, List
createdInterceptorForAdviceKey.add(interceptor.getClass().getCanonicalName());
}
}
EnhancementManager.addEnhancements(plugin, interceptors, classLoader,
MethodKeyCreator.getMethodDescKey(methodDesc));
if (checkAdviceLock(adviceKey)) {
return builder.visit(Advice.to(templateCls).on(ElementMatchers.is(methodDesc)));
}
Expand Down
Loading