support rescan plugins. #558

4.0.x
hengyunabc 6 years ago
parent 273e635f78
commit 88fe2eae5a

@ -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
}

Loading…
Cancel
Save