mirror of
https://github.com/alibaba/arthas.git
synced 2026-10-21 03:45:01 +00:00
improve profiler command output, doc, timeout. #2961
This commit is contained in:
@@ -51,6 +51,9 @@ import one.profiler.Counter;
|
||||
+ " profiler list # list all supported events\n"
|
||||
+ " profiler actions # list all supported actions\n"
|
||||
+ " profiler start --event alloc\n"
|
||||
+ " profiler start --timeout 300s"
|
||||
+ " profiler start --loop 300s -f /tmp/result-%t.html"
|
||||
+ " profiler start --duration 300"
|
||||
+ " profiler stop --format html # output file format, support flat[=N]|traces[=N]|collapsed|flamegraph|tree|jfr\n"
|
||||
+ " profiler stop --file /tmp/result.html\n"
|
||||
+ " profiler stop --threads \n"
|
||||
@@ -66,7 +69,10 @@ import one.profiler.Counter;
|
||||
//@formatter:on
|
||||
public class ProfilerCommand extends AnnotatedCommand {
|
||||
private static final Logger logger = LoggerFactory.getLogger(ProfilerCommand.class);
|
||||
// Track if a file was specified during profiler start
|
||||
private static String fileSpecifiedAtStart = null;
|
||||
|
||||
// TODO start 时,没指定 file, 是否在 stop 时,能生成 html 或者 jfr 不?
|
||||
private String action;
|
||||
private String actionArg;
|
||||
|
||||
@@ -743,10 +749,36 @@ public class ProfilerCommand extends AnnotatedCommand {
|
||||
String result = execute(asyncProfiler, this.actionArg);
|
||||
appendExecuteResult(process, result);
|
||||
} else if (ProfilerAction.start.equals(profilerAction)) {
|
||||
// Track if file parameter was specified during start
|
||||
boolean autoGeneratedFile = false;
|
||||
if (this.file != null) {
|
||||
fileSpecifiedAtStart = this.file;
|
||||
logger.debug("File specified during profiler start: {}", fileSpecifiedAtStart);
|
||||
} else if (this.timeout != null) {
|
||||
// Auto-generate file if timeout is specified but file is not
|
||||
try {
|
||||
this.file = outputFile();
|
||||
logger.debug("Auto-generated file for timeout: {}", this.file);
|
||||
fileSpecifiedAtStart = this.file;
|
||||
autoGeneratedFile = true;
|
||||
} catch (IOException e) {
|
||||
logger.warn("Failed to auto-generate file for timeout", e);
|
||||
}
|
||||
}
|
||||
|
||||
if (this.duration == null) {
|
||||
String executeArgs = executeArgs(ProfilerAction.start);
|
||||
String result = execute(asyncProfiler, executeArgs);
|
||||
appendExecuteResult(process, result);
|
||||
ProfilerModel profilerModel = createProfilerModel(result);
|
||||
|
||||
// Add information about auto-generated file for timeout
|
||||
if (autoGeneratedFile && this.file != null) {
|
||||
profilerModel.setOutputFile(this.file);
|
||||
profilerModel.setExecuteResult(profilerModel.getExecuteResult()
|
||||
+ "\nAuto-generated output file will be: " + this.file + "\n");
|
||||
}
|
||||
|
||||
process.appendResult(profilerModel);
|
||||
} else { // 设置延时执行 stop
|
||||
final String outputFile = outputFile();
|
||||
String executeArgs = executeArgs(ProfilerAction.start);
|
||||
@@ -833,12 +865,27 @@ public class ProfilerCommand extends AnnotatedCommand {
|
||||
}
|
||||
|
||||
private ProfilerModel processStop(AsyncProfiler asyncProfiler, ProfilerAction profilerAction) throws IOException {
|
||||
String outputFile = outputFile();
|
||||
String outputFile = null;
|
||||
|
||||
// If we're stopping and a file was specified during start, don't generate a new
|
||||
// output file
|
||||
if (profilerAction == ProfilerAction.stop && fileSpecifiedAtStart != null) {
|
||||
outputFile = fileSpecifiedAtStart;
|
||||
// Reset the tracking variable after stop
|
||||
logger.debug("Using file specified during start: {}", fileSpecifiedAtStart);
|
||||
fileSpecifiedAtStart = null;
|
||||
} else {
|
||||
// Otherwise generate or use the specified output file
|
||||
outputFile = outputFile();
|
||||
}
|
||||
|
||||
String executeArgs = executeArgs(profilerAction);
|
||||
String result = execute(asyncProfiler, executeArgs);
|
||||
|
||||
ProfilerModel profilerModel = createProfilerModel(result);
|
||||
profilerModel.setOutputFile(outputFile);
|
||||
if (outputFile != null) {
|
||||
profilerModel.setOutputFile(outputFile);
|
||||
}
|
||||
return profilerModel;
|
||||
}
|
||||
|
||||
|
||||
@@ -377,12 +377,18 @@ profiler start -e cpu --jfrsync +jdk.YoungGarbageCollection+jdk.OldGarbageCollec
|
||||
|
||||
使用 `--loop TIME` 可以持续运行 profiler 并周期性保存结果。选项格式可以是具体时间 hh:mm:ss 或以秒、分钟、小时或天计算的时间间隔。需要确保指定的输出文件名中包含时间戳,否则每次输出的结果都会覆盖上次保存的结果。以下命令持续执行 profiling 并将每个小时内的记录保存到一个 jfr 文件中。
|
||||
|
||||
> 如果没有指定 `-f` 参数,则不会保存任何内容。如果 `-f` 参数里没有 `%t`,则会循环保存到同一个文件里。
|
||||
|
||||
```bash
|
||||
profiler start --loop 1h -f /var/log/profile-%t.jfr
|
||||
```
|
||||
|
||||
## `--timeout` 选项
|
||||
|
||||
```bash
|
||||
profiler start --timeout 300s
|
||||
```
|
||||
|
||||
这个选项指定 profiling 自动在多久后停止。该选项和 `--loop` 选项的格式一致,可以是时间点,也可以是一个时间间隔。这两个选项都是用于 `start` action。可参考 [async-profiler docs](https://github.com/async-profiler/async-profiler/blob/master/docs/ProfilerOptions.md) 了解更多信息。
|
||||
|
||||
## `--wall` 选项
|
||||
|
||||
@@ -379,12 +379,18 @@ profiler start -e cpu --jfrsync +jdk.YoungGarbageCollection+jdk.OldGarbageCollec
|
||||
|
||||
Use `--loop TIME` to run profiler in a loop (continuous profiling). The argument is either a clock time (hh:mm:ss) or a loop duration in seconds, minutes, hours, or days. Make sure the filename includes a timestamp pattern, or the output will be overwritten on each iteration. The command below will run profiling endlessly and save records of each hour to a jfr file.
|
||||
|
||||
> If the `-f` parameter is not specified, nothing will be saved. If the `-f` parameter does not contain `%t`, it will overwrite the same file repeatedly.
|
||||
|
||||
```bash
|
||||
profiler start --loop 1h -f /var/log/profile-%t.jfr
|
||||
```
|
||||
|
||||
## `--timeout` option
|
||||
|
||||
```bash
|
||||
profiler start --timeout 300s
|
||||
```
|
||||
|
||||
This option specifies the time when profiling will automatically stop. The format is the same as in loop: it is either a wall clock time (12:34:56) or a relative time interval (2h).
|
||||
|
||||
Both `--loop` and `--timeout` are used for `start` action, for further information refer to [async-profiler docs](https://github.com/async-profiler/async-profiler/blob/master/docs/ProfilerOptions.md).
|
||||
|
||||
Reference in New Issue
Block a user