From 74c313ecaa425595fd5aab46d3e933b55a43522b Mon Sep 17 00:00:00 2001 From: Hollow Man Date: Wed, 26 Aug 2020 11:24:44 +0800 Subject: [PATCH] Add --classLoaderClass for logger (#1445) --- .../core/command/logger/LoggerCommand.java | 28 +++++++++++++++++++ .../core/command/model/LoggerModel.java | 22 +++++++++++++++ .../arthas/core/command/view/LoggerView.java | 6 ++++ site/src/site/sphinx/en/logger.md | 12 ++++++++ site/src/site/sphinx/logger.md | 12 ++++++++ .../katacoda/command-logger-cn/logger.md | 18 ++++++++++-- .../katacoda/command-logger-en/logger.md | 22 ++++++++++++--- 7 files changed, 114 insertions(+), 6 deletions(-) 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 d05b56964..b599a563b 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 @@ -20,8 +20,10 @@ 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.command.model.ClassLoaderVO; import com.taobao.arthas.core.shell.command.AnnotatedCommand; import com.taobao.arthas.core.shell.command.CommandProcess; +import com.taobao.arthas.core.util.ClassUtils; import com.taobao.arthas.core.util.ClassLoaderUtils; import com.taobao.arthas.core.util.StringUtils; import com.taobao.middleware.cli.annotations.Description; @@ -72,6 +74,7 @@ public class LoggerCommand extends AnnotatedCommand { private String name; private String hashCode; + private String classLoaderClass; private String level; @@ -92,6 +95,12 @@ public class LoggerCommand extends AnnotatedCommand { this.hashCode = hashCode; } + @Option(longName = "classLoaderClass") + @Description("The class name of the special class's classLoader.") + public void setClassLoaderClass(String classLoaderClass) { + this.classLoaderClass = classLoaderClass; + } + @Option(shortName = "l", longName = "level") @Description("set logger level") public void setLevel(String level) { @@ -158,6 +167,25 @@ public class LoggerCommand extends AnnotatedCommand { String className = clazz.getName(); ClassLoader classLoader = clazz.getClassLoader(); + if (hashCode == null && classLoaderClass != null) { + Instrumentation inst = process.session().getInstrumentation(); + List matchedClassLoaders = ClassLoaderUtils.getClassLoaderByClassName(inst, classLoaderClass); + if (matchedClassLoaders.size() == 1) { + hashCode = Integer.toHexString(matchedClassLoaders.get(0).hashCode()); + } else if (matchedClassLoaders.size() > 1) { + Collection classLoaderVOList = ClassUtils.createClassLoaderVOList(matchedClassLoaders); + LoggerModel loggerModel = new LoggerModel() + .setClassLoaderClass(classLoaderClass) + .setMatchedClassLoaders(classLoaderVOList); + process.appendResult(loggerModel); + process.end(-1, "Found more than one classloader by class name, please specify classloader with '-c '"); + return; + } else { + process.end(-1, "Can not find classloader by class name: " + classLoaderClass + "."); + return; + } + } + // if special classloader if (this.hashCode != null && !this.hashCode.equals(StringUtils.classLoaderHash(clazz))) { continue; 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 index 05ee2e0ac..8c09bc942 100644 --- 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 @@ -1,5 +1,7 @@ package com.taobao.arthas.core.command.model; +import java.util.Collection; +import java.util.List; import java.util.Map; /** @@ -10,6 +12,8 @@ import java.util.Map; public class LoggerModel extends ResultModel { private Map> loggerInfoMap; + private Collection matchedClassLoaders; + private String classLoaderClass; public LoggerModel() { } @@ -26,6 +30,24 @@ public class LoggerModel extends ResultModel { this.loggerInfoMap = loggerInfoMap; } + public String getClassLoaderClass() { + return classLoaderClass; + } + + public LoggerModel setClassLoaderClass(String classLoaderClass) { + this.classLoaderClass = classLoaderClass; + return this; + } + + public Collection getMatchedClassLoaders() { + return matchedClassLoaders; + } + + public LoggerModel setMatchedClassLoaders(Collection matchedClassLoaders) { + this.matchedClassLoaders = matchedClassLoaders; + return this; + } + @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 index b6d925aa4..40c29b09e 100644 --- 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 @@ -22,6 +22,12 @@ public class LoggerView extends ResultView { @Override public void draw(CommandProcess process, LoggerModel result) { + if (result.getMatchedClassLoaders() != null) { + process.write("Matched classloaders: \n"); + ClassLoaderView.drawClassLoaders(process, result.getMatchedClassLoaders(), false); + process.write("\n"); + return; + } process.write(renderLoggerInfo(result.getLoggerInfoMap(), process.width())); } diff --git a/site/src/site/sphinx/en/logger.md b/site/src/site/sphinx/en/logger.md index bedc9320c..0432fef9c 100644 --- a/site/src/site/sphinx/en/logger.md +++ b/site/src/site/sphinx/en/logger.md @@ -98,6 +98,10 @@ In the `appenders` section: #### View logger information for the special classloader +Note that the hashcode changes, you need to check the current ClassLoader information first, and extract the hashcode corresponding to the ClassLoader. + +if you use`-c`, you have to manually type hashcode by `-c `. + ```bash [arthas@2062]$ logger -c 2a139a55 name ROOT @@ -125,6 +129,14 @@ In the `appenders` section: appenderRef [APPLICATION] ``` +For classloader with only one instance, it can be specified by `--classLoaderClass` using class name, which is more convenient to use. + +`logger --classLoaderClass sun.misc.Launcher$AppClassLoader` + + * PS: Here the classLoaderClass in java 8 is sun.misc.Launcher$AppClassLoader, while in java 11 it's jdk.internal.loader.ClassLoaders$AppClassLoader. + +The value of `--classloaderclass` is the class name of classloader. It can only work when it matches a unique classloader instance. The purpose is to facilitate the input of general commands. However, `-c ` is dynamic. + #### Update logger level ```bash diff --git a/site/src/site/sphinx/logger.md b/site/src/site/sphinx/logger.md index 38337a46c..57b53fb42 100644 --- a/site/src/site/sphinx/logger.md +++ b/site/src/site/sphinx/logger.md @@ -99,6 +99,10 @@ logger #### 查看指定classloader的logger信息 +注意hashcode是变化的,需要先查看当前的ClassLoader信息,提取对应ClassLoader的hashcode。 + +如果你使用`-c`,你需要手动输入hashcode:`-c ` + ```bash [arthas@2062]$ logger -c 2a139a55 name ROOT @@ -126,6 +130,14 @@ logger appenderRef [APPLICATION] ``` +对于只有唯一实例的ClassLoader可以通过`--classLoaderClass`指定class name,使用起来更加方便: + +`logger --classLoaderClass sun.misc.Launcher$AppClassLoader` + + * 注: 这里classLoaderClass 在 java 8 是 sun.misc.Launcher$AppClassLoader,而java 11的classloader是jdk.internal.loader.ClassLoaders$AppClassLoader。 + +`--classLoaderClass` 的值是ClassLoader的类名,只有匹配到唯一的ClassLoader实例时才能工作,目的是方便输入通用命令,而`-c `是动态变化的。 + #### 更新logger level ```bash diff --git a/tutorials/katacoda/command-logger-cn/logger.md b/tutorials/katacoda/command-logger-cn/logger.md index 894d4f8ae..2ea5eb040 100644 --- a/tutorials/katacoda/command-logger-cn/logger.md +++ b/tutorials/katacoda/command-logger-cn/logger.md @@ -57,10 +57,20 @@ #### 查看指定classloader的logger信息 -`logger -c ` +注意hashcode是变化的,需要先查看当前的ClassLoader信息,提取对应ClassLoader的hashcode。 + +如果你使用`-c`,你需要手动输入hashcode:`-c ` ```bash -[arthas@2062]$ logger -c 2a139a55 +$ logger -c 2a139a55 +``` + +对于只有唯一实例的ClassLoader可以通过`--classLoaderClass`指定class name,使用起来更加方便: + +`logger --classLoaderClass sun.misc.Launcher$AppClassLoader`{{execute T2}} + +```bash +[arthas@2062]$ logger --classLoaderClass sun.misc.Launcher$AppClassLoader name ROOT class ch.qos.logback.classic.Logger classLoader sun.misc.Launcher$AppClassLoader@2a139a55 @@ -86,6 +96,10 @@ appenderRef [APPLICATION] ``` + * 注: 这里classLoaderClass 在 java 8 是 sun.misc.Launcher$AppClassLoader,而java 11的classloader是jdk.internal.loader.ClassLoaders$AppClassLoader,katacoda目前环境是java8。 + +`--classLoaderClass` 的值是ClassLoader的类名,只有匹配到唯一的ClassLoader实例时才能工作,目的是方便输入通用命令,而`-c `是动态变化的。 + #### 更新logger level `logger --name ROOT --level debug`{{execute T2}} diff --git a/tutorials/katacoda/command-logger-en/logger.md b/tutorials/katacoda/command-logger-en/logger.md index 1f085c359..c217b5f93 100644 --- a/tutorials/katacoda/command-logger-en/logger.md +++ b/tutorials/katacoda/command-logger-en/logger.md @@ -57,10 +57,20 @@ Note: Please replace `` with your classLoaderHash above, then e #### View logger information for the special classloader -`logger -c ` +Note that the hashcode changes, you need to check the current ClassLoader information first, and extract the hashcode corresponding to the ClassLoader. + +if you use`-c`, you have to manually type hashcode by `-c `. ```bash -[arthas@2062]$ logger -c 2a139a55 +$ logger -c 2a139a55 +``` + +For classloader with only one instance, it can be specified by `--classLoaderClass` using class name, which is more convenient to use. + +`logger --classLoaderClass sun.misc.Launcher$AppClassLoader`{{execute T2}} + +```bash +[arthas@2062]$ logger --classLoaderClass sun.misc.Launcher$AppClassLoader name ROOT class ch.qos.logback.classic.Logger classLoader sun.misc.Launcher$AppClassLoader@2a139a55 @@ -86,6 +96,10 @@ Note: Please replace `` with your classLoaderHash above, then e appenderRef [APPLICATION] ``` + * PS: Here the classLoaderClass in java 8 is sun.misc.Launcher$AppClassLoader, while in java 11 it's jdk.internal.loader.ClassLoaders$AppClassLoader. Currently katacoda using java 8. + +The value of `--classloaderclass` is the class name of classloader. It can only work when it matches a unique classloader instance. The purpose is to facilitate the input of general commands. However, `-c ` is dynamic. + #### Update logger level `logger --name ROOT --level debug`{{execute T2}} @@ -101,10 +115,10 @@ update logger level success. 可以先用 `sc -d yourClassName` 来查看具体的 classloader hashcode,然后在更新level时指定classloader: -`logger -c --name ROOT --level debug` +`logger --classLoaderClass sun.misc.Launcher$AppClassLoader --name ROOT --level debug`{{execute T2}} ```bash -[arthas@2062]$ logger -c 2a139a55 --name ROOT --level debug +[arthas@2062]$ logger --classLoaderClass sun.misc.Launcher$AppClassLoader --name ROOT --level debug ``` #### View the logger information without appenders