mirror of
https://gitee.com/arthas/arthas.git
synced 2024-12-02 04:08:34 +08:00
add perfcounter command. #1029
This commit is contained in:
parent
4e771e2a7d
commit
f5f7583c98
@ -34,6 +34,7 @@ import com.taobao.arthas.core.command.monitor200.HeapDumpCommand;
|
|||||||
import com.taobao.arthas.core.command.monitor200.JvmCommand;
|
import com.taobao.arthas.core.command.monitor200.JvmCommand;
|
||||||
import com.taobao.arthas.core.command.monitor200.MBeanCommand;
|
import com.taobao.arthas.core.command.monitor200.MBeanCommand;
|
||||||
import com.taobao.arthas.core.command.monitor200.MonitorCommand;
|
import com.taobao.arthas.core.command.monitor200.MonitorCommand;
|
||||||
|
import com.taobao.arthas.core.command.monitor200.PerfCounterCommand;
|
||||||
import com.taobao.arthas.core.command.monitor200.ProfilerCommand;
|
import com.taobao.arthas.core.command.monitor200.ProfilerCommand;
|
||||||
import com.taobao.arthas.core.command.monitor200.StackCommand;
|
import com.taobao.arthas.core.command.monitor200.StackCommand;
|
||||||
import com.taobao.arthas.core.command.monitor200.ThreadCommand;
|
import com.taobao.arthas.core.command.monitor200.ThreadCommand;
|
||||||
@ -78,6 +79,7 @@ public class BuiltinCommandPack implements CommandResolver {
|
|||||||
commands.add(Command.create(WatchCommand.class));
|
commands.add(Command.create(WatchCommand.class));
|
||||||
commands.add(Command.create(TimeTunnelCommand.class));
|
commands.add(Command.create(TimeTunnelCommand.class));
|
||||||
commands.add(Command.create(JvmCommand.class));
|
commands.add(Command.create(JvmCommand.class));
|
||||||
|
commands.add(Command.create(PerfCounterCommand.class));
|
||||||
// commands.add(Command.create(GroovyScriptCommand.class));
|
// commands.add(Command.create(GroovyScriptCommand.class));
|
||||||
commands.add(Command.create(OgnlCommand.class));
|
commands.add(Command.create(OgnlCommand.class));
|
||||||
commands.add(Command.create(MemoryCompilerCommand.class));
|
commands.add(Command.create(MemoryCompilerCommand.class));
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
package com.taobao.arthas.core.command.monitor200;
|
||||||
|
|
||||||
|
import static com.taobao.text.ui.Element.label;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.taobao.arthas.common.JavaVersionUtils;
|
||||||
|
import com.taobao.arthas.common.PidUtils;
|
||||||
|
import com.taobao.arthas.core.command.Constants;
|
||||||
|
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.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.middleware.logger.Logger;
|
||||||
|
import com.taobao.text.Decoration;
|
||||||
|
import com.taobao.text.ui.TableElement;
|
||||||
|
import com.taobao.text.util.RenderUtil;
|
||||||
|
|
||||||
|
import sun.management.counter.Counter;
|
||||||
|
import sun.management.counter.perf.PerfInstrumentation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see sun.misc.Perf
|
||||||
|
* @see sun.management.counter.perf.PerfInstrumentation
|
||||||
|
* @author hengyunabc 2020-02-16
|
||||||
|
*/
|
||||||
|
@Name("perfcounter")
|
||||||
|
@Summary("Display the perf counter infornation.")
|
||||||
|
@Description(Constants.WIKI + Constants.WIKI_HOME + "perf")
|
||||||
|
public class PerfCounterCommand extends AnnotatedCommand {
|
||||||
|
private static final Logger logger = LogUtil.getArthasLogger();
|
||||||
|
private static Object perfObject;
|
||||||
|
private static Method attachMethod;
|
||||||
|
|
||||||
|
private boolean details;
|
||||||
|
|
||||||
|
@Option(shortName = "d", longName = "details", flag = true)
|
||||||
|
@Description("print all perf counter details")
|
||||||
|
public void setDetails(boolean details) {
|
||||||
|
this.details = details;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void process(CommandProcess process) {
|
||||||
|
try {
|
||||||
|
TableElement table = new TableElement().leftCellPadding(1).rightCellPadding(1);
|
||||||
|
if (this.details) {
|
||||||
|
table = new TableElement(3, 1, 1, 10).leftCellPadding(1).rightCellPadding(1);
|
||||||
|
table.row(true, label("Name").style(Decoration.bold.bold()),
|
||||||
|
label("Variability").style(Decoration.bold.bold()),
|
||||||
|
label("Units").style(Decoration.bold.bold()), label("Value").style(Decoration.bold.bold()));
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Counter> perfCounters = getPerfCounters();
|
||||||
|
if (perfCounters.isEmpty()) {
|
||||||
|
process.write(
|
||||||
|
"please check arthas log. if java version >=9 , try to add jvm options when start your process: "
|
||||||
|
+ "--add-opens java.base/jdk.internal.perf=ALL-UNNAMED "
|
||||||
|
+ "--add-exports java.base/jdk.internal.perf=ALL-UNNAMED\n");
|
||||||
|
} else {
|
||||||
|
for (Counter counter : perfCounters) {
|
||||||
|
if (details) {
|
||||||
|
table.row(counter.getName(), String.valueOf(counter.getVariability()),
|
||||||
|
String.valueOf(counter.getUnits()), String.valueOf(counter.getValue()));
|
||||||
|
} else {
|
||||||
|
table.row(counter.getName(), String.valueOf(counter.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
process.write(RenderUtil.render(table, process.width()));
|
||||||
|
} finally {
|
||||||
|
process.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<Counter> getPerfCounters() {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* Perf p = Perf.getPerf();
|
||||||
|
* ByteBuffer buffer = p.attach(pid, "r");
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
try {
|
||||||
|
if (perfObject == null) {
|
||||||
|
// jdk8
|
||||||
|
String perfClassName = "sun.misc.Perf";
|
||||||
|
// jdk 11
|
||||||
|
if (!JavaVersionUtils.isLessThanJava9()) {
|
||||||
|
perfClassName = "jdk.internal.perf.Perf";
|
||||||
|
}
|
||||||
|
|
||||||
|
Class<?> perfClass = ClassLoader.getSystemClassLoader().loadClass(perfClassName);
|
||||||
|
Method getPerfMethod = perfClass.getDeclaredMethod("getPerf");
|
||||||
|
perfObject = getPerfMethod.invoke(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (attachMethod == null) {
|
||||||
|
attachMethod = perfObject.getClass().getDeclaredMethod("attach",
|
||||||
|
new Class<?>[] { int.class, String.class });
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuffer buffer = (ByteBuffer) attachMethod.invoke(perfObject,
|
||||||
|
new Object[] { (int) PidUtils.currentLongPid(), "r" });
|
||||||
|
|
||||||
|
PerfInstrumentation perfInstrumentation = new PerfInstrumentation(buffer);
|
||||||
|
return perfInstrumentation.getAllCounters();
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logger.error("arthas", "get perf counter error", e);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
}
|
@ -27,6 +27,7 @@
|
|||||||
* [sysprop](sysprop.md)——查看和修改JVM的系统属性
|
* [sysprop](sysprop.md)——查看和修改JVM的系统属性
|
||||||
* [sysenv](sysenv.md)——查看JVM的环境变量
|
* [sysenv](sysenv.md)——查看JVM的环境变量
|
||||||
* [vmoption](vmoption.md)——查看和修改JVM里诊断相关的option
|
* [vmoption](vmoption.md)——查看和修改JVM里诊断相关的option
|
||||||
|
* [perfcounter](perfcounter.md)——查看当前 JVM 的Perf Counter信息
|
||||||
* [logger](logger.md)——查看和修改logger
|
* [logger](logger.md)——查看和修改logger
|
||||||
* [getstatic](getstatic.md)——查看类的静态属性
|
* [getstatic](getstatic.md)——查看类的静态属性
|
||||||
* [ognl](ognl.md)——执行ognl表达式
|
* [ognl](ognl.md)——执行ognl表达式
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
* [sysprop](sysprop.md)
|
* [sysprop](sysprop.md)
|
||||||
* [sysenv](sysenv.md)
|
* [sysenv](sysenv.md)
|
||||||
* [vmoption](vmoption.md)
|
* [vmoption](vmoption.md)
|
||||||
|
* [perfcounter](perfcounter.md)
|
||||||
* [logger](logger.md)
|
* [logger](logger.md)
|
||||||
* [mbean](mbean.md)
|
* [mbean](mbean.md)
|
||||||
* [getstatic](getstatic.md)
|
* [getstatic](getstatic.md)
|
||||||
|
@ -25,6 +25,7 @@ Advanced Usage
|
|||||||
* [sysprop](sysprop.md) - view/modify system properties
|
* [sysprop](sysprop.md) - view/modify system properties
|
||||||
* [sysenv](sysenv.md) — view system environment variables
|
* [sysenv](sysenv.md) — view system environment variables
|
||||||
* [vmoption](vmoption.md) - view/modify the vm diagnostic options.
|
* [vmoption](vmoption.md) - view/modify the vm diagnostic options.
|
||||||
|
* [perfcounter](perfcounter.md) - show JVM Perf Counter information
|
||||||
* [logger](logger.md) - print the logger information, update the logger level
|
* [logger](logger.md) - print the logger information, update the logger level
|
||||||
* [getstatic](getstatic.md) - examine class's static properties
|
* [getstatic](getstatic.md) - examine class's static properties
|
||||||
* [ognl](ognl.md) - execute ongl expression
|
* [ognl](ognl.md) - execute ongl expression
|
||||||
|
@ -7,6 +7,7 @@ All Commands
|
|||||||
* [sysprop](sysprop.md)
|
* [sysprop](sysprop.md)
|
||||||
* [sysenv](sysenv.md)
|
* [sysenv](sysenv.md)
|
||||||
* [vmoption](vmoption.md)
|
* [vmoption](vmoption.md)
|
||||||
|
* [perfcounter](perfcounter.md)
|
||||||
* [logger](logger.md)
|
* [logger](logger.md)
|
||||||
* [mbean](mbean.md)
|
* [mbean](mbean.md)
|
||||||
* [getstatic](getstatic.md)
|
* [getstatic](getstatic.md)
|
||||||
|
40
site/src/site/sphinx/en/perfcounter.md
Normal file
40
site/src/site/sphinx/en/perfcounter.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
perfcounter
|
||||||
|
===
|
||||||
|
|
||||||
|
> Check the current JVM Perf Counter information.
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
|
||||||
|
```
|
||||||
|
$ perfcounter
|
||||||
|
java.ci.totalTime 2325637411
|
||||||
|
java.cls.loadedClasses 3403
|
||||||
|
java.cls.sharedLoadedClasses 0
|
||||||
|
java.cls.sharedUnloadedClasses 0
|
||||||
|
java.cls.unloadedClasses 0
|
||||||
|
java.property.java.version 11.0.4
|
||||||
|
java.property.java.vm.info mixed mode
|
||||||
|
java.property.java.vm.name OpenJDK 64-Bit Server VM
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
Print more information with the `-d` option:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ perfcounter -d
|
||||||
|
Name Variability Units Value
|
||||||
|
---------------------------------------------------------------------------------
|
||||||
|
java.ci.totalTime Monotonic Ticks 3242526906
|
||||||
|
java.cls.loadedClasses Monotonic Events 3404
|
||||||
|
java.cls.sharedLoadedClasses Monotonic Events 0
|
||||||
|
java.cls.sharedUnloadedClasses Monotonic Events 0
|
||||||
|
java.cls.unloadedClasses Monotonic Events 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### JVM above JDK9
|
||||||
|
|
||||||
|
If the information is not printed, when the application starts, add the following parameters:
|
||||||
|
|
||||||
|
```
|
||||||
|
--add-opens java.base/jdk.internal.perf=ALL-UNNAMED --add-exports java.base/jdk.internal.perf=ALL-UNNAMED
|
||||||
|
```
|
40
site/src/site/sphinx/perfcounter.md
Normal file
40
site/src/site/sphinx/perfcounter.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
perfcounter
|
||||||
|
===
|
||||||
|
|
||||||
|
> 查看当前JVM的 Perf Counter信息
|
||||||
|
|
||||||
|
### 使用参考
|
||||||
|
|
||||||
|
```
|
||||||
|
$ perfcounter
|
||||||
|
java.ci.totalTime 2325637411
|
||||||
|
java.cls.loadedClasses 3403
|
||||||
|
java.cls.sharedLoadedClasses 0
|
||||||
|
java.cls.sharedUnloadedClasses 0
|
||||||
|
java.cls.unloadedClasses 0
|
||||||
|
java.property.java.version 11.0.4
|
||||||
|
java.property.java.vm.info mixed mode
|
||||||
|
java.property.java.vm.name OpenJDK 64-Bit Server VM
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
可以用`-d`参数打印更多信息:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ perfcounter -d
|
||||||
|
Name Variability Units Value
|
||||||
|
---------------------------------------------------------------------------------
|
||||||
|
java.ci.totalTime Monotonic Ticks 3242526906
|
||||||
|
java.cls.loadedClasses Monotonic Events 3404
|
||||||
|
java.cls.sharedLoadedClasses Monotonic Events 0
|
||||||
|
java.cls.sharedUnloadedClasses Monotonic Events 0
|
||||||
|
java.cls.unloadedClasses Monotonic Events 0
|
||||||
|
```
|
||||||
|
|
||||||
|
### jdk9以上的应用
|
||||||
|
|
||||||
|
如果没有打印出信息,应用在启动时,加下面的参数:
|
||||||
|
|
||||||
|
```
|
||||||
|
--add-opens java.base/jdk.internal.perf=ALL-UNNAMED --add-exports java.base/jdk.internal.perf=ALL-UNNAMED
|
||||||
|
```
|
Loading…
Reference in New Issue
Block a user