mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
support rescan plugins. #558
This commit is contained in:
@@ -9,7 +9,6 @@ import java.util.Properties;
|
||||
|
||||
import com.alibaba.arthas.deps.org.slf4j.Logger;
|
||||
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
|
||||
import com.alibaba.arthas.plugin.PluginException;
|
||||
import com.alibaba.arthas.plugin.PluginManager;
|
||||
import com.taobao.arthas.common.FeatureCodec;
|
||||
|
||||
@@ -92,10 +91,10 @@ public class ArthasAgent {
|
||||
properties.putAll(map);
|
||||
|
||||
logger.debug("PluginManager properties: {}", properties);
|
||||
pluginManager = new PluginManager(inst, properties);
|
||||
try {
|
||||
pluginManager = new PluginManager(inst, properties, new File(arthasHome, "plugins").toURI().toURL());
|
||||
|
||||
pluginManager.scanPlugins(new File(arthasHome, "plugins"));
|
||||
pluginManager.scanPlugins();
|
||||
|
||||
pluginManager.enablePlugins();
|
||||
|
||||
@@ -103,7 +102,7 @@ public class ArthasAgent {
|
||||
|
||||
pluginManager.startPlugins();
|
||||
|
||||
} catch (PluginException e) {
|
||||
} catch (Exception e) {
|
||||
logger.error("PluginManager error", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@ public class PluginsCommand extends AnnotatedCommand {
|
||||
|
||||
private String uninstallPlugin;
|
||||
|
||||
private boolean reScanPlugins;
|
||||
|
||||
@Option(shortName = "l", longName = "list")
|
||||
@Description("List plugins")
|
||||
public void setListPlugins(boolean listPlugins) {
|
||||
@@ -54,6 +56,12 @@ public class PluginsCommand extends AnnotatedCommand {
|
||||
this.uninstallPlugin = plugin;
|
||||
}
|
||||
|
||||
@Option(longName = "rescan")
|
||||
@Description("Rescan plugin")
|
||||
public void setReScan(boolean reScanPlugins) {
|
||||
this.reScanPlugins = reScanPlugins;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void process(CommandProcess process) {
|
||||
int exitCode = 0;
|
||||
@@ -83,7 +91,11 @@ public class PluginsCommand extends AnnotatedCommand {
|
||||
} else {
|
||||
process.write("Can not find plugin " + uninstallPlugin + "\n");
|
||||
}
|
||||
} else {
|
||||
} else if( this.reScanPlugins) {
|
||||
pluginMaanger.scanPlugins();
|
||||
process.write("Rescan plugins success.\n");
|
||||
}
|
||||
else {
|
||||
TableElement table = new TableElement().leftCellPadding(1).rightCellPadding(1);
|
||||
table.row(true, label("Order").style(Decoration.bold.bold()),
|
||||
label("Name").style(Decoration.bold.bold()),
|
||||
@@ -96,6 +108,7 @@ public class PluginsCommand extends AnnotatedCommand {
|
||||
process.write(RenderUtil.render(table, process.width()));
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
process.write("Error: " + e.getMessage() + "\n");
|
||||
logger.error(null, null, e);
|
||||
}
|
||||
process.end(exitCode);
|
||||
|
||||
@@ -11,6 +11,8 @@ import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import com.alibaba.arthas.deps.org.slf4j.Logger;
|
||||
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
|
||||
import com.taobao.arthas.common.IOUtils;
|
||||
import com.taobao.arthas.common.properties.PropertiesInjectUtil;
|
||||
|
||||
@@ -20,6 +22,7 @@ import com.taobao.arthas.common.properties.PropertiesInjectUtil;
|
||||
*
|
||||
*/
|
||||
public class ArthasPlugin implements Plugin {
|
||||
private static final Logger logger = LoggerFactory.getLogger(PluginManager.class);
|
||||
|
||||
public static final int DEFAULT_ORDER = 1000;
|
||||
|
||||
@@ -79,10 +82,15 @@ public class ArthasPlugin implements Plugin {
|
||||
Class<?> activatorClass = classLoader.loadClass(pluginConfig.getPluginActivator());
|
||||
pluginActivator = (PluginActivator) activatorClass.newInstance();
|
||||
enabled = pluginActivator.enabled(pluginContext);
|
||||
if (!enabled) {
|
||||
if (enabled) {
|
||||
this.state = PluginState.ENABLED;
|
||||
} else {
|
||||
this.state = PluginState.DISABLED;
|
||||
logger.info("plugin {} disabled.", this.pluginConfig.getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
} catch (Throwable e) {
|
||||
this.state = PluginState.ERROR;
|
||||
throw new PluginException("check enabled plugin error, plugin name: " + pluginConfig.getName(), e);
|
||||
}
|
||||
return enabled;
|
||||
@@ -92,7 +100,8 @@ public class ArthasPlugin implements Plugin {
|
||||
public void init() throws PluginException {
|
||||
try {
|
||||
pluginActivator.init(pluginContext);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
this.state = PluginState.ERROR;
|
||||
throw new PluginException("init plugin error, plugin name: " + pluginConfig.getName(), e);
|
||||
}
|
||||
}
|
||||
@@ -101,7 +110,8 @@ public class ArthasPlugin implements Plugin {
|
||||
public void start() throws PluginException {
|
||||
try {
|
||||
pluginActivator.start(pluginContext);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
this.state = PluginState.ERROR;
|
||||
throw new PluginException("start plugin error, plugin name: " + pluginConfig.getName(), e);
|
||||
}
|
||||
}
|
||||
@@ -110,7 +120,8 @@ public class ArthasPlugin implements Plugin {
|
||||
public void stop() throws PluginException {
|
||||
try {
|
||||
pluginActivator.stop(pluginContext);
|
||||
} catch (Exception e) {
|
||||
} catch (Throwable e) {
|
||||
this.state = PluginState.ERROR;
|
||||
throw new PluginException("stop plugin error, plugin name: " + pluginConfig.getName(), e);
|
||||
}
|
||||
}
|
||||
@@ -171,5 +182,4 @@ public class ArthasPlugin implements Plugin {
|
||||
return urls;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.alibaba.arthas.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.instrument.Instrumentation;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
@@ -17,6 +18,8 @@ import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
|
||||
*
|
||||
*/
|
||||
public class PluginManager {
|
||||
private static final Logger logger = LoggerFactory.getLogger(PluginManager.class);
|
||||
|
||||
private ClassLoader parentClassLoader = PluginManager.class.getClassLoader();
|
||||
private List<Plugin> plugins = new ArrayList<Plugin>();
|
||||
|
||||
@@ -24,33 +27,37 @@ public class PluginManager {
|
||||
|
||||
private Properties properties;
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(PluginManager.class);
|
||||
private List<URL> scanPluginlLoacations = new ArrayList<URL>();
|
||||
|
||||
public PluginManager(Instrumentation instrumentation, Properties properties) {
|
||||
public PluginManager(Instrumentation instrumentation, Properties properties, URL scanPluginLocation) {
|
||||
this.instrumentation = instrumentation;
|
||||
this.properties = properties;
|
||||
this.scanPluginlLoacations.add(scanPluginLocation);
|
||||
}
|
||||
|
||||
// 可能会执行多次
|
||||
synchronized public void scanPlugins(File dir) throws PluginException {
|
||||
try {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (!file.isHidden() && file.isDirectory()) {
|
||||
ArthasPlugin plugin = new ArthasPlugin(file.toURI().toURL(), instrumentation, parentClassLoader, properties);
|
||||
if (!containsPlugin(plugin.name())) {
|
||||
plugins.add(plugin);
|
||||
synchronized public void scanPlugins() throws PluginException {
|
||||
for (URL scanLocation : scanPluginlLoacations) {
|
||||
File dir = new File(scanLocation.getFile());
|
||||
try {
|
||||
File[] files = dir.listFiles();
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
if (!file.isHidden() && file.isDirectory()) {
|
||||
ArthasPlugin plugin = new ArthasPlugin(file.toURI().toURL(), instrumentation,
|
||||
parentClassLoader, properties);
|
||||
if (!containsPlugin(plugin.name())) {
|
||||
plugins.add(plugin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new PluginException("scan plugins error.", e);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new PluginException("scan plugins error.", e);
|
||||
}
|
||||
|
||||
Collections.sort(plugins, new PluginComparator());
|
||||
|
||||
}
|
||||
|
||||
synchronized public boolean containsPlugin(String name) {
|
||||
@@ -73,19 +80,25 @@ public class PluginManager {
|
||||
|
||||
public void startPlugin(String name) throws PluginException {
|
||||
Plugin plugin = findPlugin(name);
|
||||
if (plugin != null && (plugin.state() == PluginState.NONE || plugin.state() == PluginState.STOPED)) {
|
||||
updateState(plugin, PluginState.INITING);
|
||||
logger.info("Init plugin, name: {}", plugin.name());
|
||||
plugin.init();
|
||||
logger.info("Init plugin success, name: {}", plugin.name());
|
||||
updateState(plugin, PluginState.INITED);
|
||||
}
|
||||
if (plugin != null && plugin.state() == PluginState.INITED) {
|
||||
updateState(plugin, PluginState.STARTING);
|
||||
logger.info("Start plugin, name: {}", plugin.name());
|
||||
plugin.start();
|
||||
logger.info("Start plugin success, name: {}", plugin.name());
|
||||
updateState(plugin, PluginState.STARTED);
|
||||
if (plugin != null) {
|
||||
if (plugin.state() == PluginState.NONE || plugin.state() == PluginState.STOPED) {
|
||||
plugin.enabled();
|
||||
}
|
||||
if (plugin.state() == PluginState.ENABLED) {
|
||||
updateState(plugin, PluginState.INITING);
|
||||
logger.info("Init plugin, name: {}", plugin.name());
|
||||
plugin.init();
|
||||
logger.info("Init plugin success, name: {}", plugin.name());
|
||||
updateState(plugin, PluginState.INITED);
|
||||
}
|
||||
|
||||
if (plugin.state() == PluginState.INITED) {
|
||||
updateState(plugin, PluginState.STARTING);
|
||||
logger.info("Start plugin, name: {}", plugin.name());
|
||||
plugin.start();
|
||||
logger.info("Start plugin success, name: {}", plugin.name());
|
||||
updateState(plugin, PluginState.STARTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,8 +125,9 @@ public class PluginManager {
|
||||
|
||||
public void enablePlugin(String name) {
|
||||
Plugin plugin = findPlugin(name);
|
||||
if (plugin != null && plugin.state() == PluginState.DISABLED) {
|
||||
updateState(plugin, PluginState.NONE);
|
||||
if (plugin != null && (plugin.state() == PluginState.DISABLED || plugin.state() == PluginState.NONE
|
||||
|| plugin.state() == PluginState.STOPED)) {
|
||||
updateState(plugin, PluginState.ENABLED);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +139,7 @@ public class PluginManager {
|
||||
|
||||
synchronized public List<Plugin> allPlugins() {
|
||||
ArrayList<Plugin> result = new ArrayList<Plugin>(plugins.size());
|
||||
Collections.copy(result, plugins);
|
||||
result.addAll(plugins);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -142,7 +156,7 @@ public class PluginManager {
|
||||
synchronized public void initPlugins() throws PluginException {
|
||||
logger.info("Init available plugins");
|
||||
for (Plugin plugin : plugins) {
|
||||
if (plugin.state() == PluginState.NONE) {
|
||||
if (plugin.state() == PluginState.ENABLED) {
|
||||
updateState(plugin, PluginState.INITING);
|
||||
logger.info("Init plugin, name: {}", plugin.name());
|
||||
plugin.init();
|
||||
|
||||
@@ -8,6 +8,6 @@ package com.alibaba.arthas.plugin;
|
||||
*/
|
||||
public enum PluginState {
|
||||
|
||||
NONE, DISABLED, INITING, INITED, STARTING, STARTED, STOPPING, STOPED
|
||||
NONE, ENABLED, DISABLED, INITING, INITED, STARTING, STARTED, STOPPING, STOPED, ERROR
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user