diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java index 2c9cf3cbd0..54657ed302 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/ProfilerCommand.java @@ -219,6 +219,16 @@ public class ProfilerCommand extends AnnotatedCommand { */ private String chunktime; + /** + * run profiler in a loop (continuous profiling) + */ + private String loop; + + /** + * automatically stop profiler at TIME (absolute or relative) + */ + private String timeout; + private static String libPath; private static AsyncProfiler profiler = null; @@ -458,6 +468,25 @@ public void setChunktime(String chunktime) { this.chunktime = chunktime; } + @Option(longName = "loop") + @Description("run profiler in a loop (continuous profiling)") + public void setLoop(String loop) { + this.loop = loop; + if (this.action.equals("collect")) { + this.action = "start"; + } + } + + @Option(longName = "timeout") + @Description("automatically stop profiler at TIME (absolute or relative)") + public void setTimeout(String timeout) { + this.timeout = timeout; + if (this.action.equals("collect")) { + this.action = "start"; + } + } + + private AsyncProfiler profilerInstance() { if (profiler != null) { return profiler; @@ -504,7 +533,7 @@ private AsyncProfiler profilerInstance() { */ public enum ProfilerAction { // start, resume, stop, dump, check, status, meminfo, list, collect, - start, resume, stop, dump, check, status, meminfo, list, + start, resume, stop, dump, check, status, meminfo, list, collect, version, load, @@ -613,6 +642,12 @@ private String executeArgs(ProfilerAction action) { if (this.chunktime!= null) { sb.append("chunktime=").append(this.chunktime).append(COMMA); } + if (this.loop != null) { + sb.append("loop=").append(this.loop).append(COMMA); + } + if (this.timeout != null) { + sb.append("timeout=").append(this.timeout).append(COMMA); + } return sb.toString(); } @@ -646,12 +681,8 @@ public void process(final CommandProcess process) { } String result = execute(asyncProfiler, this.actionArg); appendExecuteResult(process, result); - } else if (ProfilerAction.start.equals(profilerAction)) { - //jfr录制,必须在start的时候就指定文件路径 - if (this.file == null && "jfr".equals(format)) { - this.file = outputFile(); - } - String executeArgs = executeArgs(ProfilerAction.start); + } else if (ProfilerAction.collect.equals(profilerAction)) { + String executeArgs = executeArgs(ProfilerAction.collect); String result = execute(asyncProfiler, executeArgs); ProfilerModel profilerModel = createProfilerModel(result); @@ -677,6 +708,10 @@ public void run() { }, this.duration, TimeUnit.SECONDS); } process.appendResult(profilerModel); + } else if (ProfilerAction.start.equals(profilerAction)) { + String executeArgs = executeArgs(ProfilerAction.start); + String result = execute(asyncProfiler, executeArgs); + appendExecuteResult(process, result); } else if (ProfilerAction.stop.equals(profilerAction)) { ProfilerModel profilerModel = processStop(asyncProfiler, profilerAction); process.appendResult(profilerModel); diff --git a/site/docs/.vuepress/public/images/dingding4_qr.png b/site/docs/.vuepress/public/images/dingding4_qr.png new file mode 100644 index 0000000000..13dc678a2c Binary files /dev/null and b/site/docs/.vuepress/public/images/dingding4_qr.png differ diff --git a/site/docs/doc/contact-us.md b/site/docs/doc/contact-us.md index dbfff42c8b..c9512665b7 100644 --- a/site/docs/doc/contact-us.md +++ b/site/docs/doc/contact-us.md @@ -16,18 +16,22 @@ ### 钉钉群 -- Arthas 开源交流钉钉群: 21965291 ,搜索群号即可加入。(如果满了无法加入,请加 3 群) +- Arthas 开源交流钉钉群: 21965291 ,搜索群号即可加入。(如果满了无法加入,请加 4 群) ![](/images/dingding_qr.jpg) -- Arthas 开源交流钉钉群 2: 30707824 ,搜索群号即可加入。(如果满了无法加入,请加 3 群) +- Arthas 开源交流钉钉群 2: 30707824 ,搜索群号即可加入。(如果满了无法加入,请加 4 群) ![](/images/dingding2_qr.jpg) -- Arthas 开源交流钉钉群 3: 17605006847 ,搜索群号即可加入。 +- Arthas 开源交流钉钉群 3: 17605006847 ,搜索群号即可加入。(如果满了无法加入,请加 4 群) ![](/images/dingding3_qr.jpg) +- Arthas 开源交流钉钉群 4: 41920010710 ,搜索群号即可加入。 + +![](/images/dingding4_qr.png) + ### QQ 群 Arthas 开源交流 QQ 群: 916328269 (如果满了无法加入,请加 3 群) diff --git a/site/docs/doc/profiler.md b/site/docs/doc/profiler.md index 83a557b48e..0e0f2d2298 100644 --- a/site/docs/doc/profiler.md +++ b/site/docs/doc/profiler.md @@ -226,10 +226,10 @@ profiler stop --include 'java/*' --include 'com/demo/*' --exclude '*Unsafe.park* ## 指定执行时间 -比如,希望 profiler 执行 300 秒自动结束,可以用 `-d`/`--duration` 参数指定: +比如,希望 profiler 执行 300 秒自动结束,可以用 `-d`/`--duration` 参数为 collect action 指定时间: ```bash -profiler start --duration 300 +profiler collect --duration 300 ``` ## 生成 jfr 格式结果 @@ -338,3 +338,15 @@ profiler --ttsp ```bash profiler start -e cpu --jfrsync profile -f combined.jfr ``` + +## 周期性保存结果 + +使用 `--loop TIME` 可以持续运行 profiler 并周期性保存结果。选项格式可以是具体时间 hh:mm:ss 或以秒、分钟、小时或天计算的时间间隔。需要确保指定的输出文件名中包含时间戳,否则每次输出的结果都会覆盖上次保存的结果。以下命令持续执行 profiling 并将每个小时内的记录保存到一个 jfr 文件中。 + +```bash +profiler start --loop 1h -f /var/log/profile-%t.jfr +``` + +## `--timeout` 选项 + +这个选项指定 profiling 自动在多久后停止。该选项和 `--loop` 选项的格式一致,可以是时间点,也可以是一个时间间隔。这两个选项都是用于 `start` action 而不是 `collect` action 的。可参考 [async-profiler Github Discussions](https://github.com/async-profiler/async-profiler/discussions/789) 了解更多信息。 diff --git a/site/docs/en/doc/contact-us.md b/site/docs/en/doc/contact-us.md index ace3e92790..abe3531bf7 100644 --- a/site/docs/en/doc/contact-us.md +++ b/site/docs/en/doc/contact-us.md @@ -18,6 +18,10 @@ Questions about how to use Arthas and opinions can be directly raised in issues ![](/images/dingding3_qr.jpg) +- Arthas open source discussion Group 4: 41920010710 , You can join by searching for group number。 + +![](/images/dingding4_qr.png) + ### Instructions for Installing DingTalk DingTalk can be downloaded from: [https://www.dingtalk.com/en](https://page.dingtalk.com/wow/dingtalk/act/en-download) diff --git a/site/docs/en/doc/profiler.md b/site/docs/en/doc/profiler.md index d535b01151..fa7318a276 100644 --- a/site/docs/en/doc/profiler.md +++ b/site/docs/en/doc/profiler.md @@ -226,10 +226,10 @@ profiler stop --include'java/*' --include 'com/demo/*' --exclude'*Unsafe.park*' ## Specify execution time -For example, if you want the profiler to automatically end after 300 seconds, you can specify it with the `-d`/`--duration` parameter: +For example, if you want the profiler to automatically end after 300 seconds, you can specify it with the `-d`/`--duration` parameter in collect action: ```bash -profiler start --duration 300 +profiler collect --duration 300 ``` ## Generate jfr format result @@ -338,3 +338,17 @@ For example, command below use "profile" config of JFR: ```bash profiler start -e cpu --jfrsync profile -f combined.jfr ``` + +## Run profiler in a loop + +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. + +```bash +profiler start --loop 1h -f /var/log/profile-%t.jfr +``` + +## `--timeout` option + +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 but not for `collect` action, for further information refer to [async-profiler Github Discussions](https://github.com/async-profiler/async-profiler/discussions/789).