From 58e77dc6f3c4391fede56a942b4d541352bf58dc Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Tue, 3 Sep 2019 16:32:08 +0800 Subject: [PATCH] add vmoption command. close #839 --- .../core/command/BuiltinCommandPack.java | 2 + .../command/basic1000/VMOptionCommand.java | 116 ++++++++++++++++++ site/src/site/sphinx/commands.md | 1 + site/src/site/sphinx/en/commands.md | 1 + site/src/site/sphinx/en/vmoption.md | 53 ++++++++ site/src/site/sphinx/vmoption.md | 53 ++++++++ 6 files changed, 226 insertions(+) create mode 100644 core/src/main/java/com/taobao/arthas/core/command/basic1000/VMOptionCommand.java create mode 100644 site/src/site/sphinx/en/vmoption.md create mode 100644 site/src/site/sphinx/vmoption.md diff --git a/core/src/main/java/com/taobao/arthas/core/command/BuiltinCommandPack.java b/core/src/main/java/com/taobao/arthas/core/command/BuiltinCommandPack.java index 072945068..2376a9704 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/BuiltinCommandPack.java +++ b/core/src/main/java/com/taobao/arthas/core/command/BuiltinCommandPack.java @@ -12,6 +12,7 @@ import com.taobao.arthas.core.command.basic1000.ShutdownCommand; import com.taobao.arthas.core.command.basic1000.StopCommand; import com.taobao.arthas.core.command.basic1000.SystemEnvCommand; import com.taobao.arthas.core.command.basic1000.SystemPropertyCommand; +import com.taobao.arthas.core.command.basic1000.VMOptionCommand; import com.taobao.arthas.core.command.basic1000.VersionCommand; import com.taobao.arthas.core.command.hidden.JulyCommand; import com.taobao.arthas.core.command.hidden.OptionsCommand; @@ -91,6 +92,7 @@ public class BuiltinCommandPack implements CommandResolver { commands.add(Command.create(SessionCommand.class)); commands.add(Command.create(SystemPropertyCommand.class)); commands.add(Command.create(SystemEnvCommand.class)); + commands.add(Command.create(VMOptionCommand.class)); commands.add(Command.create(HistoryCommand.class)); commands.add(Command.create(CatCommand.class)); commands.add(Command.create(PwdCommand.class)); diff --git a/core/src/main/java/com/taobao/arthas/core/command/basic1000/VMOptionCommand.java b/core/src/main/java/com/taobao/arthas/core/command/basic1000/VMOptionCommand.java new file mode 100644 index 000000000..cdbd6d6de --- /dev/null +++ b/core/src/main/java/com/taobao/arthas/core/command/basic1000/VMOptionCommand.java @@ -0,0 +1,116 @@ +package com.taobao.arthas.core.command.basic1000; + +import static com.taobao.text.ui.Element.label; + +import java.lang.management.ManagementFactory; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import com.sun.management.HotSpotDiagnosticMXBean; +import com.sun.management.VMOption; +import com.taobao.arthas.core.command.Constants; +import com.taobao.arthas.core.shell.cli.Completion; +import com.taobao.arthas.core.shell.cli.CompletionUtils; +import com.taobao.arthas.core.shell.command.AnnotatedCommand; +import com.taobao.arthas.core.shell.command.CommandProcess; +import com.taobao.arthas.core.util.LogUtil; +import com.taobao.arthas.core.util.StringUtils; +import com.taobao.middleware.cli.annotations.Argument; +import com.taobao.middleware.cli.annotations.Description; +import com.taobao.middleware.cli.annotations.Name; +import com.taobao.middleware.cli.annotations.Summary; +import com.taobao.middleware.logger.Logger; +import com.taobao.text.Decoration; +import com.taobao.text.ui.TableElement; +import com.taobao.text.util.RenderUtil; + +/** + * vmoption command + * + * @author hengyunabc 2019-09-02 + * + */ +@Name("vmoption") +@Summary("Display, and update the vm diagnostic options.") +@Description("\nExamples:\n" + " vmoption\n" + " vmoption PrintGCDetails\n" + " vmoption PrintGCDetails true\n" + + Constants.WIKI + Constants.WIKI_HOME + "vmoption") +public class VMOptionCommand extends AnnotatedCommand { + private static final Logger logger = LogUtil.getArthasLogger(); + + private String name; + private String value; + + @Argument(index = 0, argName = "name", required = false) + @Description("VMOption name") + public void setOptionName(String name) { + this.name = name; + } + + @Argument(index = 1, argName = "value", required = false) + @Description("VMOption value") + public void setOptionValue(String value) { + this.value = value; + } + + @Override + public void process(CommandProcess process) { + run(process, name, value); + } + + private static void run(CommandProcess process, String name, String value) { + try { + HotSpotDiagnosticMXBean hotSpotDiagnosticMXBean = ManagementFactory + .getPlatformMXBean(HotSpotDiagnosticMXBean.class); + + if (StringUtils.isBlank(name) && StringUtils.isBlank(value)) { + // show all options + process.write(renderVMOptions(hotSpotDiagnosticMXBean.getDiagnosticOptions(), process.width())); + } else if (StringUtils.isBlank(value)) { + // view the specified option + VMOption option = hotSpotDiagnosticMXBean.getVMOption(name); + if (option == null) { + process.write("In order to change the system properties, you must specify the property value.\n"); + } else { + process.write(renderVMOptions(Arrays.asList(option), process.width())); + } + } else { + // change vm option + hotSpotDiagnosticMXBean.setVMOption(name, value); + process.write("Successfully updated the vm option.\n"); + process.write(name + "=" + hotSpotDiagnosticMXBean.getVMOption(name).getValue() + "\n"); + } + } catch (Throwable t) { + process.write("Error during setting vm option: " + t.getMessage() + "\n"); + logger.error("arthas", "Error during setting vm option", t); + } finally { + process.end(); + } + + } + + private static String renderVMOptions(List diagnosticOptions, int width) { + TableElement table = new TableElement(1, 1, 1, 1).leftCellPadding(1).rightCellPadding(1); + table.row(true, label("KEY").style(Decoration.bold.bold()), label("VALUE").style(Decoration.bold.bold()), + label("ORIGIN").style(Decoration.bold.bold()), + label("WRITEABLE").style(Decoration.bold.bold())); + + for (VMOption option : diagnosticOptions) { + table.row(option.getName(), option.getValue(), "" + option.getOrigin(), "" + option.isWriteable()); + } + + return RenderUtil.render(table, width); + } + + @Override + public void complete(Completion completion) { + HotSpotDiagnosticMXBean hotSpotDiagnosticMXBean = ManagementFactory + .getPlatformMXBean(HotSpotDiagnosticMXBean.class); + List diagnosticOptions = hotSpotDiagnosticMXBean.getDiagnosticOptions(); + List names = new ArrayList(diagnosticOptions.size()); + for (VMOption option : diagnosticOptions) { + names.add(option.getName()); + } + CompletionUtils.complete(completion, names); + } +} diff --git a/site/src/site/sphinx/commands.md b/site/src/site/sphinx/commands.md index 0d0456de0..12c706ee3 100644 --- a/site/src/site/sphinx/commands.md +++ b/site/src/site/sphinx/commands.md @@ -6,6 +6,7 @@ * [jvm](jvm.md) * [sysprop](sysprop.md) * [sysenv](sysenv.md) +* [vmoption](vmoption.md) * [mbean](mbean.md) * [getstatic](getstatic.md) diff --git a/site/src/site/sphinx/en/commands.md b/site/src/site/sphinx/en/commands.md index e0079c529..fa2e5cdc2 100644 --- a/site/src/site/sphinx/en/commands.md +++ b/site/src/site/sphinx/en/commands.md @@ -6,6 +6,7 @@ All Commands * [jvm](jvm.md) * [sysprop](sysprop.md) * [sysenv](sysenv.md) +* [vmoption](vmoption.md) * [mbean](mbean.md) * [getstatic](getstatic.md) diff --git a/site/src/site/sphinx/en/vmoption.md b/site/src/site/sphinx/en/vmoption.md new file mode 100644 index 000000000..aef3f6ecf --- /dev/null +++ b/site/src/site/sphinx/en/vmoption.md @@ -0,0 +1,53 @@ +vmoption +=== + +> Display, and update the vm diagnostic options. + +### Usage + +#### View all options + +```bash +[arthas@56963]$ vmoption + KEY VALUE ORIGIN WRITEABLE +--------------------------------------------------------------------------------------------- + HeapDumpBeforeFullGC false DEFAULT true + HeapDumpAfterFullGC false DEFAULT true + HeapDumpOnOutOfMemory false DEFAULT true + Error + HeapDumpPath DEFAULT true + CMSAbortablePrecleanW 100 DEFAULT true + aitMillis + CMSWaitDuration 2000 DEFAULT true + CMSTriggerInterval -1 DEFAULT true + PrintGC false DEFAULT true + PrintGCDetails true MANAGEMENT true + PrintGCDateStamps false DEFAULT true + PrintGCTimeStamps false DEFAULT true + PrintGCID false DEFAULT true + PrintClassHistogramBe false DEFAULT true + foreFullGC + PrintClassHistogramAf false DEFAULT true + terFullGC + PrintClassHistogram false DEFAULT true + MinHeapFreeRatio 0 DEFAULT true + MaxHeapFreeRatio 100 DEFAULT true + PrintConcurrentLocks false DEFAULT true +``` + +#### View individual option + +```bash +[arthas@56963]$ vmoption PrintGCDetails + KEY VALUE ORIGIN WRITEABLE +--------------------------------------------------------------------------------------------- + PrintGCDetails false MANAGEMENT true +``` + +#### Update individual option + +```bash +[arthas@56963]$ vmoption PrintGCDetails true +Successfully updated the vm option. +PrintGCDetails=true +``` diff --git a/site/src/site/sphinx/vmoption.md b/site/src/site/sphinx/vmoption.md new file mode 100644 index 000000000..00886aa5a --- /dev/null +++ b/site/src/site/sphinx/vmoption.md @@ -0,0 +1,53 @@ +vmoption +=== + +> 查看,更新VM诊断相关的参数 + +### 使用参考 + +#### 查看所有的option + +```bash +[arthas@56963]$ vmoption + KEY VALUE ORIGIN WRITEABLE +--------------------------------------------------------------------------------------------- + HeapDumpBeforeFullGC false DEFAULT true + HeapDumpAfterFullGC false DEFAULT true + HeapDumpOnOutOfMemory false DEFAULT true + Error + HeapDumpPath DEFAULT true + CMSAbortablePrecleanW 100 DEFAULT true + aitMillis + CMSWaitDuration 2000 DEFAULT true + CMSTriggerInterval -1 DEFAULT true + PrintGC false DEFAULT true + PrintGCDetails true MANAGEMENT true + PrintGCDateStamps false DEFAULT true + PrintGCTimeStamps false DEFAULT true + PrintGCID false DEFAULT true + PrintClassHistogramBe false DEFAULT true + foreFullGC + PrintClassHistogramAf false DEFAULT true + terFullGC + PrintClassHistogram false DEFAULT true + MinHeapFreeRatio 0 DEFAULT true + MaxHeapFreeRatio 100 DEFAULT true + PrintConcurrentLocks false DEFAULT true +``` + +#### 查看指定的option + +```bash +[arthas@56963]$ vmoption PrintGCDetails + KEY VALUE ORIGIN WRITEABLE +--------------------------------------------------------------------------------------------- + PrintGCDetails false MANAGEMENT true +``` + +#### 更新指定的option + +```bash +[arthas@56963]$ vmoption PrintGCDetails true +Successfully updated the vm option. +PrintGCDetails=true +```