From 40c2c5e039db0809f9f0959a988a19839ace88a0 Mon Sep 17 00:00:00 2001 From: gongdewei Date: Tue, 14 Jul 2020 20:12:57 +0800 Subject: [PATCH] transform command: logger --- .../core/command/logger/LoggerCommand.java | 148 +++++------------- .../core/command/model/LoggerModel.java | 34 ++++ .../arthas/core/command/view/LoggerView.java | 98 ++++++++++++ 3 files changed, 174 insertions(+), 106 deletions(-) create mode 100644 core/src/main/java/com/taobao/arthas/core/command/model/LoggerModel.java create mode 100644 core/src/main/java/com/taobao/arthas/core/command/view/LoggerView.java diff --git a/core/src/main/java/com/taobao/arthas/core/command/logger/LoggerCommand.java b/core/src/main/java/com/taobao/arthas/core/command/logger/LoggerCommand.java index a2a1d45d9..d05b56964 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/logger/LoggerCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/logger/LoggerCommand.java @@ -1,7 +1,5 @@ package com.taobao.arthas.core.command.logger; -import static com.taobao.text.ui.Element.label; - import java.io.IOException; import java.io.InputStream; import java.lang.instrument.Instrumentation; @@ -21,6 +19,7 @@ import com.alibaba.arthas.deps.org.slf4j.LoggerFactory; import com.taobao.arthas.common.IOUtils; import com.taobao.arthas.common.ReflectUtils; import com.taobao.arthas.core.command.Constants; +import com.taobao.arthas.core.command.model.LoggerModel; import com.taobao.arthas.core.shell.command.AnnotatedCommand; import com.taobao.arthas.core.shell.command.CommandProcess; import com.taobao.arthas.core.util.ClassLoaderUtils; @@ -29,15 +28,11 @@ import com.taobao.middleware.cli.annotations.Description; import com.taobao.middleware.cli.annotations.Name; import com.taobao.middleware.cli.annotations.Option; import com.taobao.middleware.cli.annotations.Summary; -import com.taobao.text.Decoration; -import com.taobao.text.ui.TableElement; -import com.taobao.text.util.RenderUtil; /** * logger command - * - * @author hengyunabc 2019-09-04 * + * @author hengyunabc 2019-09-04 */ //@formatter:off @Name("logger") @@ -60,7 +55,7 @@ public class LoggerCommand extends AnnotatedCommand { private static Map, byte[]> classToBytesMap = new HashMap, byte[]>(); private static String arthasClassLoaderHash = ClassLoaderUtils - .classLoaderHash(LoggerCommand.class.getClassLoader()); + .classLoaderHash(LoggerCommand.class.getClassLoader()); static { LoggerHelperBytes = loadClassBytes(LoggerHelper.class); @@ -111,15 +106,11 @@ public class LoggerCommand extends AnnotatedCommand { @Override public void process(CommandProcess process) { - int status = 0; - try { - if (this.name != null && this.level != null) { - level(process); - } else { - loggers(process, name); - } - } finally { - process.end(status); + // 每个分支中调用process.end()结束执行 + if (this.name != null && this.level != null) { + level(process); + } else { + loggers(process, name); } } @@ -154,9 +145,9 @@ public class LoggerCommand extends AnnotatedCommand { } if (result) { - process.write("Update logger level success.\n"); + process.end(0, "Update logger level success."); } else { - process.write("Update logger level fail. Try to specify the classloader with the -c option. Use `sc -d CLASSNAME` to find out the classloader hashcode.\n"); + process.end(-1, "Update logger level fail. Try to specify the classloader with the -c option. Use `sc -d CLASSNAME` to find out the classloader hashcode."); } } @@ -194,97 +185,21 @@ public class LoggerCommand extends AnnotatedCommand { if (loggerTypes.contains(LoggerType.LOG4J)) { Map> loggerInfoMap = loggerInfo(classLoader, Log4jHelper.class); - String renderResult = renderLoggerInfo(loggerInfoMap, process.width()); - - process.write(renderResult); + process.appendResult(new LoggerModel(loggerInfoMap)); } if (loggerTypes.contains(LoggerType.LOGBACK)) { Map> loggerInfoMap = loggerInfo(classLoader, LogbackHelper.class); - String renderResult = renderLoggerInfo(loggerInfoMap, process.width()); - - process.write(renderResult); + process.appendResult(new LoggerModel(loggerInfoMap)); } if (loggerTypes.contains(LoggerType.LOG4J2)) { Map> loggerInfoMap = loggerInfo(classLoader, Log4j2Helper.class); - String renderResult = renderLoggerInfo(loggerInfoMap, process.width()); - - process.write(renderResult); + process.appendResult(new LoggerModel(loggerInfoMap)); } } - } - - private String renderLoggerInfo(Map> loggerInfos, int width) { - StringBuilder sb = new StringBuilder(8192); - - for (Entry> entry : loggerInfos.entrySet()) { - Map info = entry.getValue(); - - TableElement table = new TableElement(2, 10).leftCellPadding(1).rightCellPadding(1); - TableElement appendersTable = new TableElement().rightCellPadding(1); - - Class clazz = (Class) info.get(LoggerHelper.clazz); - table.row(label(LoggerHelper.name).style(Decoration.bold.bold()), label("" + info.get(LoggerHelper.name))) - .row(label(LoggerHelper.clazz).style(Decoration.bold.bold()), label("" + clazz.getName())) - .row(label(LoggerHelper.classLoader).style(Decoration.bold.bold()), - label("" + clazz.getClassLoader())) - .row(label(LoggerHelper.classLoaderHash).style(Decoration.bold.bold()), - label("" + StringUtils.classLoaderHash(clazz))) - .row(label(LoggerHelper.level).style(Decoration.bold.bold()), - label("" + info.get(LoggerHelper.level))); - if (info.get(LoggerHelper.effectiveLevel) != null) { - table.row(label(LoggerHelper.effectiveLevel).style(Decoration.bold.bold()), - label("" + info.get(LoggerHelper.effectiveLevel))); - } - - if (info.get(LoggerHelper.config) != null) { - table.row(label(LoggerHelper.config).style(Decoration.bold.bold()), - label("" + info.get(LoggerHelper.config))); - } - - table.row(label(LoggerHelper.additivity).style(Decoration.bold.bold()), - label("" + info.get(LoggerHelper.additivity))) - .row(label(LoggerHelper.codeSource).style(Decoration.bold.bold()), - label("" + info.get(LoggerHelper.codeSource))); - - @SuppressWarnings("unchecked") - List> appenders = (List>) info.get(LoggerHelper.appenders); - if (appenders != null && !appenders.isEmpty()) { - - for (Map appenderInfo : appenders) { - Class appenderClass = (Class) appenderInfo.get(LoggerHelper.clazz); - - appendersTable.row(label(LoggerHelper.name).style(Decoration.bold.bold()), - label("" + appenderInfo.get(LoggerHelper.name))); - appendersTable.row(label(LoggerHelper.clazz), label("" + appenderClass.getName())); - appendersTable.row(label(LoggerHelper.classLoader), label("" + appenderClass.getClassLoader())); - appendersTable.row(label(LoggerHelper.classLoaderHash), - label("" + StringUtils.classLoaderHash(appenderClass))); - if (appenderInfo.get(LoggerHelper.file) != null) { - appendersTable.row(label(LoggerHelper.file), label("" + appenderInfo.get(LoggerHelper.file))); - } - if (appenderInfo.get(LoggerHelper.target) != null) { - appendersTable.row(label(LoggerHelper.target), - label("" + appenderInfo.get(LoggerHelper.target))); - } - if (appenderInfo.get(LoggerHelper.blocking) != null) { - appendersTable.row(label(LoggerHelper.blocking), - label("" + appenderInfo.get(LoggerHelper.blocking))); - } - if (appenderInfo.get(LoggerHelper.appenderRef) != null) { - appendersTable.row(label(LoggerHelper.appenderRef), - label("" + appenderInfo.get(LoggerHelper.appenderRef))); - } - } - - table.row(label("appenders").style(Decoration.bold.bold()), appendersTable); - } - - sb.append(RenderUtil.render(table, width)).append('\n'); - } - return sb.toString(); + process.end(); } private static String helperClassNameWithClassLoader(ClassLoader classLoader, Class helperClass) { @@ -304,25 +219,46 @@ public class LoggerCommand extends AnnotatedCommand { } catch (ClassNotFoundException e) { try { byte[] helperClassBytes = AsmRenameUtil.renameClass(classToBytesMap.get(helperClass), - helperClass.getName(), helperClassName); + helperClass.getName(), helperClassName); ReflectUtils.defineClass(helperClassName, helperClassBytes, classLoader); } catch (Throwable e1) { logger.error("arthas loggger command try to define helper class error: " + helperClassName, - e1); + e1); } } try { Class clazz = classLoader.loadClass(helperClassName); - Method getLoggersMethod = clazz.getMethod("getLoggers", new Class[] { String.class, boolean.class }); + Method getLoggersMethod = clazz.getMethod("getLoggers", new Class[]{String.class, boolean.class}); loggers = (Map>) getLoggersMethod.invoke(null, - new Object[] { name, includeNoAppender }); + new Object[]{name, includeNoAppender}); } catch (Throwable e) { // ignore } + + //expose attributes to json: classloader, classloaderHash + for (Map loggerInfo : loggers.values()) { + Class clazz = (Class) loggerInfo.get(LoggerHelper.clazz); + loggerInfo.put(LoggerHelper.classLoader, getClassLoaderName(clazz.getClassLoader())); + loggerInfo.put(LoggerHelper.classLoaderHash, StringUtils.classLoaderHash(clazz)); + + List> appenders = (List>) loggerInfo.get(LoggerHelper.appenders); + for (Map appenderInfo : appenders) { + Class appenderClass = (Class) appenderInfo.get(LoggerHelper.clazz); + if (appenderClass != null) { + appenderInfo.put(LoggerHelper.classLoader, getClassLoaderName(appenderClass.getClassLoader())); + appenderInfo.put(LoggerHelper.classLoaderHash, StringUtils.classLoaderHash(appenderClass)); + } + } + } + return loggers; } + private String getClassLoaderName(ClassLoader classLoader) { + return classLoader == null ? null : classLoader.toString(); + } + private Boolean updateLevel(Instrumentation inst, Class helperClass) throws Exception { ClassLoader classLoader = null; if (hashCode == null) { @@ -332,8 +268,8 @@ public class LoggerCommand extends AnnotatedCommand { } Class clazz = classLoader.loadClass(helperClassNameWithClassLoader(classLoader, helperClass)); - Method updateLevelMethod = clazz.getMethod("updateLevel", new Class[] { String.class, String.class }); - return (Boolean) updateLevelMethod.invoke(null, new Object[] { this.name, this.level }); + Method updateLevelMethod = clazz.getMethod("updateLevel", new Class[]{String.class, String.class}); + return (Boolean) updateLevelMethod.invoke(null, new Object[]{this.name, this.level}); } @@ -360,7 +296,7 @@ public class LoggerCommand extends AnnotatedCommand { private static byte[] loadClassBytes(Class clazz) { try { InputStream stream = LoggerCommand.class.getClassLoader() - .getResourceAsStream(clazz.getName().replace('.', '/') + ".class"); + .getResourceAsStream(clazz.getName().replace('.', '/') + ".class"); return IOUtils.getBytes(stream); } catch (IOException e) { diff --git a/core/src/main/java/com/taobao/arthas/core/command/model/LoggerModel.java b/core/src/main/java/com/taobao/arthas/core/command/model/LoggerModel.java new file mode 100644 index 000000000..05ee2e0ac --- /dev/null +++ b/core/src/main/java/com/taobao/arthas/core/command/model/LoggerModel.java @@ -0,0 +1,34 @@ +package com.taobao.arthas.core.command.model; + +import java.util.Map; + +/** + * Model of logger command + * + * @author gongdewei 2020/4/22 + */ +public class LoggerModel extends ResultModel { + + private Map> loggerInfoMap; + + public LoggerModel() { + } + + public LoggerModel(Map> loggerInfoMap) { + this.loggerInfoMap = loggerInfoMap; + } + + public Map> getLoggerInfoMap() { + return loggerInfoMap; + } + + public void setLoggerInfoMap(Map> loggerInfoMap) { + this.loggerInfoMap = loggerInfoMap; + } + + @Override + public String getType() { + return "logger"; + } + +} diff --git a/core/src/main/java/com/taobao/arthas/core/command/view/LoggerView.java b/core/src/main/java/com/taobao/arthas/core/command/view/LoggerView.java new file mode 100644 index 000000000..b6d925aa4 --- /dev/null +++ b/core/src/main/java/com/taobao/arthas/core/command/view/LoggerView.java @@ -0,0 +1,98 @@ +package com.taobao.arthas.core.command.view; + +import com.taobao.arthas.core.command.logger.LoggerHelper; +import com.taobao.arthas.core.command.model.LoggerModel; +import com.taobao.arthas.core.shell.command.CommandProcess; +import com.taobao.arthas.core.util.StringUtils; +import com.taobao.text.Decoration; +import com.taobao.text.ui.TableElement; +import com.taobao.text.util.RenderUtil; + +import java.util.List; +import java.util.Map; + +import static com.taobao.text.ui.Element.label; + +/** + * View of 'logger' command + * + * @author gongdewei 2020/4/22 + */ +public class LoggerView extends ResultView { + + @Override + public void draw(CommandProcess process, LoggerModel result) { + process.write(renderLoggerInfo(result.getLoggerInfoMap(), process.width())); + } + + private String renderLoggerInfo(Map> loggerInfos, int width) { + StringBuilder sb = new StringBuilder(8192); + + for (Map.Entry> entry : loggerInfos.entrySet()) { + Map info = entry.getValue(); + + TableElement table = new TableElement(2, 10).leftCellPadding(1).rightCellPadding(1); + TableElement appendersTable = new TableElement().rightCellPadding(1); + + Class clazz = (Class) info.get(LoggerHelper.clazz); + table.row(label(LoggerHelper.name).style(Decoration.bold.bold()), label("" + info.get(LoggerHelper.name))) + .row(label(LoggerHelper.clazz).style(Decoration.bold.bold()), label("" + clazz.getName())) + .row(label(LoggerHelper.classLoader).style(Decoration.bold.bold()), + label("" + info.get(LoggerHelper.classLoader))) + .row(label(LoggerHelper.classLoaderHash).style(Decoration.bold.bold()), + label("" + info.get(LoggerHelper.classLoaderHash))) + .row(label(LoggerHelper.level).style(Decoration.bold.bold()), + label("" + info.get(LoggerHelper.level))); + if (info.get(LoggerHelper.effectiveLevel) != null) { + table.row(label(LoggerHelper.effectiveLevel).style(Decoration.bold.bold()), + label("" + info.get(LoggerHelper.effectiveLevel))); + } + + if (info.get(LoggerHelper.config) != null) { + table.row(label(LoggerHelper.config).style(Decoration.bold.bold()), + label("" + info.get(LoggerHelper.config))); + } + + table.row(label(LoggerHelper.additivity).style(Decoration.bold.bold()), + label("" + info.get(LoggerHelper.additivity))) + .row(label(LoggerHelper.codeSource).style(Decoration.bold.bold()), + label("" + info.get(LoggerHelper.codeSource))); + + @SuppressWarnings("unchecked") + List> appenders = (List>) info.get(LoggerHelper.appenders); + if (appenders != null && !appenders.isEmpty()) { + + for (Map appenderInfo : appenders) { + Class appenderClass = (Class) appenderInfo.get(LoggerHelper.clazz); + + appendersTable.row(label(LoggerHelper.name).style(Decoration.bold.bold()), + label("" + appenderInfo.get(LoggerHelper.name))); + appendersTable.row(label(LoggerHelper.clazz), label("" + appenderClass.getName())); + appendersTable.row(label(LoggerHelper.classLoader), label("" + info.get(LoggerHelper.classLoader))); + appendersTable.row(label(LoggerHelper.classLoaderHash), + label("" + info.get(LoggerHelper.classLoaderHash))); + if (appenderInfo.get(LoggerHelper.file) != null) { + appendersTable.row(label(LoggerHelper.file), label("" + appenderInfo.get(LoggerHelper.file))); + } + if (appenderInfo.get(LoggerHelper.target) != null) { + appendersTable.row(label(LoggerHelper.target), + label("" + appenderInfo.get(LoggerHelper.target))); + } + if (appenderInfo.get(LoggerHelper.blocking) != null) { + appendersTable.row(label(LoggerHelper.blocking), + label("" + appenderInfo.get(LoggerHelper.blocking))); + } + if (appenderInfo.get(LoggerHelper.appenderRef) != null) { + appendersTable.row(label(LoggerHelper.appenderRef), + label("" + appenderInfo.get(LoggerHelper.appenderRef))); + } + } + + table.row(label("appenders").style(Decoration.bold.bold()), appendersTable); + } + + sb.append(RenderUtil.render(table, width)).append('\n'); + } + return sb.toString(); + } +}