Skip to content

Commit

Permalink
Merge pull request #1320 from luanwenfei-venus/develop_issue_1236_bug…
Browse files Browse the repository at this point in the history
…fix_new

修改 AgentCore 动态安装卸载功能测试问题
  • Loading branch information
Sherlockhan authored Sep 27, 2023
2 parents 26e0eb7 + 388cf0a commit 90cc418
Show file tree
Hide file tree
Showing 26 changed files with 445 additions and 285 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public static void install(String artifact, Map<String, Object> argsMap, Instrum
ClassLoaderManager.init(argsMap);

// 初始化日志
LoggerFactory.init();
LoggerFactory.init(artifact);

// 通过启动配置构建路径索引
BootArgsIndexer.build(argsMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void execute(String args) {
LOGGER.log(Level.WARNING, "The argument of command[INSTALL-PLUGINS] is empty.");
return;
}
String[] pluginNames = args.split("\\|");
String[] pluginNames = args.split("/");
PluginManager.install(Arrays.stream(pluginNames).collect(Collectors.toSet()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void execute(String args) {
LOGGER.log(Level.WARNING, "The argument of command[UNINSTALL-PLUGINS] is empty.");
return;
}
String[] pluginNames = args.split("\\|");
String[] pluginNames = args.split("/");
PluginManager.uninstall(Arrays.stream(pluginNames).collect(Collectors.toSet()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,25 +31,35 @@
* @since 2022-03-26
*/
public class LoggerFactory {
private static Logger logger = java.util.logging.Logger.getLogger("sermant");
private static final String LOGGER_FACTORY_IMPL_CLASS = "com.huaweicloud.sermant.implement.log.LoggerFactoryImpl";

private static final String LOGGER_INIT_METHOD = "init";

private static Logger defaultLogger;

private static Logger sermantLogger;

private LoggerFactory() {
}

/**
* 初始化logback配置文件路径
*
* @param artifact 归属产品
* @throws RuntimeException RuntimeException
*/
public static void init() {
FrameworkClassLoader frameworkClassLoader = ClassLoaderManager.getFrameworkClassLoader();
try {
Method initMethod = frameworkClassLoader
.loadClass("com.huaweicloud.sermant.implement.log.LoggerFactoryImpl").getMethod("init");
logger = (Logger) initMethod.invoke(null);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
| InvocationTargetException e) {
throw new RuntimeException(e);
public static void init(String artifact) {
if (sermantLogger == null) {
FrameworkClassLoader frameworkClassLoader = ClassLoaderManager.getFrameworkClassLoader();
try {
Method initMethod = frameworkClassLoader
.loadClass(LOGGER_FACTORY_IMPL_CLASS)
.getMethod(LOGGER_INIT_METHOD, String.class);
sermantLogger = (Logger) initMethod.invoke(null, artifact);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException
| InvocationTargetException e) {
throw new RuntimeException(e);
}
}
}

Expand All @@ -59,6 +69,14 @@ public static void init() {
* @return jul日志
*/
public static Logger getLogger() {
return logger;
if (sermantLogger != null) {
return sermantLogger;
}

// 避免日志重复获取
if (defaultLogger == null) {
defaultLogger = java.util.logging.Logger.getLogger("sermant");
}
return defaultLogger;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
import com.huaweicloud.sermant.core.plugin.agent.adviser.AdviserScheduler;
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;
import com.huaweicloud.sermant.core.plugin.classloader.ServiceClassLoader;
import com.huaweicloud.sermant.core.plugin.common.PluginConstant;
import com.huaweicloud.sermant.core.plugin.common.PluginSchemaValidator;
Expand All @@ -41,6 +42,7 @@
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -134,7 +136,8 @@ public static void uninstall(Set<String> pluginNames) {
* 卸载全部插件
*/
public static void uninstallAll() {
uninstall(PLUGIN_MAP.keySet());
// 新建一个Set,避免在清理插件时,删除PLUGIN_MAP缓存导致插件名Set被修改
uninstall(new HashSet<>(PLUGIN_MAP.keySet()));
}

/**
Expand Down Expand Up @@ -166,7 +169,7 @@ public static void initPlugins(Set<String> pluginNames, boolean isDynamic) {
if (!new File(pluginPath).exists()) {
LOGGER.log(Level.WARNING, "Plugin directory {0} does not exist, so skip initializing {1}. ",
new String[]{pluginPath, pluginName});
return;
continue;
}
doInitPlugin(
new Plugin(pluginName, pluginPath, isDynamic, ClassLoaderManager.createPluginClassLoader()));
Expand Down Expand Up @@ -349,12 +352,18 @@ private static File getServiceDir(String pluginPath) {

private static void closePluginLoaders(Plugin plugin) {
try {
plugin.getServiceClassLoader().close();
ServiceClassLoader serviceClassLoader = plugin.getServiceClassLoader();
if (serviceClassLoader != null) {
serviceClassLoader.close();
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Failed to close ServiceClassLoader for plugin:{0}", plugin.getName());
}
try {
plugin.getPluginClassLoader().close();
PluginClassLoader pluginClassLoader = plugin.getPluginClassLoader();
if (pluginClassLoader != null) {
pluginClassLoader.close();
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Failed to close PluginClassLoader for plugin:{0}", plugin.getName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,14 @@
import com.huaweicloud.sermant.core.operation.OperationManager;
import com.huaweicloud.sermant.core.operation.converter.api.YamlConverter;
import com.huaweicloud.sermant.core.plugin.config.PluginSetting;
import com.huaweicloud.sermant.core.utils.CollectionUtils;
import com.huaweicloud.sermant.core.utils.MapUtils;

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.nio.file.Files;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.logging.Logger;
Expand Down Expand Up @@ -57,7 +60,7 @@ public static void initialize(boolean isDynamic) {
Set<String> staticPlugins = pluginSetting.getPlugins();
if (!isDynamic) {
// 初始化支持静态安装的插件 premain方式启动时执行
if (staticPlugins == null || staticPlugins.isEmpty()) {
if (CollectionUtils.isEmpty(staticPlugins)) {
LOGGER.info("Non static-support-plugin is configured to be loaded.");
return;
}
Expand All @@ -66,11 +69,16 @@ public static void initialize(boolean isDynamic) {

if (isDynamic) {
// 初始化支持动态安装的主动启动插件 agentmain方式启动时执行
Set<String> activePlugins = pluginSetting.getDynamicPlugins().get("active");
if (activePlugins == null || activePlugins.isEmpty()) {
Map<String, Set<String>> dynamicPlugins = pluginSetting.getDynamicPlugins();
if (MapUtils.isEmpty(dynamicPlugins)) {
LOGGER.info("Non dynamic-support-plugin is configured to be loaded.");
return;
}
Set<String> activePlugins = dynamicPlugins.get("active");
if (CollectionUtils.isEmpty(activePlugins)) {
LOGGER.info("Non active dynamic-support-plugin is configured to be loaded.");
return;
}
PluginManager.initPlugins(activePlugins, true);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,14 +110,14 @@ private static PluginDescription combinePluginDeclarers(Plugin plugin) {
@Override
public Builder<?> transform(Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader,
JavaModule javaModule, ProtectionDomain protectionDomain) {
final List<PluginDeclarer> pluginDeclarers = nameCombinedMap.remove(typeDescription.getActualName());
final List<PluginDeclarer> pluginDeclarers = nameCombinedMap.get(typeDescription.getActualName());
final List<InterceptDeclarer> interceptDeclarers = new ArrayList<>();
for (PluginDeclarer pluginDeclarer : pluginDeclarers) {
interceptDeclarers.addAll(
Arrays.asList(pluginDeclarer.getInterceptDeclarers(ClassLoader.getSystemClassLoader())));
}
return new ReentrantTransformer(interceptDeclarers.toArray(new InterceptDeclarer[0]),
plugin).transform(builder, typeDescription, classLoader, javaModule, protectionDomain);
return new ReentrantTransformer(interceptDeclarers.toArray(new InterceptDeclarer[0]), plugin).transform(
builder, typeDescription, classLoader, javaModule, protectionDomain);
}

@Override
Expand All @@ -127,7 +127,9 @@ public boolean matches(TypeDescription target) {
if (matchTarget(declarer.getClassMatcher(), target)) {
List<PluginDeclarer> declarers = nameCombinedMap.computeIfAbsent(typeName,
k -> new ArrayList<>());
declarers.add(declarer);
if (!declarers.contains(declarer)) {
declarers.add(declarer);
}
}
}
return nameCombinedMap.containsKey(typeName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,6 @@ public class ServiceManager {
*/
private static final Map<String, BaseService> SERVICES = new HashMap<>();

/**
* Agent核心服务配置
*/
private static final ServiceConfig SERVICE_CONFIG = ConfigManager.getConfig(ServiceConfig.class);

/**
* Constructor.
*/
Expand All @@ -103,10 +98,11 @@ protected ServiceManager() {
* 初始化所有服务
*/
public static void initServices() {
ServiceConfig serviceConfig = ConfigManager.getConfig(ServiceConfig.class);
ArrayList<String> startServiceArray = new ArrayList<>();
for (final BaseService service : ServiceLoader.load(BaseService.class,
ClassLoaderManager.getFrameworkClassLoader())) {
if (SERVICE_CONFIG.checkServiceEnable(service.getClass().getName()) && loadService(service,
if (serviceConfig.checkServiceEnable(service.getClass().getName()) && loadService(service,
service.getClass(), BaseService.class)) {
service.start();
startServiceArray.add(service.getClass().getName());
Expand Down Expand Up @@ -183,28 +179,14 @@ protected static void stopService(String serviceName) {
*/
private static void addStopHook() {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
offerEvent();
for (String serviceName : SERVICES.keySet()) {
if (serviceName.equals(NETTY_GATEWAY_CLIENT) || serviceName.equals(
GatewayClient.class.getCanonicalName())) {
continue;
}
try {
SERVICES.get(serviceName).stop();
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "Error occurs while stopping service: " + serviceName, ex);
}
}
offerEvent();
BaseService nettyGateWayClient = SERVICES.remove(NETTY_GATEWAY_CLIENT);
SERVICES.remove(GatewayClient.class.getCanonicalName());
if (nettyGateWayClient != null) {
try {
nettyGateWayClient.stop();
} catch (Exception ex) {
LOGGER.log(Level.SEVERE, "Error occurs while stopping service: " + nettyGateWayClient.getClass(),
ex);
}
}
}));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,6 @@ public class SermantManager {
private SermantManager() {
}

/**
* 当前产品是否安装过Sermant
*
* @param artifact 标识基于Sermant的产品
* @return boolean
*/
public static boolean hasSermant(String artifact) {
return SERMANT_MANAGE_MAP.containsKey(artifact);
}

/**
* 创建Sermant
*
Expand All @@ -61,11 +51,21 @@ public static SermantClassLoader createSermant(String artifact, URL[] urls) {
return sermantClassLoader;
}

/**
* 获取Sermant
*
* @param artifact 标识Sermant
* @return SermantClassLoader
*/
public static SermantClassLoader getSermant(String artifact) {
return SERMANT_MANAGE_MAP.get(artifact);
}

/**
* 移除Sermant
*
* @param artifact 需要移除的Sermant的命名空间
* @exception RuntimeException RuntimeException
* @throws RuntimeException RuntimeException
*/
public static void removeSermant(String artifact) {
SermantClassLoader sermantClassLoader = SERMANT_MANAGE_MAP.get(artifact);
Expand Down Expand Up @@ -100,4 +100,14 @@ public static boolean checkSermantStatus(String artifact) {
public static void updateSermantStatus(String artifact, boolean status) {
SERMANT_STATUS.put(artifact, status);
}

/**
* 当前产品是否安装过Sermant
*
* @param artifact 标识基于Sermant的产品
* @return boolean
*/
private static boolean hasSermant(String artifact) {
return SERMANT_MANAGE_MAP.containsKey(artifact);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,35 @@
public class LoggerFactoryImpl {
private static final String LOG_LEVEL_KEY = "sermant_log_level";

private static final String INFO = "info";

private static final String ALL = "all";

private static final String TRACE = "trace";

private static final String DEBUG = "debug";

private static final String WARN = "warn";

private static final String ERROR = "error";

private static final String OFF = "off";

private LoggerFactoryImpl() {
}

/**
* init
*
* @return logger logger for sermant
* @param artifact 归属产品
* @return return logger logger for sermant
*/
public static Logger init() {
Logger logger = java.util.logging.Logger.getLogger("sermant");
public static Logger init(String artifact) {
Logger logger = java.util.logging.Logger.getLogger("sermant." + artifact);
return getLogger(logger);
}

private static Logger getLogger(Logger logger) {
logger.addHandler(new SermantBridgeHandler());
logger.setUseParentHandlers(false);
logger.setLevel(getLevel());
Expand All @@ -51,21 +70,21 @@ private static Level getLevel() {
// 环境变量 > 启动参数
String level = System.getenv(LOG_LEVEL_KEY);
if (StringUtils.isBlank(level)) {
level = System.getProperty(LOG_LEVEL_KEY, "info");
level = System.getProperty(LOG_LEVEL_KEY, INFO);
}
level = level.toLowerCase(Locale.ROOT);
switch (level) {
case "all":
case ALL:
return Level.ALL;
case "trace":
case TRACE:
return Level.FINEST;
case "debug":
case DEBUG:
return Level.FINE;
case "warn":
case WARN:
return Level.WARNING;
case "error":
case ERROR:
return Level.SEVERE;
case "off":
case OFF:
return Level.OFF;
default:
return Level.INFO;
Expand Down
Loading

0 comments on commit 90cc418

Please sign in to comment.