From 19895b43c13ca4f8c275efa0be1d93927daed60d Mon Sep 17 00:00:00 2001 From: qxo <49526356@qq.com> Date: Sat, 28 Oct 2023 03:50:22 +0000 Subject: [PATCH 1/2] =?UTF-8?q?feat:=20session=E5=91=BD=E4=BB=A4=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E6=98=BE=E7=A4=BA=E5=92=8C=E8=AE=BE=E7=BD=AEsession?= =?UTF-8?q?=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 以便可以设置上下文参供其他命令提供默认值 --- .../command/basic1000/SessionCommand.java | 88 ++++++++++++++++++- .../core/command/model/SessionModel.java | 12 +++ .../arthas/core/command/view/SessionView.java | 3 + .../arthas/core/shell/session/Session.java | 6 ++ .../core/shell/session/impl/SessionImpl.java | 5 ++ 5 files changed, 113 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java b/core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java index 44a773a8f6..cabe90d905 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java @@ -1,16 +1,28 @@ package com.taobao.arthas.core.command.basic1000; +import com.taobao.arthas.core.command.Constants; import com.taobao.arthas.core.command.model.SessionModel; import com.taobao.arthas.core.server.ArthasBootstrap; import com.taobao.arthas.core.shell.command.AnnotatedCommand; import com.taobao.arthas.core.shell.command.CommandProcess; import com.taobao.arthas.core.shell.session.Session; import com.taobao.arthas.core.util.UserStatUtil; +import com.taobao.middleware.cli.annotations.DefaultValue; +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.alibaba.arthas.tunnel.client.TunnelClient; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + /** * 查看会话状态命令 * @@ -18,15 +30,89 @@ */ @Name("session") @Summary("Display current session information") +@Description(value =Constants.EXAMPLE + + " session -s\n" + + " session -I *\n" + + " session -I '${arthas-cmd}-args=10'\n" + + " session -I 'history-args=10'\n" + + " session -I 'trace-args=-n 3 -v'\n" + + Constants.WIKI + Constants.WIKI_HOME + "session") public class SessionCommand extends AnnotatedCommand { + private static List RESERVED_WORDS = Arrays.asList( "id", "tty","pid","server","lastAccessedTime", + "createTime","subject", "instrumentation", "arthas-command-manager"); + + private boolean showSessionData = true; + + private boolean showReservedNames = false; + + private List customSesionData; + + @Option(shortName = "H", longName = "hiddenSessionData", flag = true) + @Description("Hidden artahs session data") + public void setHiddenSessionData(final boolean hiddenSessionData) { + this.showSessionData = !hiddenSessionData; + } + + @Option(shortName = "A", longName = "showAll", flag = true) + @Description("Show all session data") + public void setShowAll(final boolean showReservedNames) { + this.showReservedNames = showReservedNames; + } + + @Option(shortName = "I", longName = "input") + @Description("Input cutom session data, ie: 'trace-args=-n 3' or * for cleanup") + public void setCustomSessionData(final List customSesionData) { + this.customSesionData = customSesionData; + } + @Override public void process(CommandProcess process) { SessionModel result = new SessionModel(); Session session = process.session(); result.setJavaPid(session.getPid()); result.setSessionId(session.getSessionId()); - + if (customSesionData != null) { + process.echoTips("customSesionData: " + customSesionData + "\n"); + if (customSesionData.size() == 1 && "*".equals(customSesionData.get(0))) { + final Map sessionData = session.cloneSessionData(); + for (final Map.Entry entry : sessionData.entrySet()) { + if (!RESERVED_WORDS.contains(entry.getKey())) { + session.remove(entry.getKey()); + } + } + } else { + final Pattern pattern = Pattern.compile("\\s*([^:=]+)\\s*[:=]\\s*(.+)"); + for (final String pv : customSesionData) { + final Matcher matcher = pattern.matcher(pv); + if (matcher.find()) { + final int groupCount = matcher.groupCount(); + if (groupCount >= 2) { + final String name = matcher.group(1); + if (RESERVED_WORDS.contains(name)){ + process.echoTips("ignore: " + name); + return; + } + session.put(name, matcher.group(2)); + } + } + } + } + showSessionData = true; + } + if (showSessionData) { + final Map sessionData = session.cloneSessionData(); + if (!this.showReservedNames) { + final Iterator> iter = sessionData.entrySet().iterator(); + while(iter.hasNext()) { + if (RESERVED_WORDS.contains(iter.next().getKey())) { + iter.remove(); + continue; + } + } + } + result.setSessionData(sessionData); + } //tunnel TunnelClient tunnelClient = ArthasBootstrap.getInstance().getTunnelClient(); if (tunnelClient != null) { diff --git a/core/src/main/java/com/taobao/arthas/core/command/model/SessionModel.java b/core/src/main/java/com/taobao/arthas/core/command/model/SessionModel.java index aede0262ab..28cf1065d8 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/model/SessionModel.java +++ b/core/src/main/java/com/taobao/arthas/core/command/model/SessionModel.java @@ -1,5 +1,7 @@ package com.taobao.arthas.core.command.model; +import java.util.Map; + /** * Session command result model * @@ -15,6 +17,8 @@ public class SessionModel extends ResultModel { private boolean tunnelConnected; + private Map sessionData; + @Override public String getType() { return "session"; @@ -67,4 +71,12 @@ public boolean isTunnelConnected() { public void setTunnelConnected(boolean tunnelConnected) { this.tunnelConnected = tunnelConnected; } + + public Map getSessionData() { + return this.sessionData; + } + + public void setSessionData(Map env) { + this.sessionData = env; + } } diff --git a/core/src/main/java/com/taobao/arthas/core/command/view/SessionView.java b/core/src/main/java/com/taobao/arthas/core/command/view/SessionView.java index c496df9d72..95b83d156e 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/view/SessionView.java +++ b/core/src/main/java/com/taobao/arthas/core/command/view/SessionView.java @@ -31,6 +31,9 @@ public void draw(CommandProcess process, SessionModel result) { if (result.getStatUrl() != null) { table.row("STAT_URL", result.getStatUrl()); } + if (result.getSessionData() != null) { + table.row("SESION_ENV", result.getSessionData().toString()); + } process.write(RenderUtil.render(table, process.width())); } diff --git a/core/src/main/java/com/taobao/arthas/core/shell/session/Session.java b/core/src/main/java/com/taobao/arthas/core/shell/session/Session.java index 8ca1c902e2..3c58faa4d2 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/session/Session.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/session/Session.java @@ -6,6 +6,7 @@ import java.lang.instrument.Instrumentation; import java.util.List; +import java.util.Map; /** * A shell session. @@ -168,4 +169,9 @@ public interface Session { * Whether the session is tty term */ boolean isTty(); + + /** + * @return Clone the session data. + */ + Map cloneSessionData(); } diff --git a/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionImpl.java index 2bf8bca6fa..1b5e15ad87 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/session/impl/SessionImpl.java @@ -28,6 +28,11 @@ public SessionImpl() { this.setLastAccessTime(now); } + @Override + public Map cloneSessionData() { + return new HashMap(data); + } + @Override public Session put(String key, Object obj) { if (obj == null) { From 2883c4aac497359af3ed54a6e16dba479430debf Mon Sep 17 00:00:00 2001 From: qxo <49526356@qq.com> Date: Sat, 28 Oct 2023 08:04:29 +0000 Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E9=80=9A?= =?UTF-8?q?=E8=BF=87arthas=20session=20data=E6=9D=A5=E6=B7=BB=E5=91=BD?= =?UTF-8?q?=E4=BB=A4=E7=9A=84=E9=99=84=E5=8A=A0=E5=8F=82=E6=95=B0=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E5=87=8F=E5=B0=91=E4=B8=8D=E5=BF=85=E8=A6=81=E9=87=8D?= =?UTF-8?q?=E5=A4=8D=E8=BE=93=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 附加参数名称的格式为${arthas-cmd}-args trace对应的是trace-args watch对应的watch-args ie: ``` session -I 'trace-args=-n 3 -v' ``` 这样以后的trace命令就不自动附加上述参数了 要清除可用:`session -I *`(清除所有) 或 `session -I 'trace-args= ``(清除指定的) --- .../core/command/basic1000/SessionCommand.java | 6 +++--- .../arthas/core/command/view/SessionView.java | 2 +- .../core/shell/system/impl/ProcessImpl.java | 18 +++++++++++++++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java b/core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java index cabe90d905..355a673837 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/basic1000/SessionCommand.java @@ -44,7 +44,7 @@ public class SessionCommand extends AnnotatedCommand { private boolean showSessionData = true; - private boolean showReservedNames = false; + private boolean showAll = false; private List customSesionData; @@ -57,7 +57,7 @@ public void setHiddenSessionData(final boolean hiddenSessionData) { @Option(shortName = "A", longName = "showAll", flag = true) @Description("Show all session data") public void setShowAll(final boolean showReservedNames) { - this.showReservedNames = showReservedNames; + this.showAll = showReservedNames; } @Option(shortName = "I", longName = "input") @@ -102,7 +102,7 @@ public void process(CommandProcess process) { } if (showSessionData) { final Map sessionData = session.cloneSessionData(); - if (!this.showReservedNames) { + if (!this.showAll) { final Iterator> iter = sessionData.entrySet().iterator(); while(iter.hasNext()) { if (RESERVED_WORDS.contains(iter.next().getKey())) { diff --git a/core/src/main/java/com/taobao/arthas/core/command/view/SessionView.java b/core/src/main/java/com/taobao/arthas/core/command/view/SessionView.java index 95b83d156e..1a7a22bd7e 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/view/SessionView.java +++ b/core/src/main/java/com/taobao/arthas/core/command/view/SessionView.java @@ -32,7 +32,7 @@ public void draw(CommandProcess process, SessionModel result) { table.row("STAT_URL", result.getStatUrl()); } if (result.getSessionData() != null) { - table.row("SESION_ENV", result.getSessionData().toString()); + table.row("SESION_DATA", result.getSessionData().toString()); } process.write(RenderUtil.render(table, process.width())); } diff --git a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/ProcessImpl.java b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/ProcessImpl.java index 74adfd1bdb..137bf0d04b 100644 --- a/core/src/main/java/com/taobao/arthas/core/shell/system/impl/ProcessImpl.java +++ b/core/src/main/java/com/taobao/arthas/core/shell/system/impl/ProcessImpl.java @@ -23,6 +23,7 @@ import com.taobao.arthas.core.shell.term.Tty; import com.taobao.middleware.cli.CLIException; import com.taobao.middleware.cli.CommandLine; + import io.termd.core.function.Function; import java.lang.instrument.ClassFileTransformer; @@ -344,10 +345,25 @@ public synchronized void run(boolean fg) { args2.add(arg.value()); } } - CommandLine cl = null; try { if (commandContext.cli() != null) { + final String appCmdArgs = commandContext.name() +"-args"; + final Object cmdArgs = process.session().get(appCmdArgs); + if (cmdArgs != null) { + process.echoTips("appendCmdArgs: " + cmdArgs + "\n"); + final String cmdArgs1 = cmdArgs.toString(); + final String[] arr = cmdArgs1.contains("##") ? cmdArgs1.split("##") + : cmdArgs1.split("[; ,:#]+"); + for (final String arg : arr) { + if (arg.isEmpty()) { + break; + } + args2.add(arg); + } + process.echoTips("appendCmdArgs done: " + args2 + "\n"); + } + if (commandContext.cli().parse(args2, false).isAskingForHelp()) { appendResult(new HelpCommand().createHelpDetailModel(commandContext)); terminate();