mirror of
https://gitee.com/arthas/arthas.git
synced 2024-12-01 19:58:30 +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.MBeanCommand;
|
||||
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.StackCommand;
|
||||
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(TimeTunnelCommand.class));
|
||||
commands.add(Command.create(JvmCommand.class));
|
||||
commands.add(Command.create(PerfCounterCommand.class));
|
||||
// commands.add(Command.create(GroovyScriptCommand.class));
|
||||
commands.add(Command.create(OgnlCommand.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的系统属性
|
||||
* [sysenv](sysenv.md)——查看JVM的环境变量
|
||||
* [vmoption](vmoption.md)——查看和修改JVM里诊断相关的option
|
||||
* [perfcounter](perfcounter.md)——查看当前 JVM 的Perf Counter信息
|
||||
* [logger](logger.md)——查看和修改logger
|
||||
* [getstatic](getstatic.md)——查看类的静态属性
|
||||
* [ognl](ognl.md)——执行ognl表达式
|
||||
|
@ -7,6 +7,7 @@
|
||||
* [sysprop](sysprop.md)
|
||||
* [sysenv](sysenv.md)
|
||||
* [vmoption](vmoption.md)
|
||||
* [perfcounter](perfcounter.md)
|
||||
* [logger](logger.md)
|
||||
* [mbean](mbean.md)
|
||||
* [getstatic](getstatic.md)
|
||||
|
@ -25,6 +25,7 @@ Advanced Usage
|
||||
* [sysprop](sysprop.md) - view/modify system properties
|
||||
* [sysenv](sysenv.md) — view system environment variables
|
||||
* [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
|
||||
* [getstatic](getstatic.md) - examine class's static properties
|
||||
* [ognl](ognl.md) - execute ongl expression
|
||||
|
@ -7,6 +7,7 @@ All Commands
|
||||
* [sysprop](sysprop.md)
|
||||
* [sysenv](sysenv.md)
|
||||
* [vmoption](vmoption.md)
|
||||
* [perfcounter](perfcounter.md)
|
||||
* [logger](logger.md)
|
||||
* [mbean](mbean.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