mirror of
https://gitee.com/arthas/arthas.git
synced 2024-12-02 04:08:34 +08:00
transform command: logger
This commit is contained in:
parent
4a48a7b073
commit
40c2c5e039
@ -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<Class<?>, byte[]> classToBytesMap = new HashMap<Class<?>, 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<String, Map<String, Object>> 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<String, Map<String, Object>> 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<String, Map<String, Object>> loggerInfoMap = loggerInfo(classLoader, Log4j2Helper.class);
|
||||
String renderResult = renderLoggerInfo(loggerInfoMap, process.width());
|
||||
|
||||
process.write(renderResult);
|
||||
process.appendResult(new LoggerModel(loggerInfoMap));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private String renderLoggerInfo(Map<String, Map<String, Object>> loggerInfos, int width) {
|
||||
StringBuilder sb = new StringBuilder(8192);
|
||||
|
||||
for (Entry<String, Map<String, Object>> entry : loggerInfos.entrySet()) {
|
||||
Map<String, Object> 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<Map<String, Object>> appenders = (List<Map<String, Object>>) info.get(LoggerHelper.appenders);
|
||||
if (appenders != null && !appenders.isEmpty()) {
|
||||
|
||||
for (Map<String, Object> 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<String, Map<String, Object>>) getLoggersMethod.invoke(null,
|
||||
new Object[] { name, includeNoAppender });
|
||||
new Object[]{name, includeNoAppender});
|
||||
} catch (Throwable e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
//expose attributes to json: classloader, classloaderHash
|
||||
for (Map<String, Object> 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<Map<String, Object>> appenders = (List<Map<String, Object>>) loggerInfo.get(LoggerHelper.appenders);
|
||||
for (Map<String, Object> 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) {
|
||||
|
@ -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<String, Map<String, Object>> loggerInfoMap;
|
||||
|
||||
public LoggerModel() {
|
||||
}
|
||||
|
||||
public LoggerModel(Map<String, Map<String, Object>> loggerInfoMap) {
|
||||
this.loggerInfoMap = loggerInfoMap;
|
||||
}
|
||||
|
||||
public Map<String, Map<String, Object>> getLoggerInfoMap() {
|
||||
return loggerInfoMap;
|
||||
}
|
||||
|
||||
public void setLoggerInfoMap(Map<String, Map<String, Object>> loggerInfoMap) {
|
||||
this.loggerInfoMap = loggerInfoMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return "logger";
|
||||
}
|
||||
|
||||
}
|
@ -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<LoggerModel> {
|
||||
|
||||
@Override
|
||||
public void draw(CommandProcess process, LoggerModel result) {
|
||||
process.write(renderLoggerInfo(result.getLoggerInfoMap(), process.width()));
|
||||
}
|
||||
|
||||
private String renderLoggerInfo(Map<String, Map<String, Object>> loggerInfos, int width) {
|
||||
StringBuilder sb = new StringBuilder(8192);
|
||||
|
||||
for (Map.Entry<String, Map<String, Object>> entry : loggerInfos.entrySet()) {
|
||||
Map<String, Object> 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<Map<String, Object>> appenders = (List<Map<String, Object>>) info.get(LoggerHelper.appenders);
|
||||
if (appenders != null && !appenders.isEmpty()) {
|
||||
|
||||
for (Map<String, Object> 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();
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user