From 19107ba0379b6c678001809eae6eb7f5b74d9c9b Mon Sep 17 00:00:00 2001 From: "bohr.qiu" Date: Fri, 21 Sep 2018 11:54:35 +0800 Subject: [PATCH 01/46] add jvm command thread related document --- site/src/site/sphinx/en/jvm.md | 6 ++++-- site/src/site/sphinx/jvm.md | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/site/src/site/sphinx/en/jvm.md b/site/src/site/sphinx/en/jvm.md index 25fe20325..74701b3b4 100644 --- a/site/src/site/sphinx/en/jvm.md +++ b/site/src/site/sphinx/en/jvm.md @@ -84,8 +84,9 @@ $ jvm THREAD COUNT 16 DAEMON-COUNT 10 - LIVE-COUNT 18 + PEAK-COUNT 18 STARTED-COUNT 19 + DEADLOCK-COUNT 0 Affect cost in 2 ms. ``` @@ -93,5 +94,6 @@ Affect cost in 2 ms. * COUNT: the count of active threads * DAEMON-COUNT: the count of active daemon threads -* LIVE-COUNT: the maximum count of the live threads since JVM starts +* PEAK-COUNT: the maximum count of the live threads since JVM starts * STARTED-COUNT: the total count of the created threads since JVM starts +* DEADLOCK-COUNT: the count of deadlock threads diff --git a/site/src/site/sphinx/jvm.md b/site/src/site/sphinx/jvm.md index 14989e5c3..2278ddedb 100644 --- a/site/src/site/sphinx/jvm.md +++ b/site/src/site/sphinx/jvm.md @@ -95,5 +95,6 @@ Affect cost in 2 ms. * COUNT: JVM当前活跃的线程数 * DAEMON-COUNT: JVM当前活跃的守护线程数 -* LIVE-COUNT: 从JVM启动开始曾经活着的最大线程数 -* STARTED-COUNT: 从jvm启动开始总共启动过的线程次数 \ No newline at end of file +* PEAK-COUNT: 从JVM启动开始曾经活着的最大线程数 +* STARTED-COUNT: 从jvm启动开始总共启动过的线程次数 +* DEADLOCK-COUNT: JVM当前死锁的线程数 \ No newline at end of file From d28c9d4def2602d8e7afc10572de536c2c360a33 Mon Sep 17 00:00:00 2001 From: "bohr.qiu" Date: Fri, 21 Sep 2018 12:06:52 +0800 Subject: [PATCH 02/46] add jvm command display file descriptor count --- .../core/command/monitor200/JvmCommand.java | 18 +++++++++++++++++- site/src/site/sphinx/en/jvm.md | 11 +++++++++++ site/src/site/sphinx/jvm.md | 14 ++++++++++++-- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/core/src/main/java/com/taobao/arthas/core/command/monitor200/JvmCommand.java b/core/src/main/java/com/taobao/arthas/core/command/monitor200/JvmCommand.java index 540112b21..7f3f295c2 100644 --- a/core/src/main/java/com/taobao/arthas/core/command/monitor200/JvmCommand.java +++ b/core/src/main/java/com/taobao/arthas/core/command/monitor200/JvmCommand.java @@ -14,6 +14,7 @@ import com.taobao.text.ui.TableElement; import com.taobao.text.util.RenderUtil; import java.lang.management.*; +import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; @@ -74,12 +75,27 @@ public class JvmCommand extends AnnotatedCommand { table.row("", ""); table.row(true, label("THREAD").style(Decoration.bold.bold())); drawThreadTable(table); - + table.row("", ""); + table.row(true, label("FILE-DESCRIPTOR").style(Decoration.bold.bold())); + drawFileDescriptorTable(table); process.write(RenderUtil.render(table, process.width())); process.write(affect.toString()).write("\n"); process.end(); } + private void drawFileDescriptorTable(TableElement table) { + table.row("MAX-FILE-DESCRIPTOR-COUNT", "" + invokeFileDescriptor(operatingSystemMXBean, "getMaxFileDescriptorCount")) + .row("OPEN-FILE-DESCRIPTOR-COUNT", "" + invokeFileDescriptor(operatingSystemMXBean, "getOpenFileDescriptorCount")); + } + private long invokeFileDescriptor(OperatingSystemMXBean os, String name) { + try { + final Method method = os.getClass().getDeclaredMethod(name); + method.setAccessible(true); + return (Long) method.invoke(os); + } catch (Exception e) { + return -1; + } + } private String toCol(Collection strings) { final StringBuilder colSB = new StringBuilder(); if (strings.isEmpty()) { diff --git a/site/src/site/sphinx/en/jvm.md b/site/src/site/sphinx/en/jvm.md index 74701b3b4..b787281b7 100644 --- a/site/src/site/sphinx/en/jvm.md +++ b/site/src/site/sphinx/en/jvm.md @@ -87,6 +87,11 @@ $ jvm PEAK-COUNT 18 STARTED-COUNT 19 DEADLOCK-COUNT 0 + + FILE-DESCRIPTOR + + MAX-FILE-DESCRIPTOR-COUNT 10240 + OPEN-FILE-DESCRIPTOR-COUNT 648 Affect cost in 2 ms. ``` @@ -97,3 +102,9 @@ Affect cost in 2 ms. * PEAK-COUNT: the maximum count of the live threads since JVM starts * STARTED-COUNT: the total count of the created threads since JVM starts * DEADLOCK-COUNT: the count of deadlock threads + + +### fileDescriptor-related + +* MAX-FILE-DESCRIPTOR-COUNT:the count of max file descriptor JVM process can open +* OPEN-FILE-DESCRIPTOR-COUNT:the current count of file descriptor JVM process open \ No newline at end of file diff --git a/site/src/site/sphinx/jvm.md b/site/src/site/sphinx/jvm.md index 2278ddedb..4e668aca7 100644 --- a/site/src/site/sphinx/jvm.md +++ b/site/src/site/sphinx/jvm.md @@ -87,6 +87,11 @@ $ jvm PEAK-COUNT 18 STARTED-COUNT 19 DEADLOCK-COUNT 0 + + FILE-DESCRIPTOR + + MAX-FILE-DESCRIPTOR-COUNT 10240 + OPEN-FILE-DESCRIPTOR-COUNT 648 Affect cost in 2 ms. ``` @@ -96,5 +101,10 @@ Affect cost in 2 ms. * COUNT: JVM当前活跃的线程数 * DAEMON-COUNT: JVM当前活跃的守护线程数 * PEAK-COUNT: 从JVM启动开始曾经活着的最大线程数 -* STARTED-COUNT: 从jvm启动开始总共启动过的线程次数 -* DEADLOCK-COUNT: JVM当前死锁的线程数 \ No newline at end of file +* STARTED-COUNT: 从JVM启动开始总共启动过的线程次数 +* DEADLOCK-COUNT: JVM当前死锁的线程数 + +### 文件描述符相关 + +* MAX-FILE-DESCRIPTOR-COUNT:JVM进程最大可以打开的文件描述符数 +* OPEN-FILE-DESCRIPTOR-COUNT:JVM当前打开的文件描述符数 From 700c0cb4415df7cce346c7cb76fa4a52d0c54bfa Mon Sep 17 00:00:00 2001 From: earayu Date: Fri, 21 Sep 2018 19:41:52 +0800 Subject: [PATCH 03/46] unit test & comments --- .../core/util/matcher/FalseMatcher.java | 5 ++ .../core/util/matcher/RegexMatcher.java | 2 +- .../arthas/core/util/matcher/TrueMatcher.java | 5 ++ .../core/util/matcher/WildcardMatcher.java | 2 +- .../core/util/matcher/EqualsMatcherTest.java | 20 ++++++ .../core/util/matcher/FalseMatcherTest.java | 19 ++++++ .../core/util/matcher/RegexMatcherTest.java | 63 +++++++++++++++++++ .../core/util/matcher/TrueMatcherTest.java | 19 ++++++ 8 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 core/src/test/java/com/taobao/arthas/core/util/matcher/EqualsMatcherTest.java create mode 100644 core/src/test/java/com/taobao/arthas/core/util/matcher/FalseMatcherTest.java create mode 100644 core/src/test/java/com/taobao/arthas/core/util/matcher/RegexMatcherTest.java create mode 100644 core/src/test/java/com/taobao/arthas/core/util/matcher/TrueMatcherTest.java diff --git a/core/src/main/java/com/taobao/arthas/core/util/matcher/FalseMatcher.java b/core/src/main/java/com/taobao/arthas/core/util/matcher/FalseMatcher.java index 4294834ff..1754c9c77 100644 --- a/core/src/main/java/com/taobao/arthas/core/util/matcher/FalseMatcher.java +++ b/core/src/main/java/com/taobao/arthas/core/util/matcher/FalseMatcher.java @@ -5,6 +5,11 @@ package com.taobao.arthas.core.util.matcher; */ public class FalseMatcher implements Matcher { + /** + * always return false + * @param target + * @return true/false + */ @Override public boolean matching(T target) { return false; diff --git a/core/src/main/java/com/taobao/arthas/core/util/matcher/RegexMatcher.java b/core/src/main/java/com/taobao/arthas/core/util/matcher/RegexMatcher.java index 4c6673dc6..1998265e3 100644 --- a/core/src/main/java/com/taobao/arthas/core/util/matcher/RegexMatcher.java +++ b/core/src/main/java/com/taobao/arthas/core/util/matcher/RegexMatcher.java @@ -1,7 +1,7 @@ package com.taobao.arthas.core.util.matcher; /** - * 正则表达式匹配 + * regex matcher * @author ralf0131 2017-01-06 13:16. */ public class RegexMatcher implements Matcher { diff --git a/core/src/main/java/com/taobao/arthas/core/util/matcher/TrueMatcher.java b/core/src/main/java/com/taobao/arthas/core/util/matcher/TrueMatcher.java index 28173b9c7..07512005f 100644 --- a/core/src/main/java/com/taobao/arthas/core/util/matcher/TrueMatcher.java +++ b/core/src/main/java/com/taobao/arthas/core/util/matcher/TrueMatcher.java @@ -5,6 +5,11 @@ package com.taobao.arthas.core.util.matcher; */ public final class TrueMatcher implements Matcher { + /** + * always return true + * @param target + * @return + */ @Override public boolean matching(T target) { return true; diff --git a/core/src/main/java/com/taobao/arthas/core/util/matcher/WildcardMatcher.java b/core/src/main/java/com/taobao/arthas/core/util/matcher/WildcardMatcher.java index e46885c24..3ab53cd4f 100644 --- a/core/src/main/java/com/taobao/arthas/core/util/matcher/WildcardMatcher.java +++ b/core/src/main/java/com/taobao/arthas/core/util/matcher/WildcardMatcher.java @@ -1,7 +1,7 @@ package com.taobao.arthas.core.util.matcher; /** - * 通配符表达式匹配 + * wildcard matcher * @author ralf0131 2017-01-06 13:17. */ public class WildcardMatcher implements Matcher { diff --git a/core/src/test/java/com/taobao/arthas/core/util/matcher/EqualsMatcherTest.java b/core/src/test/java/com/taobao/arthas/core/util/matcher/EqualsMatcherTest.java new file mode 100644 index 000000000..6a4191d5d --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/util/matcher/EqualsMatcherTest.java @@ -0,0 +1,20 @@ +package com.taobao.arthas.core.util.matcher; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author earayu + */ +public class EqualsMatcherTest { + + @Test + public void testMatching(){ + Assert.assertTrue(new EqualsMatcher(null).matching(null)); + Assert.assertTrue(new EqualsMatcher("").matching("")); + Assert.assertTrue(new EqualsMatcher("foobar").matching("foobar")); + Assert.assertFalse(new EqualsMatcher("").matching(null)); + Assert.assertFalse(new EqualsMatcher("abc").matching("def")); + } + +} diff --git a/core/src/test/java/com/taobao/arthas/core/util/matcher/FalseMatcherTest.java b/core/src/test/java/com/taobao/arthas/core/util/matcher/FalseMatcherTest.java new file mode 100644 index 000000000..5314df7e9 --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/util/matcher/FalseMatcherTest.java @@ -0,0 +1,19 @@ +package com.taobao.arthas.core.util.matcher; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author earayu + */ +public class FalseMatcherTest { + + @Test + public void testMatching(){ + Assert.assertFalse(new FalseMatcher().matching(null)); + Assert.assertFalse(new FalseMatcher().matching(1)); + Assert.assertFalse(new FalseMatcher().matching("")); + Assert.assertFalse(new FalseMatcher().matching("foobar")); + } + +} diff --git a/core/src/test/java/com/taobao/arthas/core/util/matcher/RegexMatcherTest.java b/core/src/test/java/com/taobao/arthas/core/util/matcher/RegexMatcherTest.java new file mode 100644 index 000000000..f272ae270 --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/util/matcher/RegexMatcherTest.java @@ -0,0 +1,63 @@ +package com.taobao.arthas.core.util.matcher; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author earayu + */ +public class RegexMatcherTest { + + @Test + public void testMatchingWithNullInputs(){ + Assert.assertFalse(new RegexMatcher(null).matching(null)); + Assert.assertFalse(new RegexMatcher(null).matching("foobar")); + Assert.assertFalse(new RegexMatcher("foobar").matching(null)); + Assert.assertTrue(new RegexMatcher("foobar").matching("foobar")); + } + + /** + * test regux with . | * + ? \s \S \w \W and so on... + */ + @Test + public void testMatchingWithRegularGrammar(){ + Assert.assertTrue(new RegexMatcher("foo?").matching("fo")); + Assert.assertTrue(new RegexMatcher("foo?").matching("foo")); + Assert.assertTrue(new RegexMatcher("foo.").matching("fooo")); + Assert.assertTrue(new RegexMatcher("foo*").matching("fooooo")); + Assert.assertTrue(new RegexMatcher("foo.*").matching("foobarbarbar")); + Assert.assertFalse(new RegexMatcher("foo+").matching("fo")); + Assert.assertTrue(new RegexMatcher("foo+").matching("fooooo")); + + Assert.assertTrue(new RegexMatcher("foo\\s").matching("foo ")); + Assert.assertFalse(new RegexMatcher("foo\\S").matching("foo ")); + Assert.assertTrue(new RegexMatcher("foo\\w").matching("fooo")); + Assert.assertTrue(new RegexMatcher("foo\\W").matching("foo ")); + Assert.assertFalse(new RegexMatcher("foo\\W").matching("fooo")); + + + Assert.assertTrue(new RegexMatcher("foo[1234]").matching("foo1")); + Assert.assertFalse(new RegexMatcher("foo[1234]").matching("foo5")); + Assert.assertTrue(new RegexMatcher("foo\\\\").matching("foo\\")); + Assert.assertTrue(new RegexMatcher("foo\\d").matching("foo5")); + Assert.assertTrue(new RegexMatcher("fo{1,3}").matching("fo")); + Assert.assertFalse(new RegexMatcher("fo{1,3}").matching("foooo")); + } + + @Test + public void testMatchingComplexRegex(){ + String ipAddressPattern = "((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)"; + Assert.assertTrue(new RegexMatcher(ipAddressPattern).matching("1.1.1.1")); + Assert.assertFalse(new RegexMatcher(ipAddressPattern).matching("255.256.255.0")); + Assert.assertFalse(new RegexMatcher(ipAddressPattern).matching("1.1.1")); + + Assert.assertTrue(new RegexMatcher("^foobar$").matching("foobar")); + Assert.assertFalse(new RegexMatcher("^foobar$").matching("\nfoobar")); + Assert.assertFalse(new RegexMatcher("^foobar$").matching("foobar\n")); + + String emailAddressPattern = "[a-z\\d]+(\\.[a-z\\d]+)*@([\\da-z](-[\\da-z])?)+(\\.{1,2}[a-z]+)+"; + Assert.assertTrue(new RegexMatcher(emailAddressPattern).matching("foo@bar.com")); + Assert.assertFalse(new RegexMatcher(emailAddressPattern).matching("asdfghjkl")); + } + +} diff --git a/core/src/test/java/com/taobao/arthas/core/util/matcher/TrueMatcherTest.java b/core/src/test/java/com/taobao/arthas/core/util/matcher/TrueMatcherTest.java new file mode 100644 index 000000000..1cfc6fbd6 --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/util/matcher/TrueMatcherTest.java @@ -0,0 +1,19 @@ +package com.taobao.arthas.core.util.matcher; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author earayu + */ +public class TrueMatcherTest { + + @Test + public void testMatching(){ + Assert.assertTrue(new TrueMatcher().matching(null)); + Assert.assertTrue(new TrueMatcher().matching(1)); + Assert.assertTrue(new TrueMatcher().matching("")); + Assert.assertTrue(new TrueMatcher().matching("foobar")); + } + +} From 354ee39224531bfcb31179b9d50d131980e73c16 Mon Sep 17 00:00:00 2001 From: Hearen Date: Sat, 22 Sep 2018 00:53:31 +0800 Subject: [PATCH 04/46] contributing en --- CONTRIBUTING_EN.md | 81 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 CONTRIBUTING_EN.md diff --git a/CONTRIBUTING_EN.md b/CONTRIBUTING_EN.md new file mode 100644 index 000000000..c9f95b9fc --- /dev/null +++ b/CONTRIBUTING_EN.md @@ -0,0 +1,81 @@ + +## Issue + +Welcome to use [issue tracker](https://github.com/alibaba/arthas/issues) to give us :bowtie:: + +* feedbacks - what you would like to have; +* usage tips - what usages you have found splendid; +* experiences - how you use Arthas to do **effective** troubleshooting; + +## Documentation + + +用户文档在`site/src/site/sphinx`目录下,如果希望改进Arthas用户文档,欢迎提交PR。 + +Welcome PR to further improve English [documentation](https://github.com/alibaba/arthas/tree/master/site/src/site/sphinx/en). + +## Developer + +Compilation requires JDK 7 and above since we are `java.lang.management.BufferPoolMXBean` while runtime requires JDK 6. + +### Local Installation + +Recommend to use [`as-package.sh`](as-package.sh) to package, which will auto-install the latest Arthas to local `~/.arthas` and when debugging, Arthas will auto-load the latest version. + +F.Y.I +1. when using [`as.sh`](https://github.com/alibaba/arthas/blob/master/bin/as.sh) to start Arthas, it will get the latest version under `~/.arthas/lib`; +2. when [`as-package.sh`](as-package.sh) packaging, it will get the version from `pom.xml` and suffix it with the current timestamp e.g. `3.0.5.20180917161808`. + +You can also use `./mvnw clean package -DskipTests` to package and generate a `zip` under `packaging/target/` but remember when `as.sh` starts, it load the version under `~/.arthas/lib`. + +### Start Arthas in specified version + +When there are several different version, you can use `--use-version` to specify the version of Arthas to start your debug. + +```bash +./as.sh --use-version 3.0.5.20180919185025 +``` + +Tip: you can use `--versions` to list all available versions. + +```bash +./as.sh --versions +``` + +### Debug + +There are two stages when booting Arthas: + +#### Stage 1 + +Execute `com.taobao.arthas.core.Arthas`, locate a proper JVM and attach to it. + +If you intend to debug this part, you can: + +```bash +./as.sh debug pid +``` + +The JPDA port is `8888`, you can connect to it from remote to debug; if you want to make it suspend after start, you can: + +```bash +JPDA_SUSPEND=y ./as.sh debug pid +``` + +#### Stage 2 +After attaching, Arthas agent runs inside the target process. If you want to debug agent, you have to make sure the target process is started in debug mode too. If so, then you can directly import the Arthas source code, and debug it. + +### Packaging All + +* Arthas is using [Sphinx](http://www.sphinx-doc.org/en/master/) to generate the static site +* `sphinx-maven-plugin` configured in [`site/pom.xml`](https://github.com/alibaba/arthas/tree/master/site) +* `sphinx-maven-plugin` executes by downloading`sphinx-binary/` +* a [bug](https://github.com/rtfd/recommonmark/issues/93) in Sphinx plugin `recommonmark`; we fix it by packaging another [version](https://github.com/hengyunabc/sphinx-binary/releases/tag/v0.4.0.1) +* when packaging the whole project (Packaging All), you need to (Only Unix/Linux/Mac supported): + + ```bash + ./mvnw clean package -DskipTests -P full -Dsphinx.binUrl=https://github.com/hengyunabc/sphinx-binary/releases/download/v0.4.0.1/sphinx.osx-x86_64 + ``` + + + From 3948c6c7899855e423d06c7160eadbbae81059f5 Mon Sep 17 00:00:00 2001 From: Hearen Date: Sat, 22 Sep 2018 10:14:31 +0800 Subject: [PATCH 05/46] fix some typos in quick start --- site/src/site/sphinx/en/quick-start.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/site/src/site/sphinx/en/quick-start.md b/site/src/site/sphinx/en/quick-start.md index 6c75ac463..fb3e1cb9e 100644 --- a/site/src/site/sphinx/en/quick-start.md +++ b/site/src/site/sphinx/en/quick-start.md @@ -56,8 +56,7 @@ public class Demo { sudo -u admin -EH ./as.sh ``` -2. For more details of the booting script, please refer to [starting arthas](start-arthas.md). - +2. For more details of the booting script, please refer to [Start Arthas](start-arthas.md). 3. If you cannot *attach* the target process, please check the logs under `~/logs/arthas` for troubleshooting. 4. Selecting the target process as: @@ -152,7 +151,7 @@ ts=2018-09-10 17:53:14;result=@Integer[624] ts=2018-09-10 17:53:15;result=@Integer[625] ``` -[more advanced functions](advanced-use.md) +[more advanced usages](advanced-use.md) ## 5. Exit Arthas From 6fc0a5bc842dd4262bf887cd697bc6e36c69e4df Mon Sep 17 00:00:00 2001 From: Hearen Date: Sat, 22 Sep 2018 10:38:26 +0800 Subject: [PATCH 06/46] fix typos in watch en & quick start en --- site/src/site/sphinx/en/quick-start.md | 4 ++-- site/src/site/sphinx/en/watch.md | 24 ++++++++++++------------ 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/site/src/site/sphinx/en/quick-start.md b/site/src/site/sphinx/en/quick-start.md index fb3e1cb9e..19fa32248 100644 --- a/site/src/site/sphinx/en/quick-start.md +++ b/site/src/site/sphinx/en/quick-start.md @@ -89,8 +89,8 @@ public class Demo { version: 3.0.1-RC-SNAPSHOT pid: 13560 timestamp: 1536656867894 - '`'`'`'`'`'`'`'`'` - ' + + $ ``` ### Windows diff --git a/site/src/site/sphinx/en/watch.md b/site/src/site/sphinx/en/watch.md index c6bc990f5..95d88cccc 100644 --- a/site/src/site/sphinx/en/watch.md +++ b/site/src/site/sphinx/en/watch.md @@ -1,38 +1,38 @@ watch ===== -Monitor the methods in data aspect including `return value`, `exceptions` and `parameters`. +Monitor methods in data aspect including `return values`, `exceptions` and `parameters`. -With the help of [OGNL](https://en.wikipedia.org/wiki/OGNL), you can easily check the details of the variables. +With the help of [OGNL](https://en.wikipedia.org/wiki/OGNL), you can easily check the details of variables. ### Parameters & Options -There are four different usage scenarios for `watch` command, which makes it the most complicated command in Arthas. +There are four different scenarios for `watch` command, which makes it a rather complicated command in Arthas. |Name|Specification| |---:|:---| |*class-pattern*|pattern for the class name| |*method-pattern*|pattern for the method name| |*express*|expression to monitor| -|*condition-express*|condition expression| -|[b]|before invoking| +|*condition-express*|condition expression to filter| +|[b]|before method being invoked| |[e]|encountering exceptions| |[s]|returned normally| |[f]|returned normally and abnormally| -|[E]|turn on regx matching while the default is wildcards matching| +|[E]|turn on regex matching while the default is wildcards matching| |[x:]|the depth to print the specified property with default value: 1| F.Y.I 1. any valid OGNL expression as `"{params,returnObj}"` supported 2. there are four *watching* points: `-b`, `-e`, `-s` and `-f` (the first three are off in default while `-f` on); -3. at the *watching* point, Arthas will use the `expression` to calculate the values and print them out; -4. `in-parameters` and `out-parameters` are different since they can be modified; `params` stands for `in-parameters` in `-b`while `out-parameters` in other *watching* points; -5. there is no `return value` and `exceptions` when using `-b`. +3. at the *watching* point, Arthas will use the *expression* to evaluate the variables and print them out; +4. `in-parameters` and `out-parameters` are different since they can be modified within the invoked methods; `params` stands for `in-parameters` in `-b`while `out-parameters` in other *watching* points; +5. there is no `return values` and `exceptions` when using `-b`. Advanced: -* [Critical fields in expression](advice-class.md) -* [Special usage](https://github.com/alibaba/arthas/issues/71) +* [Critical fields in *expression*](advice-class.md) +* [Special usages](https://github.com/alibaba/arthas/issues/71) * [OGNL official guide](https://commons.apache.org/proper/commons-ognl/language-guide.html) ### Usage @@ -57,7 +57,7 @@ A demo: return list.size(); } ``` -#### Check the `out-parameters`and `return value` +#### Check the `out-parameters` and `return value` ```shell $ watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "{params,returnObj}" -x 2 From 1ad373529add8188fc5554f168c74b6fcaf0b7bc Mon Sep 17 00:00:00 2001 From: Hearen Date: Sat, 22 Sep 2018 12:20:50 +0800 Subject: [PATCH 07/46] fix typos in advance use en --- site/src/site/sphinx/en/advanced-use.md | 45 ++++++++++++------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/site/src/site/sphinx/en/advanced-use.md b/site/src/site/sphinx/en/advanced-use.md index f00ae75e7..31d413bcc 100644 --- a/site/src/site/sphinx/en/advanced-use.md +++ b/site/src/site/sphinx/en/advanced-use.md @@ -3,40 +3,40 @@ Advanced Usage ## Basic -- help +- help - show help info - cls - clear out the current screen - session - check details of the current session -- [reset](reset.md) - reset all empowered classes +- [reset](reset.md) - reset all injected/enhanced classes - version - print the version of the Arthas attaching to the current target process - quit/exit - exit the current Arthas client without affecting other clients - shutdown - terminate the Arthas server and all clients -## JVM-related +## JVM * [dashboard](dashboard.md) - real-time dashboard for the current system * [thread](thread.md) - thread profile * [jvm](jvm.md) - JVM profile * [sysprop](sysprop.md) - check or modify JVM system properties -* **New!** [getstatic](getstatic.md) - check the static properties of some class +* **New!** [getstatic](getstatic.md) :clap: - check the static properties of classes -## class/classloader - related +## class/classloader -* [sc](sc.md) - methods' profile of the classes loaded by JVM -* [sm](sm.md) - methods' profile of the loaded classes -* [dump](dump.md) - dump out the byte code of the loaded class to specified location -* [redefine](redefine.md) - load external `*.class` files and re-define the JVM +* [sc](sc.md) - check profiles of the classes loaded by JVM +* [sm](sm.md) - check methods' profile +* [dump](dump.md) - dump out the byte code of the loaded classes to specified location +* [redefine](redefine.md) - load external `*.class` files and re-define the JVM-loaded classes * [jad](jad.md) - de-compile the specified loaded classes -* [classloader](classloader.md) - check the inheritance structure, urls, class loading info of class cloader; using classloader to getResource +* [classloader](classloader.md) - check the inheritance structure, urls, class loading info of class cloader; using classloader to get the url of the resource e.g. `java/lang/String.class` ## monitor/watch/trace - related -> **Attention**: commands here are taking advantage of `byte code injection`, which means we are using [AOP](https://en.wikipedia.org/wiki/Aspect-oriented_programming) to monitor and analyze the classes. So when using it for online troubleshooting, you'd better *explicitly specifically* specify the classes and also remember to remove the injected code by `shutdown` or `reset` (for specific classes). +> **Attention**: commands here are taking advantage of `byte code injection`, which means we are using [AOP](https://en.wikipedia.org/wiki/Aspect-oriented_programming) to monitor and analyze the classes. So when using it for online troubleshooting, you'd better *explicitly specifically* specify the classes and also remember to remove the injected code by `shutdown` or `reset`. -* [monitor](monitor.md) -* [watch](watch.md) -* [trace](trace.md) - track the call stack trace and collect the time cost for each method call -* [stack](stack.md) - print the call stack trace of the current method +* [monitor](monitor.md) - monitor the `class-pattern` & `method-pattern` matched methods' invoking traces +* [watch](watch.md) - watch/monitor methods in data aspect including `return values`, `exceptions` and `parameters` +* [trace](trace.md) - track the method calling trace along with the time cost for each call +* [stack](stack.md) - print the call stack trace of the current method in a persistent way * [tt](tt.md) - record the arguments and returned value for the methods, history included ## options @@ -48,13 +48,15 @@ Advanced Usage `pipe` is supported in Arthas, e.g. `sm org.apache.log4j.Logger | grep ` -* grep +Commands supported in `pipe`: + +* grep - filtering * plaintext - remove the color -* wc +* wc - line counting ## async in background -[async](async.md) will be a great help, when the `incident` seldom occurs and you are `[watch](watch.md)`ing it. +[async](async.md) will be a great help, when the `incident` seldom occurs and you are [`watch`](watch.md)ing it. * jobs - list all jobs @@ -63,14 +65,9 @@ Advanced Usage * bg - put the paused job to the background * tips - a) use `>` to redirect the output; b) use `&` to put the job to the background; c) disconnecting the session will not influence the job (the default life is 1 day) -## Web Console - -Using websocket to connect Arthas - -* [Web Console](web-console.md) - ## Others +* [Web Console](web-console.md) - using websocket to connect Arthas * [log the output](save-log.md) * [batch](batch-support.md) * [how to use ognl](https://github.com/alibaba/arthas/issues/11) From 92494d04ee80fd6353d5221dd7628718dd3415a9 Mon Sep 17 00:00:00 2001 From: Hearen Date: Sat, 22 Sep 2018 15:02:15 +0800 Subject: [PATCH 08/46] fix typos and optimize descriptions - options --- site/src/site/sphinx/en/options.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/site/src/site/sphinx/en/options.md b/site/src/site/sphinx/en/options.md index e22472d48..023d81948 100644 --- a/site/src/site/sphinx/en/options.md +++ b/site/src/site/sphinx/en/options.md @@ -3,20 +3,20 @@ options > Global options -| Name | Default Value | Description | -| ------------------ | ----- | ---------------------------------------- | -| unsafe | false | Enable support for system-level class enhancement; JVM might crash, if you turn on this switch (please use with great caution!) | -| dump | false | Enable support for dumping enhanced class to external file,if turned on,class file will be dumped to`/${application dir}/arthas-class-dump/`,please see console for specific location | +|   Name   | Default Value | Description | +| ------------------------- | ----- | ---------------------------------------- | +| unsafe | false | Enable system-level class enhancement; JVM might crash, if you turn it on (use with great caution :exclamation:) | +| dump | false | Enable support for dumping enhanced class to external file; if turned on, class file will be dumped to`/${application dir}/arthas-class-dump/`,please check console output for specific location | | batch-re-transform | true | re-transform matched classes in batch | | json-format | false | Enable output in JSON format | -| disable-sub-class | false | Disabling child class matching,by default child class will be matched during matching target class,if you wish exact matching,you can turn this off | -| debug-for-asm | false | Print ASM related debug message | -| save-result | false | Enable saving logs for task results,when turn to true, all command results will be saved to `/home/admin/logs/arthas/arthas.log` | -| job-timeout | 1d | Default time-out time for back-stage tasks,if exceed this time,task will be stopped;i.e. 1d, 2h, 3m, 25s,representing day、hour、minute、second | +| disable-sub-class | false | Disabling child class matching: by default child class will be matched while matching target class; if you wish exact matching, you should turn it off | +| debug-for-asm | false | Print ASM-related debug message | +| save-result | false | Enable saving logs for task results: when true, all command results will be saved to `/home/admin/logs/arthas/arthas.log` | +| job-timeout | 1d | Default timeout for background jobs: jobs will be stopped once timed out (i.e. 1d, 2h, 3m, 25s)| ### Usage -For example,if you wish to save logs for command results, you can use following command: +Saving logs for command outputs, you can: ``` $ options save-result true From fc35390dc9323453451121f465295c4a4f3f56eb Mon Sep 17 00:00:00 2001 From: Hearen Date: Fri, 21 Sep 2018 23:41:47 +0800 Subject: [PATCH 09/46] release-notes en --- site/src/site/sphinx/en/release-notes.md | 123 +++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 site/src/site/sphinx/en/release-notes.md diff --git a/site/src/site/sphinx/en/release-notes.md b/site/src/site/sphinx/en/release-notes.md new file mode 100644 index 000000000..fffdecd9d --- /dev/null +++ b/site/src/site/sphinx/en/release-notes.md @@ -0,0 +1,123 @@ +Release Notes +============= + +### :tada: :tada: [v3.0.4](https://github.com/alibaba/arthas/milestone/1?closed=1) :exclamation: + +v2017-11-03 +---- + +* [improvement] add [`getstatic`](getstatic.md) +* [bug] fix Arthas class loader logs loading issues +* [improvement] introduce [OGNL](https://en.wikipedia.org/wiki/OGNL) to customize `classloader` to invoke static methods +* [improvement] optimise `termd` uppercase output performance +* [improvement] `classloader` compile in class loader category by default +* [bug] fix `wc` counting issue +* [improvement] disable certain JDK classes e.g. `Classloader`, `Method`, `Integer` and the lik +* [improvement] quit directly when encountering incorrect [OGNL](https://en.wikipedia.org/wiki/OGNL) expression +* [bug] fix `pipe` issues +* [improvement] optimize command re-direct features using asynchronous log +* [improvement] [`trace`](trace.md) can filter JDK method calls + +v2017-09-22 +---- + +* [improvement] improve the error message when starting agent and server fails +* [bug] fix some asynchronous issues + +v2017-09-11 +---- + +* [improvement] [`async`](async.md) supported +* [improvement] optimize [`jad`](jad.md) support JDK 8 and inner class +* [bug] fix Chinese encoding issues + +v2017-05-11 +---- + +* [improvement] [`tt`](tt.md) investigating/recording level one to avoid too much performance overhea +* [bug] fix Chinese characters can not be presented issue + +v2017-05-12 +---- + +* Arthas 3.0 release :confetti_ball: + +v2016-12-09 +---- + +* [feature] [`as.sh`](https://github.com/alibaba/arthas/blob/master/bin/as.sh) support `-h` to print help info +* [bug] [#121] fix leftover temp files causing Arthas cannot start issue +* [bug] [#123] fix `attach/shutdown` repeatedly causing Arthas classloader leakage issue +* [improvement] make the help info more readable +* [bug] [#126] fix the documents links issues +* [bug] [#122] fix the [`classloader`](classloader.md) filtering out `sun.reflect.DelegatingClassLoader` issue +* [bug] [#129] fix [`classloader`](classloader.md) presenting structure issues +* [improvement] [#125] make the Arthas log output more readable +* [improvement] [#96] [`sc`](sc.md) and more commands are supporting format as `com/taobao/xxx/TestClass` +* [bug] [#124] fix the negative values of [`trace`](trace.md) +* [improvement] [#128] the output of [`tt`](tt.md) will auto-expand now +* [bug] [#130] providing more meaningful error messages when port conflicts +* [bug] [#98] fix Arthas starting issue: when updating/downloading failed, Arthas will fail to start +* [bug] [#139] fix agent attaching fails under some scenarios issues +* [improvement] [#156] delay `jd-core-java` initialization to avoid Arthas starting failure +* [bug] avoid thread names duplicate issue +* [improvement] [#150] filtering by total time cost in [`trace`](trace.md) +* [bug] fix [`sc`](sc.md) `NPE` issue when searching `SystemClassloader` +* [bug] [#180] fix attach fails issues: attaching succeed at the first time, delete the Arthas installer, re-compile and package => attaching fails + + +v2016-06-07 +---- + +* [bug] fix NPE when loading `spy` as resource +* [improvement] locating the blocking thread +* [improvement] print out thread in name order +* [improvement] specify the refreshing interval when checking topN busiest threads + +v2016-04-08 +---- + +* [feature] specify refreshing interval and execution times in [`dashboard`](dashboard.md) +* [feature] log the command execution result +* [feature] speed up the booting and attaching while the first attaching is even quicker by 100% than before +* [feature] batch supported; script supported +* [feature] interactive mode used in Arthas +* [feature] inheritance relation included in class searching; global option `disable-sub-class` can be used to turn it off +* [feature] colorful and plain text modes both supported +* [improvement] merge `exit` and `quit` commands +* [improvement] help info enclosed with wiki links +* [improvement] optimize [`watch`](watch.md) using flow for better UX +* [improvement] add examples to [`thread`](thread.md) +* [improvement] auto-completion ignores character case +* [improvement] make the UI more beautiful/friendly +* [bug] fix [`trace`](trace.md) printing too much encountering loop issues +* [bug] fix [`trace`](trace.md) node twisting issues when method throwing exceptions +* [bug] fix injected/enhanced `BootstrapClassLoader` cannot locate `spy` issues + +v2016-03-07 +---- + +* [feature] checking the topN thread and related stack traces +* [bug] fix Arthas starting failure in OpenJdk issues (requiring to reinstall [as.sh](https://github.com/alibaba/arthas/blob/master/bin/as.sh)) +* [improvement] optimize UX + + +v2016-01-18 +---- + +* [improvement] optimise [`jad`](jad.md); dump memory byte array in real time; using `jd-core-java` to de-compile; line number presented; +* [bug] fix checking/re-producing issues when [`tt`](tt.md) is watching thread-context related methods invoking + +v2016-01-08 +---- + +* [bug] jad NPE +* [bug] watch/monitor NPE +* [bug] wrong escaping issues +* [bug] wrong statistics +* [bug] [`sc`](sc.md) checking internal structure issues + +v2015-12-29 +--- + +* Arthas 2.0 Beta :boom:! From 9237e9b32aeb04a544dd5a793a204dc6d731f074 Mon Sep 17 00:00:00 2001 From: earayu Date: Sat, 22 Sep 2018 16:44:45 +0800 Subject: [PATCH 10/46] #135 1. change the param's name, from 'string' to 'target' 2. get rid of the magic value of: * ? \ 3. bugfix: return false if the pattern or target is NULL --- .../core/util/matcher/WildcardMatcher.java | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/core/src/main/java/com/taobao/arthas/core/util/matcher/WildcardMatcher.java b/core/src/main/java/com/taobao/arthas/core/util/matcher/WildcardMatcher.java index 3ab53cd4f..f97946d0e 100644 --- a/core/src/main/java/com/taobao/arthas/core/util/matcher/WildcardMatcher.java +++ b/core/src/main/java/com/taobao/arthas/core/util/matcher/WildcardMatcher.java @@ -8,6 +8,12 @@ public class WildcardMatcher implements Matcher { private final String pattern; + private static final Character ASTERISK = '*'; + private static final Character QUESTION_MARK = '?'; + private static final Character ESCAPE = '\\'; + + + public WildcardMatcher(String pattern) { this.pattern = pattern; } @@ -21,51 +27,61 @@ public class WildcardMatcher implements Matcher { /** * Internal matching recursive function. */ - private boolean match(String string, String pattern, int stringStartNdx, int patternStartNdx) { + private boolean match(String target, String pattern, int stringStartNdx, int patternStartNdx) { + //#135 + if(target==null || pattern==null){ + return false; + } int pNdx = patternStartNdx; int sNdx = stringStartNdx; int pLen = pattern.length(); if (pLen == 1) { - if (pattern.charAt(0) == '*') { // speed-up + // speed-up + if (pattern.charAt(0) == ASTERISK) { return true; } } - int sLen = string.length(); + int sLen = target.length(); boolean nextIsNotWildcard = false; while (true) { // check if end of string and/or pattern occurred - if ((sNdx >= sLen)) { // end of string still may have pending '*' callback pattern - while ((pNdx < pLen) && (pattern.charAt(pNdx) == '*')) { + if ((sNdx >= sLen)) { + // end of string still may have pending '*' callback pattern + while ((pNdx < pLen) && (pattern.charAt(pNdx) == ASTERISK)) { pNdx++; } return pNdx >= pLen; } - if (pNdx >= pLen) { // end of pattern, but not end of the string + // end of pattern, but not end of the string + if (pNdx >= pLen) { return false; } - char p = pattern.charAt(pNdx); // pattern char + // pattern char + char p = pattern.charAt(pNdx); // perform logic if (!nextIsNotWildcard) { - if (p == '\\') { + if (p == ESCAPE) { pNdx++; nextIsNotWildcard = true; continue; } - if (p == '?') { + if (p == QUESTION_MARK) { sNdx++; pNdx++; continue; } - if (p == '*') { - char pnext = 0; // next pattern char + if (p == ASTERISK) { + // next pattern char + char pnext = 0; if (pNdx + 1 < pLen) { pnext = pattern.charAt(pNdx + 1); } - if (pnext == '*') { // double '*' have the same effect as one '*' + // double '*' have the same effect as one '*' + if (pnext == ASTERISK) { pNdx++; continue; } @@ -74,8 +90,8 @@ public class WildcardMatcher implements Matcher { // find recursively if there is any substring from the end of the // line that matches the rest of the pattern !!! - for (i = string.length(); i >= sNdx; i--) { - if (match(string, pattern, i, pNdx)) { + for (i = target.length(); i >= sNdx; i--) { + if (match(target, pattern, i, pNdx)) { return true; } } @@ -86,7 +102,7 @@ public class WildcardMatcher implements Matcher { } // check if pattern char and string char are equals - if (p != string.charAt(sNdx)) { + if (p != target.charAt(sNdx)) { return false; } From e3567e2317df80626c80e66e94376d77e823e671 Mon Sep 17 00:00:00 2001 From: earayu Date: Sat, 22 Sep 2018 16:52:51 +0800 Subject: [PATCH 11/46] unit test for WildcardMatcher --- .../util/matcher/WildcardMatcherTest.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 core/src/test/java/com/taobao/arthas/core/util/matcher/WildcardMatcherTest.java diff --git a/core/src/test/java/com/taobao/arthas/core/util/matcher/WildcardMatcherTest.java b/core/src/test/java/com/taobao/arthas/core/util/matcher/WildcardMatcherTest.java new file mode 100644 index 000000000..e63a71cd1 --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/util/matcher/WildcardMatcherTest.java @@ -0,0 +1,36 @@ +package com.taobao.arthas.core.util.matcher; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author earayu + */ +public class WildcardMatcherTest { + + @Test + public void testMatching(){ + Assert.assertFalse(new WildcardMatcher(null).matching(null)); + Assert.assertFalse(new WildcardMatcher(null).matching("foo")); + Assert.assertFalse(new WildcardMatcher("foo").matching(null)); + + Assert.assertTrue(new WildcardMatcher("foo").matching("foo")); + Assert.assertFalse(new WildcardMatcher("foo").matching("bar")); + + Assert.assertTrue(new WildcardMatcher("foo*").matching("foo")); + Assert.assertTrue(new WildcardMatcher("foo*").matching("fooooooobar")); + Assert.assertTrue(new WildcardMatcher("f*r").matching("fooooooobar")); + Assert.assertFalse(new WildcardMatcher("foo*").matching("fo")); + Assert.assertFalse(new WildcardMatcher("foo*").matching("bar")); + + Assert.assertFalse(new WildcardMatcher("foo?").matching("foo")); + Assert.assertTrue(new WildcardMatcher("foo?").matching("foob")); + + Assert.assertTrue(new WildcardMatcher("foo\\*").matching("foo*")); + Assert.assertFalse(new WildcardMatcher("foo\\*").matching("foooooo")); + + Assert.assertTrue(new WildcardMatcher("foo\\?").matching("foo?")); + Assert.assertFalse(new WildcardMatcher("foo\\?").matching("foob")); + } + +} From e440e624d4fedcc9d7a4eb9a01c3724d5c0955af Mon Sep 17 00:00:00 2001 From: Hearen Date: Sat, 22 Sep 2018 16:33:39 +0800 Subject: [PATCH 12/46] save-log en --- site/src/site/sphinx/en/save-log.md | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 site/src/site/sphinx/en/save-log.md diff --git a/site/src/site/sphinx/en/save-log.md b/site/src/site/sphinx/en/save-log.md new file mode 100644 index 000000000..cb4ba4c25 --- /dev/null +++ b/site/src/site/sphinx/en/save-log.md @@ -0,0 +1,37 @@ +Log command outputs +=================== + +Log command outputs for later analysis, turned off by default. + +To turn it on, using [options](options.md) as: + +```sh +$ options save-result true + NAME BEFORE-VALUE AFTER-VALUE +---------------------------------------- + save-result false true +Affect(row-cnt:1) cost in 3 ms. +``` + +F.Y.I + +1. logging file lies in: `{user.home}/logs/arthas-cache/result.log`; +2. remember to clean up the file to save disk space. + +### Asynchronous log + + :notes: :notes: +With the latest Arthas, you can log the outputs asynchronously in the background: + +```sh +$ trace Test t >> & +job id : 2 +cache location : /Users/zhuyong/logs/arthas-cache/28198/2 +``` + +F.Y.I + +1. `quit/exit` or `Ctrl+C` will not affect the asynchronous jobs :sparkles:; +2. default timeout for the background job is 1 day (you can set it via [options](options.md)); +3. outputs will be save to the `cache location` now (no matter what `save-result` is - not `~/logs/arthas-cache/result.log` any more). + From f590986744fa3a1d720750b4f078f8e629badec8 Mon Sep 17 00:00:00 2001 From: earayu Date: Sat, 22 Sep 2018 18:19:28 +0800 Subject: [PATCH 13/46] 1. add some comments 2. do some minimum refactor --- .../com/taobao/arthas/core/util/IPUtils.java | 47 ++++++++----------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/core/src/main/java/com/taobao/arthas/core/util/IPUtils.java b/core/src/main/java/com/taobao/arthas/core/util/IPUtils.java index 1f7508b2e..9d2b704a0 100644 --- a/core/src/main/java/com/taobao/arthas/core/util/IPUtils.java +++ b/core/src/main/java/com/taobao/arthas/core/util/IPUtils.java @@ -5,55 +5,52 @@ import java.net.NetworkInterface; import java.util.Enumeration; /** - * @author weipeng2k 2015年1月30日 下午3:06:47 + * @author weipeng2k 2015-01-30 15:06:47 */ public class IPUtils { + private static final String WINDOWS = "windows"; + private static final String OS_NAME = "os.name"; + /** - * 判断当前操作是否Windows. - * - * @return true---是Windows操作系统 + * check: whether current operating system is windows + * + * @return true---is windows */ public static boolean isWindowsOS() { - boolean isWindowsOS = false; - String osName = System.getProperty("os.name"); - if (osName.toLowerCase().indexOf("windows") > -1) { - isWindowsOS = true; - } - return isWindowsOS; + String osName = System.getProperty(OS_NAME); + return osName.toLowerCase().contains(WINDOWS); } /** - * 获取本机IP地址,并自动区分Windows还是Linux操作系统 - * + * get IP address, automatically distinguish the operating system.(windows or linux) + * * @return String */ public static String getLocalIP() { - String sIP = null; InetAddress ip = null; try { if (isWindowsOS()) { ip = InetAddress.getLocalHost(); } else { - // 如果是回环地址则扫描所有的NetWorkInterface + //scan all NetWorkInterfaces if it's loopback address if (!InetAddress.getLocalHost().isLoopbackAddress()) { ip = InetAddress.getLocalHost(); } else { boolean bFindIP = false; - Enumeration netInterfaces = (Enumeration) NetworkInterface.getNetworkInterfaces(); + Enumeration netInterfaces = NetworkInterface.getNetworkInterfaces(); while (netInterfaces.hasMoreElements()) { if (bFindIP) { break; } - NetworkInterface ni = (NetworkInterface) netInterfaces.nextElement(); + NetworkInterface ni = netInterfaces.nextElement(); // ----------特定情况,可以考虑用ni.getName判断 - // 遍历所有ip + // iterator all IPs Enumeration ips = ni.getInetAddresses(); while (ips.hasMoreElements()) { - ip = (InetAddress) ips.nextElement(); - // 127.开头的都是lookback地址 - if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() - && ip.getHostAddress().indexOf(":") == -1) { + ip = ips.nextElement(); + // IP starts with 127. is loopback address + if (ip.isSiteLocalAddress() && !ip.isLoopbackAddress() && !ip.getHostAddress().contains(":")) { bFindIP = true; break; } @@ -65,13 +62,7 @@ public class IPUtils { } catch (Exception e) { } - if (ip != null) { - sIP = ip.getHostAddress(); - } - return sIP; + return ip == null ? null : ip.getHostAddress(); } - public static void main(String[] args) { - System.out.println(getLocalIP()); - } } From f6970242e9f597c54bba32b89831e2ce38116f7a Mon Sep 17 00:00:00 2001 From: Hearen Date: Sun, 23 Sep 2018 17:35:40 +0800 Subject: [PATCH 14/46] batch processing translated --- site/src/site/sphinx/en/batch-support.md | 39 ++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 site/src/site/sphinx/en/batch-support.md diff --git a/site/src/site/sphinx/en/batch-support.md b/site/src/site/sphinx/en/batch-support.md new file mode 100644 index 000000000..1095985b1 --- /dev/null +++ b/site/src/site/sphinx/en/batch-support.md @@ -0,0 +1,39 @@ +Batch Processing +================ + +With the help of `Batch Processing`, you can run several commands in one line and get the results. + +### Usage + +#### Step-1: Create the script + +Creating a `test.as` script suffixed with `as` here for consistency (actually any suffix is acceptable). + +``` +➜ arthas git:(develop) cat /var/tmp/test.as +help +dashboard -b -n 1 +session +thread +sc -d org.apache.commons.lang.StringUtils +``` + +Attention: +* each command takes each independent line; +* `dashboard` command should include `-b` to turn on batch mode and `-n` to ensure the script ends; +* commands as `watch/tt/trace/monitor/stack` should include `-n` option to ensure the script ends; +* [asynchronous](async.md) can also be used as `watch c.t.X test returnObj > &`; + +#### Step-2: Run the script + +Using `-b` to turn on script mode, and `-f` to run it and you can also *redirect* the output as: + +```sh +./as.sh -b -f /var/tmp/test.as 56328 > test.out +``` + +#### Step-3: Check the outputs + +```sh +cat test.out +``` From c9d9edada8424b9bd339d6d0e46c3f1513f5f223 Mon Sep 17 00:00:00 2001 From: Windshear <34466573+ktz72@users.noreply.github.com> Date: Sun, 23 Sep 2018 16:17:00 +0530 Subject: [PATCH 15/46] README-minor-changes.md Some improvements in Grammer of Documentation --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a9f3420f3..94e451e4e 100644 --- a/README.md +++ b/README.md @@ -6,21 +6,21 @@ Arthas can help developer trouble-shooting production issues for Java applications without modifying your code or restating your server. -[中文说明](README_CN.md) +[中文说明](README_CN.md) (For Chinese Documentation) ### Background In production system, sometimes the networks is unreachable from local development environment. If you encounter some issues in production system, it is impossible to use IDE to debug the application remotely. More importantly, debugging in production is unacceptable, because it will suspend all the threads, which leads to business unavailability. -Some may think of reproducing the same issue on the test/staging environment, however, some tricky issue either can hardly be reproduced on a different environment, or even disappeared once restarted. +Some may think of reproducing the same issue on the test/staging environment, however, some tricky issues either can hardly be reproduced on a different environment, or even disappear once restarted. -Thinking of adding some logs to your code? You have to go through test, staging, and then on to production. Time is money! That is a lot inefficient! Besides, the issue may not be reproducible once restart your JVM, as described above. +Thinking of adding some logs to your code? You have to go through test, staging, and then on to production. Time is money! That is a lot inefficient! Besides, the issue may not be reproducible once you restart your JVM, as described above. -Arthas is born to solve these issues. You can trouble-shoot your production issue on-the-fly. No JVM restart, no additional code changes. Arthas works as an observer, which will never suspend your existing threads. +Arthas is born to solve these issues. You can trouble-shoot your production issue on-the-fly. No need for JVM restart, no additional code changes. Arthas works as an observer, which will never suspend your existing threads. ### Key features -* Check whether a class is loaded? And whether is class loaded from? (Useful for trouble-shooting jar file conflicts) +* Check whether a class is loaded? And where the class is loaded from? (Useful for trouble-shooting jar file conflicts) * Decompile a class to ensure the code is running as expected. * View classloader statistics, e.g. how may classloaders are there? how many class is loaded per classloader? What is the classloader hierarchy? Is there possible classloader leaks? * View the method invocation details, e.g. method parameter, return object, thrown exception, and etc. @@ -307,4 +307,4 @@ $ classloader * [greys-anatomy](https://github.com/oldmanpushcart/greys-anatomy): The Arthas code base has derived from Greys, we thank for the excellent work done by Greys. * [termd](https://github.com/termd/termd): Arthas's termnial implementation is based on termd, an open source library for writing terminal applications in Java. * [crash](https://github.com/crashub/crash): Arthas's text based user interface rendering is based on codes extracted from [here](https://github.com/crashub/crash/tree/1.3.2/shell) -* [cli](https://github.com/eclipse-vertx/vert.x/tree/master/src/main/java/io/vertx/core/cli): Arthas's command line interface implementation is based on cli, open sourced by vert.x \ No newline at end of file +* [cli](https://github.com/eclipse-vertx/vert.x/tree/master/src/main/java/io/vertx/core/cli): Arthas's command line interface implementation is based on cli, open sourced by vert.x From f70e0626f3dde0038291123615462dec8604704b Mon Sep 17 00:00:00 2001 From: Hearen Date: Sun, 23 Sep 2018 21:22:38 +0800 Subject: [PATCH 16/46] manual-install en --- site/src/site/sphinx/en/manual-install.md | 31 +++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 site/src/site/sphinx/en/manual-install.md diff --git a/site/src/site/sphinx/en/manual-install.md b/site/src/site/sphinx/en/manual-install.md new file mode 100644 index 000000000..a755d4ef1 --- /dev/null +++ b/site/src/site/sphinx/en/manual-install.md @@ -0,0 +1,31 @@ +Manual Installation +=================== + +### Download + +Latest `bin.zip `: [![Arthas](https://img.shields.io/maven-central/v/com.taobao.arthas/arthas-packaging.svg?style=flat-square "Arthas")](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) + + +If the downloading is rather clumsy, try to download from the [repository in AliYun](https://maven.aliyun.com/); the downloading URL template is (remember to fill up the version `3.x.x` template to your needs) + +`https://maven.aliyun.com/repository/public/com/taobao/arthas/arthas-packaging/3.x.x/arthas-packaging-3.x.x-bin.zip` +### Unzip + +```bash +unzip arthas-packaging-bin.zip +``` + +### Install + +```bash +sudo su admin +rm -rf /home/admin/.arthas/lib/* # remove all the leftover of the old outdated Arthas +cd arthas +./install-local.sh # switch the user based on the owner of the target Java process. +``` + +### Start + +```bash +./as.sh # make sure the old Arthas has been shut down (using command shutdown); +``` From 76eca52834dc7313c21b1781e4ecfa621ed77bb2 Mon Sep 17 00:00:00 2001 From: Hearen Date: Sun, 23 Sep 2018 21:47:40 +0800 Subject: [PATCH 17/46] advice-class en --- site/src/site/sphinx/en/advice-class.md | 44 +++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 site/src/site/sphinx/en/advice-class.md diff --git a/site/src/site/sphinx/en/advice-class.md b/site/src/site/sphinx/en/advice-class.md new file mode 100644 index 000000000..479f93055 --- /dev/null +++ b/site/src/site/sphinx/en/advice-class.md @@ -0,0 +1,44 @@ +Critical Fields in Expressions +============================== + +There is a very fundamental class `Advice` for the expressions used in filtering, tracing or monitoring and other aspects in commands. + +```java +public class Advice { + + private final ClassLoader loader; + private final Class clazz; + private final ArthasMethod method; + private final Object target; + private final Object[] params; + private final Object returnObj; + private final Throwable throwExp; + private final boolean isBefore; + private final boolean isThrow; + private final boolean isReturn; + ... + // getter/setter +} +``` + +|Name|Specification| +|---:|:---| +|loader|class loader of the class| +|clazz|the reference of the class| +|method|the reflective reference of the method| +|target|the instance of the class| +|params|the parameters of the method, which is an array (when there is no argument in the method, it will be an empty array)| +|returnObj|the return value of the method - only when `isReturn==true`, it's a valid result but if the return value is `void` then it will be a `null`| +|throwExp|the exceptions thrown by the method invoking - only when `isThrow==true`, it's a valid thrown exception| +|isBefore|assistant checking flag used in [`before-watching` point](watch.md) and at this very moment: `isBefore==true`, `isThrow==false` and `isReturn==false` since it's before we invoke the method| +|isThrow|assistant checking flag: whether the current method invoking ends with exceptions| +|isReturn|assistant checking flag: whether the method invoking exits normally without exceptions| + +F.Y.I +1. all the *fields* mentioned in the table above can be used directly in the `expressions`; +2. if the expressions are [invalid OGNL](https://en.wikipedia.org/wiki/OGNL), the command will be cancelled automatically with hints to correct the expressions; +3. [typical use cases](https://github.com/alibaba/arthas/issues/71); +4. [OGNL official usage guide](https://commons.apache.org/proper/commons-ognl/language-guide.html). + + + From 3fcbad51640e9497629654b26ceb58bdd946c9b7 Mon Sep 17 00:00:00 2001 From: Alexander Minderov Date: Sun, 23 Sep 2018 23:18:38 -0700 Subject: [PATCH 18/46] Improve grammar in README.md --- README.md | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/README.md b/README.md index 94e451e4e..5169a56b6 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,19 @@ ![arthas](site/src/site/sphinx/arthas.png) -`Arthas` is an Java Diagnostic tool open sourced by Alibaba. +`Arthas` is a Java Diagnostic tool open sourced by Alibaba. -Arthas can help developer trouble-shooting production issues for Java applications without modifying your code or restating your server. +Arthas can help developer trouble-shoot production issues for Java applications without modifying your code or restarting your server. [中文说明](README_CN.md) (For Chinese Documentation) ### Background -In production system, sometimes the networks is unreachable from local development environment. If you encounter some issues in production system, it is impossible to use IDE to debug the application remotely. More importantly, debugging in production is unacceptable, because it will suspend all the threads, which leads to business unavailability. +In production system, sometimes the network is unreachable from local development environment. If you encounter some issues in production system, it is impossible to use IDE to debug the application remotely. More importantly, debugging in production is unacceptable, because it will suspend all the threads, which leads to business unavailability. -Some may think of reproducing the same issue on the test/staging environment, however, some tricky issues either can hardly be reproduced on a different environment, or even disappear once restarted. +Some may think of reproducing the same issue on the test/staging environment. However, some tricky issues either can hardly be reproduced on a different environment, or even disappear once restarted. -Thinking of adding some logs to your code? You have to go through test, staging, and then on to production. Time is money! That is a lot inefficient! Besides, the issue may not be reproducible once you restart your JVM, as described above. +Thinking of adding some logs to your code? You have to go through test, staging, and then on to production. Time is money! That is very inefficient! Besides, the issue may not be reproducible once you restart your JVM, as described above. Arthas is born to solve these issues. You can trouble-shoot your production issue on-the-fly. No need for JVM restart, no additional code changes. Arthas works as an observer, which will never suspend your existing threads. @@ -22,13 +22,13 @@ Arthas is born to solve these issues. You can trouble-shoot your production issu * Check whether a class is loaded? And where the class is loaded from? (Useful for trouble-shooting jar file conflicts) * Decompile a class to ensure the code is running as expected. -* View classloader statistics, e.g. how may classloaders are there? how many class is loaded per classloader? What is the classloader hierarchy? Is there possible classloader leaks? +* View classloader statistics, e.g. how may classloaders are there? How many classes are loaded per classloader? What is the classloader hierarchy? Are there possible classloader leaks? * View the method invocation details, e.g. method parameter, return object, thrown exception, and etc. -* Check the stack trace of specified method invocation. This is useful when you would like to know who is calling your method? +* Check the stack trace of specified method invocation. This is useful when you would like to know who is calling your method. * Trace the method invocation to find slow sub-invocations. -* Monitor method invcation statistics, e.g. qps, rt, success rate and etc. -* Monitoring your system metrics, thread states and cpu usage, gc statistics, and etc. -* Support command line interactive mode, with auto completed feature enabled. +* Monitor method invcation statistics, e.g. qps, rt, success rate, etc. +* Monitoring your system metrics, thread states and cpu usage, gc statistics, etc. +* Support command line interactive mode, with auto complete feature enabled. * Support telnet and websocket, which enables both local and remote diagnostics with command line and browsers. ### Quick start @@ -49,10 +49,10 @@ Start Arthas: #### Windows -1. Click [here](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) to Download the latest binary releases. +1. Click [here](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) to download the latest binary releases. 2. Unzip the file. 3. Go to the bin directory -4. run the following command `as.bat $PID` +4. Run the following command `as.bat $PID` ### Documentation @@ -77,7 +77,7 @@ English version is on the way, if you would like to contribute, please leave a m #### Thread -See who is eating your cpu (ranked by top cpu usage) and what is going on there in one glance: +See what is eating your cpu (ranked by top cpu usage) and what is going on there in one glance: ``` $ thread -n 3 @@ -218,7 +218,7 @@ ts=2018-09-18 10:11:45;thread_name=http-bio-8080-exec-10;id=d9;is_daemon=true;pr #### Trace -See who is slowing down your method invocation with trace command: +See what is slowing down your method invocation with trace command: ![trace](site/src/site/sphinx/_static/trace.png) @@ -259,7 +259,7 @@ Affect(class-cnt:1 , method-cnt:1) cost in 109 ms. #### Time Tunnel(tt) -Recording method invocation data, so that you can check the method invacation parameters, returned value and thrown exception later. It works as if you could come back and replay the past method invacation via time tunnel. +Record method invocation data, so that you can check the method invacation parameters, returned value and thrown exception later. It works as if you could come back and replay the past method invocation via time tunnel. ``` $ tt -t org.apache.dubbo.demo.provider.DemoServiceImpl sayHello @@ -305,6 +305,6 @@ $ classloader ### Credit * [greys-anatomy](https://github.com/oldmanpushcart/greys-anatomy): The Arthas code base has derived from Greys, we thank for the excellent work done by Greys. -* [termd](https://github.com/termd/termd): Arthas's termnial implementation is based on termd, an open source library for writing terminal applications in Java. +* [termd](https://github.com/termd/termd): Arthas's terminal implementation is based on termd, an open source library for writing terminal applications in Java. * [crash](https://github.com/crashub/crash): Arthas's text based user interface rendering is based on codes extracted from [here](https://github.com/crashub/crash/tree/1.3.2/shell) * [cli](https://github.com/eclipse-vertx/vert.x/tree/master/src/main/java/io/vertx/core/cli): Arthas's command line interface implementation is based on cli, open sourced by vert.x From d091cdd74238d5603fc344f9dd83f5241691c02e Mon Sep 17 00:00:00 2001 From: Hearen Date: Mon, 24 Sep 2018 20:44:50 +0800 Subject: [PATCH 19/46] improve the descriptions and fix some typos for the English documentation --- site/src/site/sphinx/en/classloader.md | 14 ++++++------ site/src/site/sphinx/en/commands.md | 25 +++++++++++---------- site/src/site/sphinx/en/dump.md | 8 +++---- site/src/site/sphinx/en/index.md | 2 +- site/src/site/sphinx/en/jad.md | 14 +++++++----- site/src/site/sphinx/en/monitor.md | 14 ++++++------ site/src/site/sphinx/en/options.md | 6 +++--- site/src/site/sphinx/en/redefine.md | 8 +++---- site/src/site/sphinx/en/sc.md | 6 +++--- site/src/site/sphinx/en/sm.md | 4 ++-- site/src/site/sphinx/en/stack.md | 16 +++++++------- site/src/site/sphinx/en/trace.md | 15 ++++++------- site/src/site/sphinx/en/tt.md | 22 +++++++++---------- site/src/site/sphinx/en/watch.md | 30 +++++++++++++------------- 14 files changed, 95 insertions(+), 89 deletions(-) diff --git a/site/src/site/sphinx/en/classloader.md b/site/src/site/sphinx/en/classloader.md index bfa14936a..913f9d4de 100644 --- a/site/src/site/sphinx/en/classloader.md +++ b/site/src/site/sphinx/en/classloader.md @@ -9,17 +9,17 @@ It can be a great help for `ResourceNotFoundException` when you can use command |Name|Specification| |---:|:---| -|[l]|count based on the class loader instance| -|[t]|print all the inheritance structure of the class loaders| +|[l]|list all class loader instances based on thread count| +|[t]|print the inheritance structure of the class loaders| |[a]|list all the classes loaded by all the class loaders (use it with great caution since the output can be huge)| -|`[c:]`|get the hashcode of the class loader| -|`[c: r:]`|using class loader to search resource| +|[c:]|get the hashcode of the class loader| +|[c: r:]|using class loader to search resource| ### Usage -* categorised by class loader +* Categorised by class loader -```s +```sh $ classloader name numberOfInstances loadedCountTotal com.taobao.pandora.service.loader.ModuleClassLoader 29 11659 @@ -100,7 +100,7 @@ $ classloader -t | | +-sun.reflect.DelegatingClassLoader@73f44f24 ``` -* Check the real urls of `URLClassLoader` +* Check URL of the class loader ```shell $ classloader -c 5ffe9775 diff --git a/site/src/site/sphinx/en/commands.md b/site/src/site/sphinx/en/commands.md index f103f7b14..d5c1e664d 100644 --- a/site/src/site/sphinx/en/commands.md +++ b/site/src/site/sphinx/en/commands.md @@ -1,6 +1,19 @@ -Commands List +All Commands ============= +### Basic + +* help - check the assistant info for the command +* cls - clear out the current screen area +* session - check the current session profile +* [reset](reset.md) - clear the injected code from the classes (B.T.W when Arthas server closed, all the injected will also be cleared) +* version - the version of the working Arthas +* quit - exit the current Arthas client without affecting other clients +* shutdown - terminate the Arthas server and all clients +* [keymap](keymap.md) - shortcuts for Arthas and also you can define your own + + +### Advanced * [dashboard](dashboard.md) * [thread](thread.md) * [jvm](jvm.md) @@ -25,13 +38,3 @@ Commands List * [options](options.md) -### Arthas Basic Commands - -* help - check the assistant info for the command -* cls - clear out the current screen area -* session - check the current session profile -* [reset](reset.md) - clear the injected code from the classes (B.T.W when Arthas server closed, all the injected will also be cleared) -* version - the version of the working Arthas -* quit - exit the current Arthas client without affecting other clients -* shutdown - terminate the Arthas server and all clients -* [keymap](keymap.md) - shortcuts for Arthas and also you can define your own diff --git a/site/src/site/sphinx/en/dump.md b/site/src/site/sphinx/en/dump.md index ac3089c59..c0e157f23 100644 --- a/site/src/site/sphinx/en/dump.md +++ b/site/src/site/sphinx/en/dump.md @@ -8,13 +8,13 @@ Dump the bytecode the loaded classes to a specified directory. |Name|Specification| |---:|:---| |*class-pattern*|pattern for the class name| -|`[c:]`|hashcode of the class loader that loaded the class| -|[E]|turn on regx matching while the default is wildcards matching| +|[c:]|hashcode of the [class loader](classloader.md) that loaded the class| +|[E]|turn on regex matching while the default is wildcard matching| ### Usage -```shell -$ dump -E org\.apache\.commons\.lang\.StringUtils +```bash +$ dump org.apache.commons.lang.StringUtils HASHCODE CLASSLOADER LOCATION 29505d69 +-tddl-client's ModuleClassLoader /Users/zhuyong/middleware/taobao-tomcat/output/build/bin/classdump/com.taobao.pandora .service.loader.ModuleClassLoader-29505d69/org.apache.commons.lang.StringUtils.class diff --git a/site/src/site/sphinx/en/index.md b/site/src/site/sphinx/en/index.md index 173020577..b604a9131 100644 --- a/site/src/site/sphinx/en/index.md +++ b/site/src/site/sphinx/en/index.md @@ -36,7 +36,7 @@ Arthas is born to solve these issues. You can trouble-shoot your production issu Contents -------- -English version is on the way, if you would like to contribute, please leave a message [here](https://github.com/alibaba/arthas/issues/51) +English version has just been finished. If you would like to make it better, please check [here](https://github.com/alibaba/arthas/issues/51) and submit your PM. * [Installation](install-detail.md) * [Quick start](quick-start.md) diff --git a/site/src/site/sphinx/en/jad.md b/site/src/site/sphinx/en/jad.md index 31c146015..6aa6fc6af 100644 --- a/site/src/site/sphinx/en/jad.md +++ b/site/src/site/sphinx/en/jad.md @@ -6,22 +6,22 @@ De-compile specified loaded classes. `jad` helps to *de-compile* the byte code in JVM to the source code to assist you to better understand the logic behind. F.Y.I -* the de-compiled code will be grammatically highlighted for readability in Arthas Console; -* you have to understand there might be some trivial grammar errors but it won't affect the logic understanding. +* the de-compiled code will be grammatically highlighted for readability in Arthas console; +* there might be some trivial grammar errors but it won't affect the logic understanding. ### Options |Name|Specification| |---:|:---| |*class-pattern*|pattern for the class name| -|`[c:]`|hashcode of the class loader that loaded the class| -|[E]|turn on regx matching while the default is wildcards matching| +|[c:]|hashcode of the class loader that loaded the class| +|[E]|turn on regex matching while the default is wildcard matching| ### Usage When several class loaders loaded the same class: 1. `jad` to get the hashcode of the class loader; -2. `jad -c ` to get the de-compiled class loaded by the class loader. +2. `jad -c ` to get the de-compiled class loaded by the specified class loader. ```java $ jad org.apache.log4j.Logger @@ -156,3 +156,7 @@ private Map directMetrics(String ip, String[] metrics) { Affect(row-cnt:1) cost in 1508 ms. ``` + +F.Y.I + +Inner class is not yet supported, you can just check the *outer* class to further check the inner class. diff --git a/site/src/site/sphinx/en/monitor.md b/site/src/site/sphinx/en/monitor.md index 37dbc1551..d77b4b64f 100644 --- a/site/src/site/sphinx/en/monitor.md +++ b/site/src/site/sphinx/en/monitor.md @@ -1,14 +1,14 @@ monitor ======= -Monitor the `class-pattern` & `method-pattern` matched methods invoking traces. +Monitor methods calling stack traces. F.Y.I -1. `monitor` is a persistent command, it never returns until `Ctrl+C` to manually stop it. -2. the server runs the tasks in the background; -3. injected code will become invalid automatically once the tasks being terminated; -4. in theory, Arthas commands will not change any original behaviors. +1. `monitor` is a persistent command, it never returns until you press `Ctrl+C` to manually stop it; +2. the server runs the jobs in the background; +3. injected monitoring code will become invalid automatically once the monitoring jobs being terminated; +4. in theory, Arthas will not change any original behaviors but if it does, please do not hesitate to start an [issue](https://github.com/alibaba/arthas/issues). ### Properties monitored @@ -29,8 +29,8 @@ F.Y.I |---:|:---| |*class-pattern*|pattern for the class name| |*method-pattern*|pattern for the method name| -|[E]|turn on regx matching while the default is wildcards matching| -|`[c:]`|cycle of output with default value: `120 s`| +|[E]|turn on regex matching while the default is wildcard matching| +|[c:]|cycle of output with default value: `60 s`| ### Usage diff --git a/site/src/site/sphinx/en/options.md b/site/src/site/sphinx/en/options.md index 023d81948..51bd2efb2 100644 --- a/site/src/site/sphinx/en/options.md +++ b/site/src/site/sphinx/en/options.md @@ -1,12 +1,12 @@ options === -> Global options +### Global options -|   Name   | Default Value | Description | +|Name| Default Value | Description | | ------------------------- | ----- | ---------------------------------------- | | unsafe | false | Enable system-level class enhancement; JVM might crash, if you turn it on (use with great caution :exclamation:) | -| dump | false | Enable support for dumping enhanced class to external file; if turned on, class file will be dumped to`/${application dir}/arthas-class-dump/`,please check console output for specific location | +| dump | false | Enable support for dumping enhanced class to external files; if turned on, class file will be dumped to`/${application dir}/arthas-class-dump/`,please check console output for specific location | | batch-re-transform | true | re-transform matched classes in batch | | json-format | false | Enable output in JSON format | | disable-sub-class | false | Disabling child class matching: by default child class will be matched while matching target class; if you wish exact matching, you should turn it off | diff --git a/site/src/site/sphinx/en/redefine.md b/site/src/site/sphinx/en/redefine.md index 4ce2af248..fdb2c6a85 100644 --- a/site/src/site/sphinx/en/redefine.md +++ b/site/src/site/sphinx/en/redefine.md @@ -1,14 +1,14 @@ redefine ======== -Load the external `*.class` files and *re-define* the JVM-loaded classes. +Load the external `*.class` files to **re-define** the JVM-loaded classes. Reference: [Instrumentation#redefineClasses](https://docs.oracle.com/javase/8/docs/api/java/lang/instrument/Instrumentation.html#redefineClasses-java.lang.instrument.ClassDefinition...-) F.Y.I 1. Re-defined classes cannot be restores any more; -2. Re-definition can fail (like adding a new field); for more information, please refer to JDK documentation +2. Re-definition can fail (like adding a new field/method); for more information, please refer to JDK documentation ### Options @@ -21,6 +21,6 @@ F.Y.I ### Usage ``` - redefine -p /tmp/Test.class - redefine -c 327a647b -p /tmp/Test.class /tmp/Test\$Inner.class +redefine -p /tmp/Test.class +redefine -c 327a647b -p /tmp/Test.class /tmp/Test$Inner.class ``` diff --git a/site/src/site/sphinx/en/sc.md b/site/src/site/sphinx/en/sc.md index 23eb6af1d..6aaabebdc 100644 --- a/site/src/site/sphinx/en/sc.md +++ b/site/src/site/sphinx/en/sc.md @@ -3,7 +3,7 @@ sc Check the profiles of the loaded classes. -Abbreviated from “Search-Class”; with the help of this command, you can search out all the loaded classes in JVM. Supported options are: `[d]`、`[E]`、`[f]` and `[x:]`. +Abbreviated from *Search-Class*; with the help of this command, you can search out all the loaded classes in JVM. Supported options are: `[d]`、`[E]`、`[f]` and `[x:]`. Options ------- @@ -16,12 +16,12 @@ Options |*method-pattern*|pattern for the method name| |[d]|print the details of the current class including the source file, class declaration, the class loaders and the like.
F.Y.I if a class is loaded by several class loaders, then the class will be printed several times| |[E]|turn on regx matching while the default is wildcards matching| -|[f]|print the fields info of the current class, which should be used along with `-d`| +|[f]|print the fields info of the current class, which ***must*** be used with `-d`| |[x:]|the depth to print the static fields, whose default is `0` - directly invoke the `toString()`| Tip: 1. *class-patten* supports full qualified class name (e.g. com.taobao.test.AAA and com/taobao/test/AAA) -2. `sc` turned on the `sub-class` matching in default mode, if you do want to hide the `sub-class` please just turn it off via `options disable-sub-class true`. +2. `sc` turned on the `sub-class` matching in default mode; if you do want to hide `sub-class`, you can just turn it off with [options](options.md) as `options disable-sub-class true`. ### Usage diff --git a/site/src/site/sphinx/en/sm.md b/site/src/site/sphinx/en/sm.md index 3f0496cee..062a32018 100644 --- a/site/src/site/sphinx/en/sm.md +++ b/site/src/site/sphinx/en/sm.md @@ -3,7 +3,7 @@ sm Check the method profile of the loaded classes; -Abbreviated from “Search-Method”, with which you can search out all methods profiles of the loaded classes. +Abbreviated from *Search-Method*, with which you can check all methods profiles of the loaded classes. F.Y.I `sm` only shows the methods declared in the current class; methods declared in ancestors will not be presented. @@ -15,7 +15,7 @@ F.Y.I |*class-pattern*|pattern for class name| |*method-pattern*|pattern for method name| |[d]|print the details of the method| -|[E]|turn the regex matching on while the default mode is wildcards matching| +|[E]|turn on regex matching while the default mode is wildcard matching| ### Usage diff --git a/site/src/site/sphinx/en/stack.md b/site/src/site/sphinx/en/stack.md index bfc5243a2..6b373341d 100644 --- a/site/src/site/sphinx/en/stack.md +++ b/site/src/site/sphinx/en/stack.md @@ -11,16 +11,16 @@ Most of the time, we know the method being invoked but not always we know **HOW |---:|:---| |*class-pattern*|pattern for the class name| |*method-pattern*|pattern for the method name| -|*condition-express*|condition expression| -|[E]|turn on regx matching while the default is wildcards matching| -|`[n:]`|calling times| +|*condition-expression*|condition expression| +|[E]|turn on regex matching while the default is wildcard matching| +|[n:]|calling times| F.Y.I 1. any valid OGNL expression as `"{params,returnObj}"` supported; -2. filter by time cost as `trace *StringUtils isBlank '$cost>100'`; calling stack with only time cost higher than `100ms` will be printed. +2. filter by time cost as `trace *StringUtils isBlank '#cost>100'`; calling stack with only time cost higher than `100ms` will be printed. Attention: -1. `$cost` can be used in `watch/stack/trace`; +1. `#cost` can be used in `watch/stack/trace`; 2. using `#cost` in Arthas 3.0 instead of `$cost`. @@ -32,7 +32,7 @@ Advanced: ### Usage -The quoting rules: if there are quotes within the expression, use another type of quotes to quote the whole expression. +The quoting rules: if there are quotes within the expression, use another type of quotes to quote the whole expression (single `''` or double `""` quotes). ``` $ stack com.alibaba.sample.petstore.dal.dao.ProductDao getProductById 'params[0]=="K9-BD-01"' @@ -68,7 +68,7 @@ thread_name="http-bio-8080-exec-2" thread_id=0x48;is_daemon=true;priority=5; at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invoke(PipelineImpl.java:210) at com.alibaba.citrus.service.pipeline.impl.valve.ChooseValve.invoke(ChooseValve.java:98) at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157) -...... +... ``` Filtering by time cost: @@ -110,5 +110,5 @@ thread_name=http-nio-8080-exec-10;id=31;is_daemon=true;priority=5;TCCL=com.taoba at com.alibaba.citrus.webx.impl.WebxControllerImpl.service(WebxControllerImpl.java:43) at com.alibaba.citrus.webx.impl.WebxRootControllerImpl.handleRequest(WebxRootControllerImpl.java:53) at com.alibaba.citrus.webx.support.AbstractWebxRootController.service(AbstractWebxRootController.java:165) -......... +... ``` diff --git a/site/src/site/sphinx/en/trace.md b/site/src/site/sphinx/en/trace.md index cb25cd2f6..6f94628f7 100644 --- a/site/src/site/sphinx/en/trace.md +++ b/site/src/site/sphinx/en/trace.md @@ -1,7 +1,7 @@ trace ===== -Track the `class-pattern` & `method-pattern` matched method calling trace and print the time cost in each call. +Track methods calling stack trace and print the time cost in each call. ### Parameters @@ -11,19 +11,18 @@ Track the `class-pattern` & `method-pattern` matched method calling trace and pr |*method-pattern*|pattern for the method name| |*condition-express*|condition expression| |[E]|turn on regx matching while the default is wildcards matching| -|`[n:]`|calling times| -|`#cost`|time cost| +|[n:]|calling times| +|#cost|time cost| F.Y.I 1. any valid OGNL expression as `"{params,returnObj}"` supported; -2. filter by time cost as `trace *StringUtils isBlank '$cost>100'`; calling stack with only time cost higher than `100ms` will be printed. +2. filter by time cost as `trace *StringUtils isBlank '#cost>100'`; calling stack with only time cost higher than `100ms` will be printed. Attention: -1. `$cost` can be used in `watch/stack/trace`; +1. `#cost` can be used in `watch/stack/trace`; 2. using `#cost` in Arthas 3.0 instead of `$cost`. 3. `trace` can help to locate the performance lurking issue but only `level-one` method invoking considered. - Advanced: * [Critical fields in expression](advice-class.md) * [Special usage](https://github.com/alibaba/arthas/issues/71) @@ -101,8 +100,8 @@ trace com.alibaba.sample.petstore.web.store.module.screen.ItemList execute #cost Only the calling trace of the time cost higher than `4ms`presented now. F.Y.I -1. just like JProfile and the like commercial software, you can `trace` down the specified method calling in Arthas; +1. like JProfile and other similar commercial software, you can `trace` down the specified method calling stack with time cost in Arthas; 2. there will be some overhead using `trace` but not much; -3. the time cost is an instructive clue for troubleshooting, which means it's not that accurate ignoring the cost it itself causes; the deeper or more the call is, the accuracy is becoming worse; +3. the time cost is an instructive clue for troubleshooting, which means it's not that accurate ignoring the cost it itself causes; the deeper or more the call is, the worse accuracy the time cost will be; 4. `[0,0,0ms,11]xxx:yyy() [throws Exception]`,the same method calling aggregated into one line here while `throws Exception` indicates there is an exception. diff --git a/site/src/site/sphinx/en/tt.md b/site/src/site/sphinx/en/tt.md index f1cca71f8..b0a134d73 100644 --- a/site/src/site/sphinx/en/tt.md +++ b/site/src/site/sphinx/en/tt.md @@ -1,13 +1,13 @@ tt == -Check the parameters, return values and exceptions of the methods at different times. +Check the `parameters`, `return values` and `exceptions` of the methods at different times. `watch` is a powerful command but due to its feasibility and complexity, it's quite hard to locate the issue effectively. In such difficulties, `tt` comes into play. -With the help of `tt` (abbreviated from *TimeTunnel*), you can check the contexts of the methods at different times. +With the help of `tt` (*TimeTunnel*), you can check the contexts of the methods at different times in execution history. ### Usage @@ -37,7 +37,7 @@ Let's record the whole calling contexts: - `-n 3` - limit the number of the records (avoid overflow for too many records; with `-n` option, Arthas can automatically stop recording once the records reach the limit) + limit the number of the records (avoid overflow for too many records; with `-n` option, Arthas can automatically stop recording once the records reach the specified limit) #### Property @@ -46,8 +46,8 @@ Let's record the whole calling contexts: |INDEX|the index for each call based on time| |TIMESTAMP|time to invoke the method| |COST(ms)|time cost of the method call| -|IS-RET|end with normal return| -|IS-EXP|end with exceptions| +|IS-RET|whether method exits with normal return| +|IS-EXP|whether method failed with exceptions| |OBJECT|`hashCode()` of the object invoking the method| |CLASS|class name of the object invoking the method| |METHOD|method being invoked| @@ -55,7 +55,7 @@ Let's record the whole calling contexts: #### Condition expression Tips: -1. `tt -t *Test print params[0].length==1` with different amount of parameters; +1. `tt -t *Test print params[0].length==1` with different amounts of parameters; 2. `tt -t *Test print 'params[1] instanceof Integer'` with different types of parameters; 3. `tt -t *Test print params[0].mobile=="13989838402"` with specified parameter. @@ -67,7 +67,7 @@ Advanced: ### Searching for records -#### A specified time range +#### All the recorded ``` $ tt -l @@ -147,7 +147,7 @@ $ ### Re-produce -Since Arthas stores the context of the call, you can even re-produce the method calling after some modifications with extra option `-p`. +Since Arthas stores the context of the call, you can even *replay* the method calling afterwards with extra option `-p` to re-produce the issue for advanced troubleshooting. ``` $ tt -i 1003 -p @@ -189,6 +189,6 @@ $ ``` F.Y.I -1. the calling stack is little different using Arthas now instead of the original method; -2. **Loss** of the thread local variables will be a fact since there is no way for Arthas to record the thread local info. -3. **Potential** modifications of objects can happen since only a reference will be recorded by Arthas while later process might modify objects without Arthas's watch. +1. the calling stack is little different using Arthas now unlike the original; +2. **Loss** of the thread local variables will be a undeniable fact since there is no way for Arthas to record the thread local info (*If you find one, please share with us in [issues tracker](https://github.com/alibaba/arthas/issues)*). +3. **Potential** modifications of objects can happen since only a reference will be recorded while later operations might modify objects without Arthas's watch. diff --git a/site/src/site/sphinx/en/watch.md b/site/src/site/sphinx/en/watch.md index 95d88cccc..97150a34c 100644 --- a/site/src/site/sphinx/en/watch.md +++ b/site/src/site/sphinx/en/watch.md @@ -3,31 +3,31 @@ watch Monitor methods in data aspect including `return values`, `exceptions` and `parameters`. -With the help of [OGNL](https://en.wikipedia.org/wiki/OGNL), you can easily check the details of variables. +With the help of [OGNL](https://en.wikipedia.org/wiki/OGNL), you can easily check the details of variables when methods being invoked. ### Parameters & Options -There are four different scenarios for `watch` command, which makes it a rather complicated command in Arthas. +There are four different scenarios for `watch` command, which makes it rather complicated. |Name|Specification| |---:|:---| |*class-pattern*|pattern for the class name| |*method-pattern*|pattern for the method name| -|*express*|expression to monitor| -|*condition-express*|condition expression to filter| +|*expression*|expression to monitor| +|*condition-expression*|condition expression to filter| |[b]|before method being invoked| -|[e]|encountering exceptions| -|[s]|returned normally| -|[f]|returned normally and abnormally| -|[E]|turn on regex matching while the default is wildcards matching| +|[e]|when method encountering exceptions| +|[s]|when method exits normally| +|[f]|when method exits (either succeed or fail with exceptions)| +|[E]|turn on regex matching while the default is wildcard matching| |[x:]|the depth to print the specified property with default value: 1| F.Y.I 1. any valid OGNL expression as `"{params,returnObj}"` supported 2. there are four *watching* points: `-b`, `-e`, `-s` and `-f` (the first three are off in default while `-f` on); 3. at the *watching* point, Arthas will use the *expression* to evaluate the variables and print them out; -4. `in-parameters` and `out-parameters` are different since they can be modified within the invoked methods; `params` stands for `in-parameters` in `-b`while `out-parameters` in other *watching* points; -5. there is no `return values` and `exceptions` when using `-b`. +4. `in parameters` and `out parameters` are different since they can be modified within the invoked methods; `params` stands for `in parameters` in `-b`while `out parameters` in other *watching* points; +5. there are no `return values` and `exceptions` when using `-b`. Advanced: @@ -57,7 +57,7 @@ A demo: return list.size(); } ``` -#### Check the `out-parameters` and `return value` +#### Check the `out parameters` and `return value` ```shell $ watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "{params,returnObj}" -x 2 @@ -73,7 +73,7 @@ Affect(class-cnt:1 , method-cnt:1) cost in 44 ms. ] ``` -#### Check `in-parameters` +#### Check `in parameters` ```shell $ watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "{params,returnObj}" -x 2 -b @@ -89,7 +89,7 @@ Affect(class-cnt:1 , method-cnt:1) cost in 48 ms. ] ``` -Compared to the previous *check*: +Compared to the previous *check*, there are two differences: 1. size of `params[0]` is `2` instead of `4`; 2. `return value` is `null` since it's `-b`. @@ -122,7 +122,7 @@ F.Y.I 1. the first block of output is the *before watching* point; 2. the order of the output determined by the *watching* order itself (nothing to do with the order of the options `-b -s`). -#### Using `-x` to check more details +#### Use `-x` to check more details ```shell $ watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "{params,returnObj}" -x 3 @@ -150,7 +150,7 @@ Affect(class-cnt:1 , method-cnt:1) cost in 59 ms. ] ``` -#### Using condition expressions to locate specific call +#### Use condition expressions to locate specific call ```shell $ watch com.alibaba.sample.petstore.biz.impl.UserManagerImpl testAdd "{params, returnObj}" "params[0].equals('aaa')" -x 2 From ea540554b1cb48a417df11342d7f13026ecf697a Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 26 Sep 2018 10:56:21 +0800 Subject: [PATCH 20/46] update en/release-notes.md. #51 --- site/src/site/sphinx/en/release-notes.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/site/src/site/sphinx/en/release-notes.md b/site/src/site/sphinx/en/release-notes.md index fffdecd9d..d835a02eb 100644 --- a/site/src/site/sphinx/en/release-notes.md +++ b/site/src/site/sphinx/en/release-notes.md @@ -1,7 +1,11 @@ Release Notes ============= -### :tada: :tada: [v3.0.4](https://github.com/alibaba/arthas/milestone/1?closed=1) :exclamation: + +v3.0.4 +--- + +* https://github.com/alibaba/arthas/milestone/1?closed=1 v2017-11-03 ---- From 55cff99e87728fa6a75bad0bd6bd61043f3795a6 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 26 Sep 2018 11:03:13 +0800 Subject: [PATCH 21/46] merge CONTRIBUTING_EN.md into CONTRIBUTING.md. #51 --- CONTRIBUTING.md | 79 ++++++++++++++++++++++++++++++++++++++++++++ CONTRIBUTING_EN.md | 81 ---------------------------------------------- 2 files changed, 79 insertions(+), 81 deletions(-) delete mode 100644 CONTRIBUTING_EN.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ceb75063c..21d7fddb7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,5 +1,84 @@ +## Issue + +Welcome to use [issue tracker](https://github.com/alibaba/arthas/issues) to give us :bowtie:: + +* feedbacks - what you would like to have; +* usage tips - what usages you have found splendid; +* experiences - how you use Arthas to do **effective** troubleshooting; + +## Documentation + +Welcome PR to further improve English [documentation](https://github.com/alibaba/arthas/tree/master/site/src/site/sphinx/en). + +## Developer + +Compilation requires JDK 7 and above since we are `java.lang.management.BufferPoolMXBean` while runtime requires JDK 6. + +### Local Installation + +Recommend to use [`as-package.sh`](as-package.sh) to package, which will auto-install the latest Arthas to local `~/.arthas` and when debugging, Arthas will auto-load the latest version. + +F.Y.I +1. when using [`as.sh`](https://github.com/alibaba/arthas/blob/master/bin/as.sh) to start Arthas, it will get the latest version under `~/.arthas/lib`; +2. when [`as-package.sh`](as-package.sh) packaging, it will get the version from `pom.xml` and suffix it with the current timestamp e.g. `3.0.5.20180917161808`. + +You can also use `./mvnw clean package -DskipTests` to package and generate a `zip` under `packaging/target/` but remember when `as.sh` starts, it load the version under `~/.arthas/lib`. + +### Start Arthas in specified version + +When there are several different version, you can use `--use-version` to specify the version of Arthas to start your debug. + +```bash +./as.sh --use-version 3.0.5.20180919185025 +``` + +Tip: you can use `--versions` to list all available versions. + +```bash +./as.sh --versions +``` + +### Debug + +There are two stages when booting Arthas: + +#### Stage 1 + +Execute `com.taobao.arthas.core.Arthas`, locate a proper JVM and attach to it. + +If you intend to debug this part, you can: + +```bash +./as.sh debug pid +``` + +The JPDA port is `8888`, you can connect to it from remote to debug; if you want to make it suspend after start, you can: + +```bash +JPDA_SUSPEND=y ./as.sh debug pid +``` + +#### Stage 2 +After attaching, Arthas agent runs inside the target process. If you want to debug agent, you have to make sure the target process is started in debug mode too. If so, then you can directly import the Arthas source code, and debug it. + +### Packaging All + +* Arthas is using [Sphinx](http://www.sphinx-doc.org/en/master/) to generate the static site +* `sphinx-maven-plugin` configured in [`site/pom.xml`](https://github.com/alibaba/arthas/tree/master/site) +* `sphinx-maven-plugin` executes by downloading`sphinx-binary/` +* a [bug](https://github.com/rtfd/recommonmark/issues/93) in Sphinx plugin `recommonmark`; we fix it by packaging another [version](https://github.com/hengyunabc/sphinx-binary/releases/tag/v0.4.0.1) +* when packaging the whole project (Packaging All), you need to (Only Unix/Linux/Mac supported): + + ```bash + ./mvnw clean package -DskipTests -P full -Dsphinx.binUrl=https://github.com/hengyunabc/sphinx-binary/releases/download/v0.4.0.1/sphinx.osx-x86_64 + ``` + + +--- + + ## issue diff --git a/CONTRIBUTING_EN.md b/CONTRIBUTING_EN.md deleted file mode 100644 index c9f95b9fc..000000000 --- a/CONTRIBUTING_EN.md +++ /dev/null @@ -1,81 +0,0 @@ - -## Issue - -Welcome to use [issue tracker](https://github.com/alibaba/arthas/issues) to give us :bowtie:: - -* feedbacks - what you would like to have; -* usage tips - what usages you have found splendid; -* experiences - how you use Arthas to do **effective** troubleshooting; - -## Documentation - - -用户文档在`site/src/site/sphinx`目录下,如果希望改进Arthas用户文档,欢迎提交PR。 - -Welcome PR to further improve English [documentation](https://github.com/alibaba/arthas/tree/master/site/src/site/sphinx/en). - -## Developer - -Compilation requires JDK 7 and above since we are `java.lang.management.BufferPoolMXBean` while runtime requires JDK 6. - -### Local Installation - -Recommend to use [`as-package.sh`](as-package.sh) to package, which will auto-install the latest Arthas to local `~/.arthas` and when debugging, Arthas will auto-load the latest version. - -F.Y.I -1. when using [`as.sh`](https://github.com/alibaba/arthas/blob/master/bin/as.sh) to start Arthas, it will get the latest version under `~/.arthas/lib`; -2. when [`as-package.sh`](as-package.sh) packaging, it will get the version from `pom.xml` and suffix it with the current timestamp e.g. `3.0.5.20180917161808`. - -You can also use `./mvnw clean package -DskipTests` to package and generate a `zip` under `packaging/target/` but remember when `as.sh` starts, it load the version under `~/.arthas/lib`. - -### Start Arthas in specified version - -When there are several different version, you can use `--use-version` to specify the version of Arthas to start your debug. - -```bash -./as.sh --use-version 3.0.5.20180919185025 -``` - -Tip: you can use `--versions` to list all available versions. - -```bash -./as.sh --versions -``` - -### Debug - -There are two stages when booting Arthas: - -#### Stage 1 - -Execute `com.taobao.arthas.core.Arthas`, locate a proper JVM and attach to it. - -If you intend to debug this part, you can: - -```bash -./as.sh debug pid -``` - -The JPDA port is `8888`, you can connect to it from remote to debug; if you want to make it suspend after start, you can: - -```bash -JPDA_SUSPEND=y ./as.sh debug pid -``` - -#### Stage 2 -After attaching, Arthas agent runs inside the target process. If you want to debug agent, you have to make sure the target process is started in debug mode too. If so, then you can directly import the Arthas source code, and debug it. - -### Packaging All - -* Arthas is using [Sphinx](http://www.sphinx-doc.org/en/master/) to generate the static site -* `sphinx-maven-plugin` configured in [`site/pom.xml`](https://github.com/alibaba/arthas/tree/master/site) -* `sphinx-maven-plugin` executes by downloading`sphinx-binary/` -* a [bug](https://github.com/rtfd/recommonmark/issues/93) in Sphinx plugin `recommonmark`; we fix it by packaging another [version](https://github.com/hengyunabc/sphinx-binary/releases/tag/v0.4.0.1) -* when packaging the whole project (Packaging All), you need to (Only Unix/Linux/Mac supported): - - ```bash - ./mvnw clean package -DskipTests -P full -Dsphinx.binUrl=https://github.com/hengyunabc/sphinx-binary/releases/download/v0.4.0.1/sphinx.osx-x86_64 - ``` - - - From e6a0f1dc20517e93d2bfb7217c7b72ffe82bf0b6 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 26 Sep 2018 11:12:59 +0800 Subject: [PATCH 22/46] update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5169a56b6..75bd061c5 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Start Arthas: #### Windows -1. Click [here](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) to download the latest binary releases. +1. Click [here](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) to download the latest binary releases of `bin.zip`. 2. Unzip the file. 3. Go to the bin directory 4. Run the following command `as.bat $PID` From 03d1e1fcd23981557081ba23dda9b513cfe2b98d Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 26 Sep 2018 15:15:57 +0800 Subject: [PATCH 23/46] fix en doc edit on github link. --- site/src/site/sphinx/_templates/breadcrumbs.html | 5 ++++- site/src/site/sphinx/en/conf.py | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/site/src/site/sphinx/_templates/breadcrumbs.html b/site/src/site/sphinx/_templates/breadcrumbs.html index cb8144835..aa4a9272f 100644 --- a/site/src/site/sphinx/_templates/breadcrumbs.html +++ b/site/src/site/sphinx/_templates/breadcrumbs.html @@ -4,4 +4,7 @@ {% set github_repo = 'arthas' %} {% set theme_vcs_pageview_mode = 'blob' %} {% set github_version = 'master' %} -{% set conf_py_path = '/site/src/site/sphinx/' %} +{% set conf_py_path = "/site/src/site/sphinx/" %} +{% if language == 'en' %} + {% set conf_py_path = "/site/src/site/sphinx/en/" %} +{% endif %} diff --git a/site/src/site/sphinx/en/conf.py b/site/src/site/sphinx/en/conf.py index 1c1cd7321..cac3ead04 100644 --- a/site/src/site/sphinx/en/conf.py +++ b/site/src/site/sphinx/en/conf.py @@ -78,7 +78,7 @@ release = version # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -# language = u'zh_CN' +language = u'en' # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: @@ -203,7 +203,7 @@ html_static_path = ['_static'] # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' -#html_search_language = 'en' +html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # Now only 'ja' uses this config value From 1d81cd7b28eef93b43871da40fc431fec091159f Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 26 Sep 2018 15:32:16 +0800 Subject: [PATCH 24/46] update README.md README_CN.md --- README.md | 2 +- README_CN.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 75bd061c5..19bc0b5ad 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Start Arthas: #### Windows -1. Click [here](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) to download the latest binary releases of `bin.zip`. +1. Click [![Arthas](https://img.shields.io/maven-central/v/com.taobao.arthas/arthas-packaging.svg "Arthas")](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) to download the latest binary releases of `bin.zip`. 2. Unzip the file. 3. Go to the bin directory 4. Run the following command `as.bat $PID` diff --git a/README_CN.md b/README_CN.md index 2b57dbeeb..35e05fd46 100644 --- a/README_CN.md +++ b/README_CN.md @@ -40,7 +40,7 @@ curl -L https://alibaba.github.io/arthas/install.sh | sh #### Windows -1. 点击 [这里](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) 下载最新的Arthas zip包 +1. 点击 [![Arthas](https://img.shields.io/maven-central/v/com.taobao.arthas/arthas-packaging.svg "Arthas")](http://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.taobao.arthas%22%20AND%20a%3A%22arthas-packaging%22) 下载最新的Arthas `bin.zip`包 2. 解压缩zip包. 3. 进入bin目录 4. 执行以下命令 `as.bat $PID` From 76640cd08803b98232b497508dd8238a5f05d4b2 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 26 Sep 2018 15:42:20 +0800 Subject: [PATCH 25/46] add en reset.md. #51 --- site/src/site/sphinx/en/advanced-use.md | 14 +++---- site/src/site/sphinx/en/reset.md | 54 +++++++++++++++++++++++++ site/src/site/sphinx/reset.md | 2 +- 3 files changed, 62 insertions(+), 8 deletions(-) create mode 100644 site/src/site/sphinx/en/reset.md diff --git a/site/src/site/sphinx/en/advanced-use.md b/site/src/site/sphinx/en/advanced-use.md index 31d413bcc..d3e8d4e75 100644 --- a/site/src/site/sphinx/en/advanced-use.md +++ b/site/src/site/sphinx/en/advanced-use.md @@ -3,13 +3,13 @@ Advanced Usage ## Basic -- help - show help info -- cls - clear out the current screen -- session - check details of the current session -- [reset](reset.md) - reset all injected/enhanced classes -- version - print the version of the Arthas attaching to the current target process -- quit/exit - exit the current Arthas client without affecting other clients -- shutdown - terminate the Arthas server and all clients +* help - show help info +* cls - clear out the current screen +* session - check details of the current session +* [reset](reset.md) - reset all injected/enhanced classes +* version - print the version of the Arthas attaching to the current target process +* quit/exit - exit the current Arthas client without affecting other clients +* shutdown - terminate the Arthas server and all clients ## JVM diff --git a/site/src/site/sphinx/en/reset.md b/site/src/site/sphinx/en/reset.md new file mode 100644 index 000000000..d32d8dc5d --- /dev/null +++ b/site/src/site/sphinx/en/reset.md @@ -0,0 +1,54 @@ +reset +=== + +> Reset all classes that have been enhanced by Arthas, and all enhanced classes will be reset when Arthas server `shutdown`. + +### Usage + +``` +$ reset -h + USAGE: + reset [-h] [-E] [class-pattern] + + SUMMARY: + Reset all the enhanced classes + + EXAMPLES: + reset + reset *List + reset -E .*List + + OPTIONS: + -h, --help this help + -E, --regex Enable regular expression to match (wildcard matching by default) + Path and classname of Pattern Matching +``` + +### Reset specified class + +``` +$ trace Test test +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 57 ms. +`---ts=2017-10-26 17:10:33;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@14dad5dc + `---[0.590102ms] Test:test() + +`---ts=2017-10-26 17:10:34;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@14dad5dc + `---[0.068692ms] Test:test() + +$ reset Test +Affect(class-cnt:1 , method-cnt:0) cost in 11 ms. +``` + +### Reset all classes + +``` +$ trace Test test +Press Ctrl+C to abort. +Affect(class-cnt:1 , method-cnt:1) cost in 15 ms. +`---ts=2017-10-26 17:12:06;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@14dad5dc + `---[0.128518ms] Test:test() + +$ reset +Affect(class-cnt:1 , method-cnt:0) cost in 9 ms. +``` \ No newline at end of file diff --git a/site/src/site/sphinx/reset.md b/site/src/site/sphinx/reset.md index 3c9b53681..ecdd1cbcc 100644 --- a/site/src/site/sphinx/reset.md +++ b/site/src/site/sphinx/reset.md @@ -1,7 +1,7 @@ reset命令 === -> 重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类 +> 重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端`shutdown`时会重置所有增强过的类 ### 使用参考 From 99f54a9cfc6252f1998836b79cd56d7e8229a206 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 26 Sep 2018 17:56:11 +0800 Subject: [PATCH 26/46] add en keymap.md. #51 --- site/src/site/sphinx/en/keymap.md | 75 +++++++++++++++++++++++++++++++ site/src/site/sphinx/keymap.md | 8 ++-- 2 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 site/src/site/sphinx/en/keymap.md diff --git a/site/src/site/sphinx/en/keymap.md b/site/src/site/sphinx/en/keymap.md new file mode 100644 index 000000000..1f2321298 --- /dev/null +++ b/site/src/site/sphinx/en/keymap.md @@ -0,0 +1,75 @@ +Arthas Console Keymap +=== + +`keymap` command print current keymap. + +The default keymap is: + + +| Shortcut | Shortcut Description | Command Name | Command Description | +| ------------- | ---------------- | -------------------- | ---------------- | +| `"\C-a"` | ctrl + a | beginning-of-line | go to the beginning of the line | +| ` "\C-e"` | ctrl + e | end-of-line | go to the end of the line| +| `"\C-f"` | ctrl + f | forward-word | forward a word | +| `"\C-b"` | ctrl + b | backward-word | backward a word | +| `"\e[D"` | left arrow | backward-char | backward a character | +| `"\e[C"` | right arrow | forward-char | forward a character | +| `"\e[B"` | down arrow | next-history | show next history command | +| `"\e[A"` | up arrow | previous-history | show previous history command | +| `"\C-h"` | ctrl + h | backward-delete-char | backward delete a character | +| `"\C-?"` | ctrl + shift + / | backward-delete-char | backward delete a character | +| `"\C-u"` | ctrl + u | undo | clear current line | +| `"\C-d"` | ctrl + d | delete-char | delete the character of the current cursor | +| `"\C-k"` | ctrl + k | kill-line | delete all characters from the current cursor to the end of the line | +| `"\C-i"` | ctrl + i | complete | Auto completion, equivalent to `TAB` | +| `"\C-j"` | ctrl + j | accept-line | end the current line, equivalent to `enter` | +| `"\C-m"` | ctrl + m | accept-line | end the current line, equivalent to `enter` | +| `"\C-w"` | | backward-delete-word | | +| `"\C-x\e[3~"` | | backward-kill-line | | +| `"\e\C-?"` | | backward-kill-word | | + + +* You can enter `Tab` to get automatic prompts at any time. +* After typing the command, type `-` or `--`, then press `tab` to display the specific options of this command. + + +#### Custom shortcuts + +Create a new `$USER_HOME/.arthas/conf/inputrc` file in the current user home directory and add a custom configuration. + +Suppose I am a heavy user of vim. I want to set `ctrl+h` to the cursor forward character. Set it as follows, first copy the default configuration. + +``` +"\C-a": beginning-of-line +"\C-e": end-of-line +"\C-f": forward-word +"\C-b": backward-word +"\e[D": backward-char +"\e[C": forward-char +"\e[B": next-history +"\e[A": previous-history +"\C-h": backward-delete-char +"\C-?": backward-delete-char +"\C-u": undo +"\C-d": delete-char +"\C-k": kill-line +"\C-i": complete +"\C-j": accept-line +"\C-m": accept-line +"\C-w": backward-delete-word +"\C-x\e[3~": backward-kill-line +"\e\C-?": backward-kill-word +``` + +Then replace `"\C-h": backward-delete-char` with `"\C-h": backward-char`, then reconnect. + +#### Shortcuts about async + +* ctrl + c: Terminate current command +* ctrl + z: Suspend the current command, you can restore this command with bg/fg, or kill it. +* ctrl + a: Go to the beginning the line +* ctrl + e: Go to the end of the line + + + + diff --git a/site/src/site/sphinx/keymap.md b/site/src/site/sphinx/keymap.md index b73cf621d..a6bc92ca1 100644 --- a/site/src/site/sphinx/keymap.md +++ b/site/src/site/sphinx/keymap.md @@ -1,7 +1,7 @@ -Arthas 3.0命令行快捷键 +Arthas 命令行快捷键 === -keymap命令输出当前的快捷键映射表: +`keymap`命令输出当前的快捷键映射表: 默认的快捷键如下: @@ -17,8 +17,8 @@ keymap命令输出当前的快捷键映射表: | `"\C-b"` | ctrl + b | backward-word | 向后移动一个单词 | | `"\e[D"` | 键盘左方向键 | backward-char | 光标向前移动一个字符 | | `"\e[C"` | 键盘右方向键 | forward-char | 光标向后移动一个字符 | -| `"\e[B"` | 键盘下方向键 | next-history | 上翻显示上一个命令 | -| `"\e[A"` | 键盘上方向键 | previous-history | 下翻显示下一个命令 | +| `"\e[B"` | 键盘下方向键 | next-history | 下翻显示下一个命令 | +| `"\e[A"` | 键盘上方向键 | previous-history | 上翻显示上一个命令 | | `"\C-h"` | ctrl + h | backward-delete-char | 向后删除一个字符 | | `"\C-?"` | ctrl + shift + / | backward-delete-char | 向后删除一个字符 | | `"\C-u"` | ctrl + u | undo | 撤销上一个命令,相当于清空当前行 | From 2702059874d62336ff39fb192cfb2d59fc3ea695 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Wed, 26 Sep 2018 18:52:24 +0800 Subject: [PATCH 27/46] add en web-console.md. #51 --- site/src/site/sphinx/en/web-console.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 site/src/site/sphinx/en/web-console.md diff --git a/site/src/site/sphinx/en/web-console.md b/site/src/site/sphinx/en/web-console.md new file mode 100644 index 000000000..98aa68465 --- /dev/null +++ b/site/src/site/sphinx/en/web-console.md @@ -0,0 +1,11 @@ +Web Console +=== + +Arthas supports the Web Console. After attach success, the user can access: [http://localhost:8563/] (http://localhost:8563/). + +The user can fill in the IP and connect the remote arthas on other machines. + +![web console](_static/web-console-local.png) + + +If you have suggestions for the Web Console, please leave a message here: [https://github.com/alibaba/arthas/issues/15](https://github.com/alibaba/arthas/issues/15) \ No newline at end of file From 3b3e2cc1a04ac2a8fa0f492158e3c5432f7b7d27 Mon Sep 17 00:00:00 2001 From: Nithyanandan Natchimuthu Date: Wed, 26 Sep 2018 21:26:42 +0530 Subject: [PATCH 28/46] Grammar and rewording for clarity Fixed grammatical errors and reworded portions of text for better clarity --- site/src/site/sphinx/en/index.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/site/src/site/sphinx/en/index.md b/site/src/site/sphinx/en/index.md index b604a9131..97265a95c 100644 --- a/site/src/site/sphinx/en/index.md +++ b/site/src/site/sphinx/en/index.md @@ -5,32 +5,32 @@ Arthas Documentation ![arthas](arthas.png) -`Arthas` is an Java Diagnostic tool open sourced by Alibaba. +`Arthas` is a Java Diagnostic tool open sourced by Alibaba. -Arthas can help developer trouble-shooting production issues for Java applications without modifying your code or restating your server. +Arthas help developers in trouble-shooting production issues for Java applications without modifying code or restarting servers. ### Background -In production system, sometimes the networks is unreachable from local development environment. If you encounter some issues in production system, it is impossible to use IDE to debug the application remotely. More importantly, debugging in production is unacceptable, because it will suspend all the threads, which leads to business unavailability. +Often times, the production system network is inaccessible from local development environment. If issues are encountered in production systems, it is impossible to use IDE to debug the application remotely. More importantly, debugging in production environment is unacceptable, as it will suspend all the threads, which leads to blocking of business services. -Some may think of reproducing the same issue on the test/staging environment, however, some tricky issue either can hardly be reproduced on a different environment, or even disappeared once restarted. +Developers could always try to reproduce the same issue on the test/staging environment. However, this is tricky as some issues cannot be be reproduced easily on a different environment, or even disappear once restarted. -Thinking of adding some logs to your code? You have to go through test, staging, and then on to production. Time is money! That is a lot inefficient! Besides, the issue may not be reproducible once restart your JVM, as described above. +And if you're thinking of adding some logs to your code to help trouble-shoot the issue, you will have to go through the following lifecycle; test, staging, and then to production. Time is money! This approach is inefficient! Besides, the issue may not be reproducible once the JVM is restarted, as described above. -Arthas is born to solve these issues. You can trouble-shoot your production issue on-the-fly. No JVM restart, no additional code changes. Arthas works as an observer, which will never suspend your existing threads. +Arthas was built to solve these issues. A developer can trouble-shoot your production issues on-the-fly. No JVM restart, no additional code changes. Arthas works as an observer, which will never suspend your existing threads. ### Key features -* Check whether a class is loaded? And whether is class loaded from? (Useful for trouble-shooting jar file conflicts) +* Check whether a class is loaded? Or where the class is loaded from? (Useful for trouble-shooting jar file conflicts) * Decompile a class to ensure the code is running as expected. -* View classloader statistics, e.g. how may classloaders are there? how many class is loaded per classloader? What is the classloader hierarchy? Is there possible classloader leaks? +* View classloader statistics, e.g. the number of classloaders, the number of classes loaded per classloader, the classloader hierarchy, possible classloader leaks, etc. * View the method invocation details, e.g. method parameter, return object, thrown exception, and etc. -* Check the stack trace of specified method invocation. This is useful when you would like to know who is calling your method? +* Check the stack trace of specified method invocation. This is useful when a developers wants to know the caller of the said method. * Trace the method invocation to find slow sub-invocations. -* Monitor method invcation statistics, e.g. qps, rt, success rate and etc. -* Monitoring your system metrics, thread states and cpu usage, gc statistics, and etc. -* Support command line interactive mode, with auto completed feature enabled. -* Support telnet and websocket, which enables both local and remote diagnostics with command line and browsers. +* Monitor method invocation statistics, e.g. qps, rt, success rate and etc. +* Monitor system metrics, thread states and cpu usage, gc statistics, and etc. +* Supports command line interactive mode, with auto-complete feature enabled. +* Supports telnet and websocket, which enables both local and remote diagnostics with command line and browsers. Contents From 5ee56e9475bb4fd992dbf3cf365d79f768965be5 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 27 Sep 2018 11:11:02 +0800 Subject: [PATCH 29/46] add en async.md. #51 --- site/src/site/sphinx/async.md | 6 +-- site/src/site/sphinx/en/async.md | 83 ++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 site/src/site/sphinx/en/async.md diff --git a/site/src/site/sphinx/async.md b/site/src/site/sphinx/async.md index 92e971c7d..90e827da3 100644 --- a/site/src/site/sphinx/async.md +++ b/site/src/site/sphinx/async.md @@ -36,8 +36,8 @@ $ jobs * ‘ctrl + d’:按照linux语义应当是退出终端,目前arthas中是空实现,不处理 ## 4. fg、bg命令,将命令转到前台、后台继续执行 -* 任务在后台执行或者暂停状态(‘ctrl + z’暂停任务)时,执行fg 将可以把对应的任务转到前台继续执行。在前台执行时,无法在console中执行其他命令 -* 当任务处于暂停状态时(‘ctrl + z’暂停任务),执行bg 将可以把对应的任务在后台继续执行 +* 任务在后台执行或者暂停状态(`ctrl + z`暂停任务)时,执行`fg `将可以把对应的任务转到前台继续执行。在前台执行时,无法在console中执行其他命令 +* 当任务处于暂停状态时(`ctrl + z`暂停任务),执行`bg `将可以把对应的任务在后台继续执行 * 非当前session创建的job,只能由当前session fg到前台执行 ## 5. 任务输出重定向 @@ -48,7 +48,7 @@ $ trace Test t >> test.out & ``` 这时trace命令会在后台执行,并且把结果输出到~/logs/arthas-cache/test.out。可继续执行其他命令。并可查看文件中的命令执行结果。 -当远程调用时,可能无法确定机器文件路径,arthas同时支持了自动重定向到缓存路径。使用方法如下: +当连接到远程的arthas server时,可能无法查看远程机器的文件,arthas同时支持了自动重定向到本地缓存路径。使用方法如下: ```sh $ trace Test t >> & job id : 2 diff --git a/site/src/site/sphinx/en/async.md b/site/src/site/sphinx/en/async.md new file mode 100644 index 000000000..2f53e0416 --- /dev/null +++ b/site/src/site/sphinx/en/async.md @@ -0,0 +1,83 @@ +Arthas Async Jobs +=== + +Asynchronous jobs in arthas, using commands related to linux jobs.[linux man jobs](http://man7.org/linux/man-pages/man1/jobs.1p.html)。 + + +## 1. Use & to run the command in the background + +For example, execute the trace command in the background: + +```sh +trace Test t & +``` + +## 2. List background jobs + +If you want to list all background jobs, you can execute the `jobs` command and the results are as follows: + + +```sh +$ jobs +[10]* + Stopped watch com.taobao.container.Test test "params[0].{? #this.name == null }" -x 2 + execution count : 19 + start time : Fri Sep 22 09:59:55 CST 2017 + timeout date : Sat Sep 23 09:59:55 CST 2017 + session : 3648e874-5e69-473f-9eed-7f89660b079b (current) +``` + +You can see that there is currently a background job executing. + +* job id is 10, `*` indicates that this job is created by the current session. +* status is `Stopped` +* execution count is the number of executions, which have been executed 19 times since the start. +* timeout date: After this time, the job will automatically timeout and exit. + +## 3. Suspend and Cannel job + +When the job is executing in the foreground, such as directly calling the command `trace Test t` or calling the background job command `trace Test t &`, the job is transferred to the foreground through the `fg` command. At this point, the console cannot continue to execute the command, but can receive and process the following keyboard events: + +* ‘ctrl + z’: Suspend the job, the job status will change to `Stopped`, and the job can be restarted by `bg ` or `fg ` +* ‘ctrl + c’: Stop the job +* ‘ctrl + d’: According to linux semantics should be the exit terminal, currently arthas ignore this input. + + + +## 4. fg/bg, Bring a background job to the foreground/Restart a stopped background job + +* When the job is executed in the background or suspended (`ctrl + z` to suspend job), executing `fg ` will transfer the corresponding job to the foreground to continue execution. +* When the job is suspended (`ctrl + z` to suspend job), executing `bg ` will continue the corresponding job in the background. +* A job created by a non-current session can only be executed by the current session fg to the foreground. + +## 5. Redirect the job output + +The job output can be redirect to the specified file by `>` or `>>`, and can be used together with `&` to implement the asynchronous job of the arthas command. such as: + +```sh +$ trace Test t >> test.out & +``` + +The trace command will be executed in the background and the output will be redirect to `~/logs/arthas-cache/test.out`. You can continue to execute other commands in the console. + + +When connecting to a remote arthas server, you may not be able to view the files of the remote machine. Arthas also supports automatic redirection to the local cache file. Examples are as follows: + +```sh +$ trace Test t >> & +job id : 2 +cache location : /Users/gehui/logs/arthas-cache/28198/2 +``` + +You can see that does not specify the redirect file after `>>`, arthas will automatically redirect the job output to the `~/logs/arthas-cache`. + +In the above example, pid is `28198` and job id is `2`. + +## 6. Stop job + +If you want to stop background job, just `kill `. + +## 7. Others + +* Support up to 8 commands at the same time redirect the output to the log file. +* Do not open too many background asynchronous commands at the same time to avoid affecting the performance of the target JVM. \ No newline at end of file From 045bd0e30cbb1db4731230a291aad5940af392e0 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 27 Sep 2018 11:20:11 +0800 Subject: [PATCH 30/46] update en/commands.md. #51 --- site/src/site/sphinx/en/commands.md | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/site/src/site/sphinx/en/commands.md b/site/src/site/sphinx/en/commands.md index d5c1e664d..8ef88a647 100644 --- a/site/src/site/sphinx/en/commands.md +++ b/site/src/site/sphinx/en/commands.md @@ -1,19 +1,8 @@ All Commands ============= -### Basic - -* help - check the assistant info for the command -* cls - clear out the current screen area -* session - check the current session profile -* [reset](reset.md) - clear the injected code from the classes (B.T.W when Arthas server closed, all the injected will also be cleared) -* version - the version of the working Arthas -* quit - exit the current Arthas client without affecting other clients -* shutdown - terminate the Arthas server and all clients -* [keymap](keymap.md) - shortcuts for Arthas and also you can define your own -### Advanced * [dashboard](dashboard.md) * [thread](thread.md) * [jvm](jvm.md) @@ -38,3 +27,17 @@ All Commands * [options](options.md) + +### Basic Commands + +* help - check the assistant info for the command +* cls - clear out the current screen area +* session - check the current session profile +* [reset](reset.md) - clear the injected code from the classes (B.T.W when Arthas server closed, all the injected will also be cleared) +* version - the version of the working Arthas +* quit - exit the current Arthas client without affecting other clients +* shutdown - terminate the Arthas server and all clients +* [keymap](keymap.md) - shortcuts for Arthas and also you can define your own + + + From d02565745748ff3918844a90e5300c65cd0d8669 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 27 Sep 2018 11:33:06 +0800 Subject: [PATCH 31/46] update README.md. #51 --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 19bc0b5ad..0a4b7815b 100644 --- a/README.md +++ b/README.md @@ -4,32 +4,32 @@ `Arthas` is a Java Diagnostic tool open sourced by Alibaba. -Arthas can help developer trouble-shoot production issues for Java applications without modifying your code or restarting your server. +Arthas help developers in trouble-shooting production issues for Java applications without modifying code or restarting servers. [中文说明](README_CN.md) (For Chinese Documentation) ### Background -In production system, sometimes the network is unreachable from local development environment. If you encounter some issues in production system, it is impossible to use IDE to debug the application remotely. More importantly, debugging in production is unacceptable, because it will suspend all the threads, which leads to business unavailability. +Often times, the production system network is inaccessible from local development environment. If issues are encountered in production systems, it is impossible to use IDE to debug the application remotely. More importantly, debugging in production environment is unacceptable, as it will suspend all the threads, which leads to blocking of business services. -Some may think of reproducing the same issue on the test/staging environment. However, some tricky issues either can hardly be reproduced on a different environment, or even disappear once restarted. +Developers could always try to reproduce the same issue on the test/staging environment. However, this is tricky as some issues cannot be be reproduced easily on a different environment, or even disappear once restarted. -Thinking of adding some logs to your code? You have to go through test, staging, and then on to production. Time is money! That is very inefficient! Besides, the issue may not be reproducible once you restart your JVM, as described above. +And if you're thinking of adding some logs to your code to help trouble-shoot the issue, you will have to go through the following lifecycle; test, staging, and then to production. Time is money! This approach is inefficient! Besides, the issue may not be reproducible once the JVM is restarted, as described above. -Arthas is born to solve these issues. You can trouble-shoot your production issue on-the-fly. No need for JVM restart, no additional code changes. Arthas works as an observer, which will never suspend your existing threads. +Arthas was built to solve these issues. A developer can trouble-shoot your production issues on-the-fly. No JVM restart, no additional code changes. Arthas works as an observer, which will never suspend your existing threads. ### Key features -* Check whether a class is loaded? And where the class is loaded from? (Useful for trouble-shooting jar file conflicts) +* Check whether a class is loaded? Or where the class is loaded from? (Useful for trouble-shooting jar file conflicts) * Decompile a class to ensure the code is running as expected. -* View classloader statistics, e.g. how may classloaders are there? How many classes are loaded per classloader? What is the classloader hierarchy? Are there possible classloader leaks? +* View classloader statistics, e.g. the number of classloaders, the number of classes loaded per classloader, the classloader hierarchy, possible classloader leaks, etc. * View the method invocation details, e.g. method parameter, return object, thrown exception, and etc. -* Check the stack trace of specified method invocation. This is useful when you would like to know who is calling your method. +* Check the stack trace of specified method invocation. This is useful when a developers wants to know the caller of the said method. * Trace the method invocation to find slow sub-invocations. -* Monitor method invcation statistics, e.g. qps, rt, success rate, etc. -* Monitoring your system metrics, thread states and cpu usage, gc statistics, etc. -* Support command line interactive mode, with auto complete feature enabled. -* Support telnet and websocket, which enables both local and remote diagnostics with command line and browsers. +* Monitor method invocation statistics, e.g. qps, rt, success rate and etc. +* Monitor system metrics, thread states and cpu usage, gc statistics, and etc. +* Supports command line interactive mode, with auto-complete feature enabled. +* Supports telnet and websocket, which enables both local and remote diagnostics with command line and browsers. ### Quick start From b0bec341a082f9695f1fc8de508f28a5bf10a9b7 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 27 Sep 2018 11:47:20 +0800 Subject: [PATCH 32/46] fix bash codeblock highlight. --- site/src/site/sphinx/arthas3.md | 2 +- site/src/site/sphinx/arthas_3_0/new_feature.md | 4 ++-- site/src/site/sphinx/async.md | 8 ++++---- site/src/site/sphinx/batch-support.md | 4 ++-- site/src/site/sphinx/classloader.md | 2 +- site/src/site/sphinx/en/async.md | 8 ++++---- site/src/site/sphinx/en/batch-support.md | 4 ++-- site/src/site/sphinx/en/classloader.md | 4 ++-- site/src/site/sphinx/en/jad.md | 2 +- site/src/site/sphinx/en/save-log.md | 4 ++-- site/src/site/sphinx/en/sm.md | 2 +- site/src/site/sphinx/en/start-arthas.md | 2 +- site/src/site/sphinx/en/thread.md | 4 ++-- site/src/site/sphinx/jad.md | 2 +- site/src/site/sphinx/save-log.md | 4 ++-- site/src/site/sphinx/sm.md | 2 +- site/src/site/sphinx/start-arthas.md | 2 +- site/src/site/sphinx/thread.md | 4 ++-- 18 files changed, 32 insertions(+), 32 deletions(-) diff --git a/site/src/site/sphinx/arthas3.md b/site/src/site/sphinx/arthas3.md index df93a15d7..15fa0fb51 100644 --- a/site/src/site/sphinx/arthas3.md +++ b/site/src/site/sphinx/arthas3.md @@ -19,7 +19,7 @@ Arthas 3.0开始支持管道, 率先提供了`grep`,`wc`,`plaintext`的支持。 groovy表达式在arthas2.0中大量使用,例如watch表达式 -```sh +```bash watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "params + ' ' + returnObj" params.size()==2 ``` diff --git a/site/src/site/sphinx/arthas_3_0/new_feature.md b/site/src/site/sphinx/arthas_3_0/new_feature.md index f73cb52ed..d38392e94 100644 --- a/site/src/site/sphinx/arthas_3_0/new_feature.md +++ b/site/src/site/sphinx/arthas_3_0/new_feature.md @@ -16,7 +16,7 @@ Arthas 3.0最重要的特性,通过Arthas在线诊断平台,无需再登陆 Arthas 3.0开始支持管道, 率先提供了`grep`,`wc`,`plaintext`的支持。 -```sh +```bash java.vendor.url http://java.oracle.com/ java.vm.vendor Oracle Corporation java.runtime.name Java(TM) SE Runtime Environment @@ -55,7 +55,7 @@ To solve this, choose one of the following command: groovy表达式在arthas2.0中大量使用,例如watch表达式 -```sh +```bash watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "params + ' ' + returnObj" params.size()==2 ``` diff --git a/site/src/site/sphinx/async.md b/site/src/site/sphinx/async.md index 90e827da3..aaa0a3267 100644 --- a/site/src/site/sphinx/async.md +++ b/site/src/site/sphinx/async.md @@ -6,14 +6,14 @@ arthas中的异步调用,使用了仿linux系统任务相关的命令。[linux ## 1. 使用&在后台执行任务 比如希望执行后台执行trace命令,那么调用下面命令 -```sh +```bash trace Test t & ``` 这时命令在后台执行,可以在console中继续执行其他命令。 ## 2. 通过jobs查看任务 如果希望查看当前有哪些arthas任务在执行,可以执行jobs命令,执行结果如下 -```sh +```bash $ jobs [10]* Stopped watch com.taobao.container.Test test "params[0].{? #this.name == null }" -x 2 @@ -43,13 +43,13 @@ $ jobs ## 5. 任务输出重定向 可通过`>`或者`>>`将任务输出结果输出到指定的文件中,可以和`&`一起使用,实现arthas命令的异步调用。比如: -```sh +```bash $ trace Test t >> test.out & ``` 这时trace命令会在后台执行,并且把结果输出到~/logs/arthas-cache/test.out。可继续执行其他命令。并可查看文件中的命令执行结果。 当连接到远程的arthas server时,可能无法查看远程机器的文件,arthas同时支持了自动重定向到本地缓存路径。使用方法如下: -```sh +```bash $ trace Test t >> & job id : 2 cache location : /Users/gehui/logs/arthas-cache/28198/2 diff --git a/site/src/site/sphinx/batch-support.md b/site/src/site/sphinx/batch-support.md index 5d17473fb..d1199537e 100644 --- a/site/src/site/sphinx/batch-support.md +++ b/site/src/site/sphinx/batch-support.md @@ -28,12 +28,12 @@ sc -d org.apache.commons.lang.StringUtils 通过`-b`开启批处理模式, `-f`执行脚本文件, 批处理脚本默认会输出到标准输出中,可以将结果重定向到文件中。 -```sh +```bash ./as.sh -b -f /var/tmp/test.as 56328 > test.out ``` #### 第三步: 查看运行结果 -```sh +```bash cat test.out ``` \ No newline at end of file diff --git a/site/src/site/sphinx/classloader.md b/site/src/site/sphinx/classloader.md index f0e9c934c..c7f6233b6 100644 --- a/site/src/site/sphinx/classloader.md +++ b/site/src/site/sphinx/classloader.md @@ -41,7 +41,7 @@ Affect(row-cnt:11) cost in 66 ms. * 按类加载实例查看统计信息 -```sh +```bash $ classloader -l name loadedCount hash parent BootstrapClassLoader 3711 null null diff --git a/site/src/site/sphinx/en/async.md b/site/src/site/sphinx/en/async.md index 2f53e0416..c24bfab2f 100644 --- a/site/src/site/sphinx/en/async.md +++ b/site/src/site/sphinx/en/async.md @@ -8,7 +8,7 @@ Asynchronous jobs in arthas, using commands related to linux jobs.[linux man job For example, execute the trace command in the background: -```sh +```bash trace Test t & ``` @@ -17,7 +17,7 @@ trace Test t & If you want to list all background jobs, you can execute the `jobs` command and the results are as follows: -```sh +```bash $ jobs [10]* Stopped watch com.taobao.container.Test test "params[0].{? #this.name == null }" -x 2 @@ -54,7 +54,7 @@ When the job is executing in the foreground, such as directly calling the comman The job output can be redirect to the specified file by `>` or `>>`, and can be used together with `&` to implement the asynchronous job of the arthas command. such as: -```sh +```bash $ trace Test t >> test.out & ``` @@ -63,7 +63,7 @@ The trace command will be executed in the background and the output will be redi When connecting to a remote arthas server, you may not be able to view the files of the remote machine. Arthas also supports automatic redirection to the local cache file. Examples are as follows: -```sh +```bash $ trace Test t >> & job id : 2 cache location : /Users/gehui/logs/arthas-cache/28198/2 diff --git a/site/src/site/sphinx/en/batch-support.md b/site/src/site/sphinx/en/batch-support.md index 1095985b1..6672f2006 100644 --- a/site/src/site/sphinx/en/batch-support.md +++ b/site/src/site/sphinx/en/batch-support.md @@ -28,12 +28,12 @@ Attention: Using `-b` to turn on script mode, and `-f` to run it and you can also *redirect* the output as: -```sh +```bash ./as.sh -b -f /var/tmp/test.as 56328 > test.out ``` #### Step-3: Check the outputs -```sh +```bash cat test.out ``` diff --git a/site/src/site/sphinx/en/classloader.md b/site/src/site/sphinx/en/classloader.md index 913f9d4de..a20105599 100644 --- a/site/src/site/sphinx/en/classloader.md +++ b/site/src/site/sphinx/en/classloader.md @@ -19,7 +19,7 @@ It can be a great help for `ResourceNotFoundException` when you can use command * Categorised by class loader -```sh +```bash $ classloader name numberOfInstances loadedCountTotal com.taobao.pandora.service.loader.ModuleClassLoader 29 11659 @@ -38,7 +38,7 @@ Affect(row-cnt:11) cost in 66 ms. * Categorized by class loader instance -```sh +```bash $ classloader -l name loadedCount hash parent BootstrapClassLoader 3711 null null diff --git a/site/src/site/sphinx/en/jad.md b/site/src/site/sphinx/en/jad.md index 6aa6fc6af..ef6a55ad5 100644 --- a/site/src/site/sphinx/en/jad.md +++ b/site/src/site/sphinx/en/jad.md @@ -122,7 +122,7 @@ Affect(row-cnt:1) cost in 190 ms. De-compile the specified method: -```sh +```bash $ jad com.taobao.container.web.arthas.rest.MetricsController directMetrics ClassLoader: diff --git a/site/src/site/sphinx/en/save-log.md b/site/src/site/sphinx/en/save-log.md index cb4ba4c25..0d580c513 100644 --- a/site/src/site/sphinx/en/save-log.md +++ b/site/src/site/sphinx/en/save-log.md @@ -5,7 +5,7 @@ Log command outputs for later analysis, turned off by default. To turn it on, using [options](options.md) as: -```sh +```bash $ options save-result true NAME BEFORE-VALUE AFTER-VALUE ---------------------------------------- @@ -23,7 +23,7 @@ F.Y.I :notes: :notes: With the latest Arthas, you can log the outputs asynchronously in the background: -```sh +```bash $ trace Test t >> & job id : 2 cache location : /Users/zhuyong/logs/arthas-cache/28198/2 diff --git a/site/src/site/sphinx/en/sm.md b/site/src/site/sphinx/en/sm.md index 062a32018..a11502b1d 100644 --- a/site/src/site/sphinx/en/sm.md +++ b/site/src/site/sphinx/en/sm.md @@ -61,7 +61,7 @@ org.apache.catalina.connector.Connector->getMaxCookieCount ``` -```sh +```bash $ sm org.apache.catalina.connector.Connector -d declaring-class org.apache.catalina.connector.Connector constructor-name diff --git a/site/src/site/sphinx/en/start-arthas.md b/site/src/site/sphinx/en/start-arthas.md index 0dd5b6f07..3cfc333bd 100644 --- a/site/src/site/sphinx/en/start-arthas.md +++ b/site/src/site/sphinx/en/start-arthas.md @@ -7,7 +7,7 @@ Start Arthas ./as.sh ``` -```sh +```bash ➜ bin git:(develop) ✗ ./as.sh Found existing java process, please choose one and hit RETURN. [1]: 3088 org.jetbrains.idea.maven.server.RemoteMavenServer diff --git a/site/src/site/sphinx/en/thread.md b/site/src/site/sphinx/en/thread.md index 7c9b4b9cd..21e00d33f 100644 --- a/site/src/site/sphinx/en/thread.md +++ b/site/src/site/sphinx/en/thread.md @@ -100,7 +100,7 @@ $ thread 1 Using `-b`, we can effectively locate the threads holding locks blocking other threads resulting in a frozen system. -```sh +```bash $ thread -b "http-bio-8080-exec-4" Id=27 TIMED_WAITING at java.lang.Thread.sleep(Native Method) @@ -144,7 +144,7 @@ $ thread -b #### thread -i specify the collecting interval -```sh +```bash $ thread -n 3 -i 1000 "as-command-execute-daemon" Id=4759 cpuUsage=23% RUNNABLE at sun.management.ThreadImpl.dumpThreads0(Native Method) diff --git a/site/src/site/sphinx/jad.md b/site/src/site/sphinx/jad.md index 56ec3deaf..7ad01c335 100644 --- a/site/src/site/sphinx/jad.md +++ b/site/src/site/sphinx/jad.md @@ -119,7 +119,7 @@ Affect(row-cnt:1) cost in 190 ms. 反编译指定的方法: -```sh +```bash $ jad com.taobao.container.web.arthas.rest.MetricsController directMetrics ClassLoader: diff --git a/site/src/site/sphinx/save-log.md b/site/src/site/sphinx/save-log.md index 33fa4e898..920ce1cef 100644 --- a/site/src/site/sphinx/save-log.md +++ b/site/src/site/sphinx/save-log.md @@ -5,7 +5,7 @@ * 默认情况下,该功能是关闭的,如果需要开启,请执行以下命令: -```sh +```bash $ options save-result true NAME BEFORE-VALUE AFTER-VALUE ---------------------------------------- @@ -21,7 +21,7 @@ Affect(row-cnt:1) cost in 3 ms. ### 使用新版本Arthas的异步后台任务将结果存日志文件 -```sh +```bash $ trace Test t >> & job id : 2 cache location : /Users/zhuyong/logs/arthas-cache/28198/2 diff --git a/site/src/site/sphinx/sm.md b/site/src/site/sphinx/sm.md index d486f04af..a37345892 100644 --- a/site/src/site/sphinx/sm.md +++ b/site/src/site/sphinx/sm.md @@ -60,7 +60,7 @@ org.apache.catalina.connector.Connector->getMaxCookieCount ``` -```sh +```bash $ sm org.apache.catalina.connector.Connector -d declaring-class org.apache.catalina.connector.Connector constructor-name diff --git a/site/src/site/sphinx/start-arthas.md b/site/src/site/sphinx/start-arthas.md index 4e0d65ec1..61a4e2de5 100644 --- a/site/src/site/sphinx/start-arthas.md +++ b/site/src/site/sphinx/start-arthas.md @@ -7,7 +7,7 @@ ./as.sh ``` -```sh +```bash ➜ bin git:(develop) ✗ ./as.sh Found existing java process, please choose one and hit RETURN. [1]: 3088 org.jetbrains.idea.maven.server.RemoteMavenServer diff --git a/site/src/site/sphinx/thread.md b/site/src/site/sphinx/thread.md index aa9c63c91..bf2d8411b 100644 --- a/site/src/site/sphinx/thread.md +++ b/site/src/site/sphinx/thread.md @@ -99,7 +99,7 @@ $ thread 1 有时候我们发现应用卡住了, 通常是由于某个线程拿住了某个锁, 并且其他线程都在等待这把锁造成的。 为了排查这类问题, arthas提供了`thread -b`, 一键找出那个罪魁祸首。 -```sh +```bash $ thread -b "http-bio-8080-exec-4" Id=27 TIMED_WAITING at java.lang.Thread.sleep(Native Method) @@ -143,7 +143,7 @@ $ thread -b #### thread -i, 指定采样时间间隔 -```sh +```bash $ thread -n 3 -i 1000 "as-command-execute-daemon" Id=4759 cpuUsage=23% RUNNABLE at sun.management.ThreadImpl.dumpThreads0(Native Method) From d8b843f1c68a5c24be73f3ba2f77ecdfb7fa6d63 Mon Sep 17 00:00:00 2001 From: earayu Date: Thu, 27 Sep 2018 14:59:41 +0800 Subject: [PATCH 33/46] bugfix --- .../taobao/arthas/core/util/TokenUtils.java | 38 +++++- .../arthas/core/util/TokenUtilsTest.java | 126 ++++++++++++++++++ 2 files changed, 157 insertions(+), 7 deletions(-) create mode 100644 core/src/test/java/com/taobao/arthas/core/util/TokenUtilsTest.java diff --git a/core/src/main/java/com/taobao/arthas/core/util/TokenUtils.java b/core/src/main/java/com/taobao/arthas/core/util/TokenUtils.java index e4159e806..b2cb89c3b 100644 --- a/core/src/main/java/com/taobao/arthas/core/util/TokenUtils.java +++ b/core/src/main/java/com/taobao/arthas/core/util/TokenUtils.java @@ -1,20 +1,27 @@ package com.taobao.arthas.core.util; import java.util.List; - import com.taobao.arthas.core.shell.cli.CliToken; /** - * tokens处理的辅助类 + * tokenizer helper * - * @author gehui 2017年7月27日 上午11:39:56 + * @author gehui 2017-07-27 11:39:56 */ public class TokenUtils { + /** + * find the first text token + * @param tokens + * @return + */ public static CliToken findFirstTextToken(List tokens) { + if(tokens==null || tokens.isEmpty()){ + return null; + } CliToken first = null; for (CliToken token : tokens) { - if (token.isText()) { + if (token!=null && token.isText()) { first = token; break; } @@ -22,20 +29,37 @@ public class TokenUtils { return first; } + /** + * find the last text token + * @param tokens + * @return + */ public static CliToken findLastTextToken(List tokens) { - for (int i = tokens.size() - 1; i > 0; i--) { + if(tokens==null || tokens.isEmpty()){ + return null; + } + //#165 + for (int i = tokens.size() - 1; i >= 0; i--) { CliToken token = tokens.get(i); - if (token.isText()) { + if (token!=null && token.isText()) { return token; } } return null; } + /** + * find the second text token's text + * @param tokens + * @return + */ public static String findSecondTokenText(List tokens) { + if(tokens==null || tokens.isEmpty()){ + return null; + } boolean first = true; for (CliToken token : tokens) { - if (token.isText()) { + if (token!=null && token.isText()) { if (first) { first = false; } else { diff --git a/core/src/test/java/com/taobao/arthas/core/util/TokenUtilsTest.java b/core/src/test/java/com/taobao/arthas/core/util/TokenUtilsTest.java new file mode 100644 index 000000000..4da98be29 --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/util/TokenUtilsTest.java @@ -0,0 +1,126 @@ +package com.taobao.arthas.core.util; + +import com.taobao.arthas.core.shell.cli.CliToken; +import com.taobao.arthas.core.shell.cli.impl.CliTokenImpl; +import org.junit.Assert; +import org.junit.Test; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author earayu + */ +public class TokenUtilsTest { + + private List newCliTokenList(CliToken ... tokens){ + List cliTokens = new ArrayList(); + if(tokens!=null) { + Collections.addAll(cliTokens, tokens); + } + return cliTokens; + } + + @Test + public void testFindFirstTextToken(){ + CliToken textCliToken = new CliTokenImpl(true,"textCliToken"); + CliToken nonTextCliToken = new CliTokenImpl(false,"nonTextCliToken"); + + //null list + Assert.assertEquals(null, TokenUtils.findFirstTextToken(null)); + + //empty list + Assert.assertEquals(null, TokenUtils.findFirstTextToken(new ArrayList())); + + //list with null value + Assert.assertEquals(null, + TokenUtils.findFirstTextToken(newCliTokenList(new CliToken[]{null}))); + Assert.assertEquals(textCliToken, + TokenUtils.findFirstTextToken(newCliTokenList(new CliToken[]{null, textCliToken}))); + Assert.assertEquals(textCliToken, + TokenUtils.findFirstTextToken(newCliTokenList(new CliToken[]{null, nonTextCliToken, textCliToken}))); + Assert.assertEquals(textCliToken, + TokenUtils.findFirstTextToken(newCliTokenList(new CliToken[]{nonTextCliToken, null, textCliToken}))); + + //list with normal inputs + Assert.assertEquals(textCliToken, + TokenUtils.findFirstTextToken(newCliTokenList(new CliToken[]{textCliToken}))); + Assert.assertEquals(textCliToken, + TokenUtils.findFirstTextToken(newCliTokenList(new CliToken[]{nonTextCliToken, textCliToken}))); + Assert.assertEquals(textCliToken, + TokenUtils.findFirstTextToken(newCliTokenList(new CliToken[]{textCliToken, nonTextCliToken}))); + + } + + + + @Test + public void testFindLastTextToken(){ + CliToken textCliToken = new CliTokenImpl(true,"textCliToken"); + CliToken nonTextCliToken = new CliTokenImpl(false,"nonTextCliToken"); + + //null list + Assert.assertEquals(null, TokenUtils.findLastTextToken(null)); + + //empty list + Assert.assertEquals(null, TokenUtils.findLastTextToken(new ArrayList())); + + //list with null value + Assert.assertEquals(null, + TokenUtils.findLastTextToken(newCliTokenList(new CliToken[]{null}))); + Assert.assertEquals(textCliToken, + TokenUtils.findLastTextToken(newCliTokenList(new CliToken[]{null, textCliToken}))); + Assert.assertEquals(textCliToken, + TokenUtils.findLastTextToken(newCliTokenList(new CliToken[]{null, nonTextCliToken, textCliToken}))); + Assert.assertEquals(textCliToken, + TokenUtils.findLastTextToken(newCliTokenList(new CliToken[]{nonTextCliToken, null, textCliToken}))); + Assert.assertEquals(textCliToken, + TokenUtils.findLastTextToken(newCliTokenList(new CliToken[]{textCliToken, null, nonTextCliToken}))); + + //list with normal inputs + Assert.assertEquals(textCliToken, + TokenUtils.findLastTextToken(newCliTokenList(new CliToken[]{textCliToken}))); + Assert.assertEquals(null, + TokenUtils.findLastTextToken(newCliTokenList(new CliToken[]{nonTextCliToken}))); + Assert.assertEquals(textCliToken, + TokenUtils.findLastTextToken(newCliTokenList(new CliToken[]{nonTextCliToken, textCliToken}))); + Assert.assertEquals(textCliToken, + TokenUtils.findLastTextToken(newCliTokenList(new CliToken[]{textCliToken, nonTextCliToken}))); + + } + + + @Test + public void testFindSecondTextToken(){ + CliToken textCliToken = new CliTokenImpl(true,"textCliToken"); + CliToken nonTextCliToken = new CliTokenImpl(false,"nonTextCliToken"); + + //null list + Assert.assertEquals(null, TokenUtils.findSecondTokenText(null)); + + //empty list + Assert.assertEquals(null, TokenUtils.findSecondTokenText(new ArrayList())); + + //list with null value + Assert.assertEquals(null, + TokenUtils.findSecondTokenText(newCliTokenList(new CliToken[]{null}))); + Assert.assertEquals(null, + TokenUtils.findSecondTokenText(newCliTokenList(new CliToken[]{null, textCliToken}))); + Assert.assertEquals(null, + TokenUtils.findSecondTokenText(newCliTokenList(new CliToken[]{null, nonTextCliToken, textCliToken}))); + Assert.assertEquals(textCliToken.value(), + TokenUtils.findSecondTokenText(newCliTokenList(new CliToken[]{null, nonTextCliToken, textCliToken, textCliToken}))); + + //list with normal inputs + Assert.assertEquals(null, + TokenUtils.findSecondTokenText(newCliTokenList(new CliToken[]{textCliToken}))); + Assert.assertEquals(null, + TokenUtils.findSecondTokenText(newCliTokenList(new CliToken[]{nonTextCliToken}))); + Assert.assertEquals(null, + TokenUtils.findSecondTokenText(newCliTokenList(new CliToken[]{nonTextCliToken, textCliToken}))); + Assert.assertEquals(textCliToken.value(), + TokenUtils.findSecondTokenText(newCliTokenList(new CliToken[]{textCliToken, nonTextCliToken, textCliToken}))); + + } + +} From b1a738999426d23c5f7a16d8f59fb5683305e88c Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 27 Sep 2018 15:18:24 +0800 Subject: [PATCH 34/46] add repo mirror. --- README_CN.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README_CN.md b/README_CN.md index 35e05fd46..453666df8 100644 --- a/README_CN.md +++ b/README_CN.md @@ -302,4 +302,8 @@ $ classloader * [greys-anatomy](https://github.com/oldmanpushcart/greys-anatomy): Arthas代码基于Greys二次开发而来,非常感谢Greys之前所有的工作,以及Greys原作者对Arthas提出的意见和建议! * [termd](https://github.com/termd/termd): Arthas的命令行实现基于termd开发,是一款优秀的命令行程序开发框架,感谢termd提供了优秀的框架。 * [crash](https://github.com/crashub/crash): Arthas的文本渲染功能基于crash中的文本渲染功能开发,可以从[这里](https://github.com/crashub/crash/tree/1.3.2/shell)看到源码,感谢crash在这方面所做的优秀工作。 -* [cli](https://github.com/eclipse-vertx/vert.x/tree/master/src/main/java/io/vertx/core/cli): Arthas的命令行界面基于vert.x提供的cli库进行开发,感谢vert.x在这方面做的优秀工作。 \ No newline at end of file +* [cli](https://github.com/eclipse-vertx/vert.x/tree/master/src/main/java/io/vertx/core/cli): Arthas的命令行界面基于vert.x提供的cli库进行开发,感谢vert.x在这方面做的优秀工作。 + +### 仓库镜像 + +* [码云Arthas](https://gitee.com/arthas/arthas) \ No newline at end of file From 7c6fd86014764e6968e395275b16cc178acffe58 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 27 Sep 2018 16:56:46 +0800 Subject: [PATCH 35/46] fix as-package.sh unzip error. #84 --- as-package.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/as-package.sh b/as-package.sh index 5541f5fde..0cb8d4039 100755 --- a/as-package.sh +++ b/as-package.sh @@ -4,7 +4,8 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" get_local_maven_project_version() { - $DIR/mvnw org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=project.version | grep -e '^[^\[]' | cut -b 1-5 + $DIR/mvnw org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate \ + -Dexpression=project.version -f $DIR/pom.xml | grep -e '^[^\[]' | cut -b 1-5 } CUR_VERSION=$(get_local_maven_project_version) @@ -40,7 +41,7 @@ rm -r $DIR/core/src/main/resources/com/taobao/arthas/core/res/version # install to local mkdir -p ${NEWEST_ARTHAS_LIB_HOME} -unzip ${packaging_bin_path} -d ${NEWEST_ARTHAS_LIB_HOME}/ +unzip ${packaging_bin_path} -d "${NEWEST_ARTHAS_LIB_HOME}/" # print ~/.arthas directory size arthas_dir_size="$(du -hs ${HOME}/.arthas | cut -f1)" From c2c54743f070871d2eee9848b32b3ce0e2bbf995 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Thu, 27 Sep 2018 18:54:42 +0800 Subject: [PATCH 36/46] fix log path error. #168 --- .../src/main/java/com/taobao/arthas/agent/AgentBootstrap.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/agent/src/main/java/com/taobao/arthas/agent/AgentBootstrap.java b/agent/src/main/java/com/taobao/arthas/agent/AgentBootstrap.java index 1821911a5..77e1091a1 100644 --- a/agent/src/main/java/com/taobao/arthas/agent/AgentBootstrap.java +++ b/agent/src/main/java/com/taobao/arthas/agent/AgentBootstrap.java @@ -35,9 +35,9 @@ public class AgentBootstrap { static { try { File log = new File(System.getProperty("user.home") + File.separator + "logs" + File.separator - + ".arthas" + File.separator + "arthas.log"); + + "arthas" + File.separator + "arthas.log"); if (!log.exists()) { - log.getParentFile().mkdir(); + log.getParentFile().mkdirs(); log.createNewFile(); } ps = new PrintStream(new FileOutputStream(log, true)); From e2d55e8dfec6dbdc2fa212c3d132e88606c083fd Mon Sep 17 00:00:00 2001 From: beiwei30 Date: Thu, 27 Sep 2018 11:42:24 -0400 Subject: [PATCH 37/46] enhance translation for advanced-use.md --- site/src/site/sphinx/en/advanced-use.md | 77 +++++++++++++------------ 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/site/src/site/sphinx/en/advanced-use.md b/site/src/site/sphinx/en/advanced-use.md index d3e8d4e75..c1537d669 100644 --- a/site/src/site/sphinx/en/advanced-use.md +++ b/site/src/site/sphinx/en/advanced-use.md @@ -3,71 +3,74 @@ Advanced Usage ## Basic -* help - show help info -* cls - clear out the current screen -* session - check details of the current session -* [reset](reset.md) - reset all injected/enhanced classes -* version - print the version of the Arthas attaching to the current target process -* quit/exit - exit the current Arthas client without affecting other clients -* shutdown - terminate the Arthas server and all clients +* help - display Arthas help +* cls - clear the screen +* session - display current session information +* [reset](reset.md) - reset all the enhanced classes. All enhanced classes will also be reset when Arthas server is closed by `shutdown` +* version - print the version for the Arthas attached to the current Java process +* quit/exit - exit the current Arthas session, without effecting other sessions +* shutdown - terminate the Arthas server, all Arthas sessions will be destroyed +* [keymap](keymap.md) - keymap for Arthas keyboard shortcut ## JVM -* [dashboard](dashboard.md) - real-time dashboard for the current system -* [thread](thread.md) - thread profile -* [jvm](jvm.md) - JVM profile -* [sysprop](sysprop.md) - check or modify JVM system properties -* **New!** [getstatic](getstatic.md) :clap: - check the static properties of classes +* [dashboard](dashboard.md) - dashboard for the system's real-time data +* [thread](thread.md) - show java thread information +* [jvm](jvm.md) - show JVM information +* [sysprop](sysprop.md) - show/modify system properties +* **New!** [getstatic](getstatic.md) :clap: - examine class's static properties ## class/classloader - -* [sc](sc.md) - check profiles of the classes loaded by JVM -* [sm](sm.md) - check methods' profile -* [dump](dump.md) - dump out the byte code of the loaded classes to specified location -* [redefine](redefine.md) - load external `*.class` files and re-define the JVM-loaded classes +* [sc](sc.md) - check the info for the classes loaded by JVM +* [sm](sm.md) - check methods info for the loaded classes +* [dump](dump.md) - dump the loaded classes in byte code to the specified location +* [redefine](redefine.md) - load external `*.class` files and re-define it into JVM * [jad](jad.md) - de-compile the specified loaded classes -* [classloader](classloader.md) - check the inheritance structure, urls, class loading info of class cloader; using classloader to get the url of the resource e.g. `java/lang/String.class` +* [classloader](classloader.md) - check the inheritance structure, urls, class loading info for the specified class; using classloader to get the url of the resource e.g. `java/lang/String.class` ## monitor/watch/trace - related -> **Attention**: commands here are taking advantage of `byte code injection`, which means we are using [AOP](https://en.wikipedia.org/wiki/Aspect-oriented_programming) to monitor and analyze the classes. So when using it for online troubleshooting, you'd better *explicitly specifically* specify the classes and also remember to remove the injected code by `shutdown` or `reset`. +> **Attention**: commands here are taking advantage of byte-code-injection, which means we are injecting some [aspects](https://en.wikipedia.org/wiki/Aspect-oriented_programming) into the current classes for monitoring and statistics purpose. Therefore when use it for online troubleshooting in your production environment, you'd better **explicitly specify** classes/methods/criteria, and remember to remove the injected code by `shutdown` or `reset`. -* [monitor](monitor.md) - monitor the `class-pattern` & `method-pattern` matched methods' invoking traces -* [watch](watch.md) - watch/monitor methods in data aspect including `return values`, `exceptions` and `parameters` -* [trace](trace.md) - track the method calling trace along with the time cost for each call -* [stack](stack.md) - print the call stack trace of the current method in a persistent way -* [tt](tt.md) - record the arguments and returned value for the methods, history included +* [monitor](monitor.md) - monitor method execution statistics +* [watch](watch.md) - display the input/output parameter, return object, and thrown exception of specified method invocation +* [trace](trace.md) - trace the execution time of specified method invocation +* [stack](stack.md) - display the stack trace for the specified class and method +* [tt](tt.md) - time tunnel, record the arguments and returned value for the methods and replay ## options -* [options](options.md) - check or set Arthas global options +* [options](options.md) - check/set Arthas global options ## pipe -`pipe` is supported in Arthas, e.g. `sm org.apache.log4j.Logger | grep ` +Arthas provides `pipe` to process the result returned from commands further, e.g. `sm org.apache.log4j.Logger | grep `. Commands supported in `pipe`: -Commands supported in `pipe`: - -* grep - filtering +* grep - filter the result with the given keyword * plaintext - remove the color -* wc - line counting +* wc - count lines ## async in background -[async](async.md) will be a great help, when the `incident` seldom occurs and you are [`watch`](watch.md)ing it. - +[async](async.md) can be handy when a problem is hardly to reproduce in the production enviornment, e.g. one `watch` condition may happen only once in one single day. +* job control - use `>` to redirect result into the log file, use `&` to put the job to the background. Job keeps running even if the session is disconnected (the session lifecycle is 1 day by default) * jobs - list all jobs * kill - forcibly terminate the job -* fg - bring the paused job back to the front -* bg - put the paused job to the background -* tips - a) use `>` to redirect the output; b) use `&` to put the job to the background; c) disconnecting the session will not influence the job (the default life is 1 day) +* fg - bring the suspend job to the foreground +* bg - put the job to run in the background -## Others +## Web Console -* [Web Console](web-console.md) - using websocket to connect Arthas +Arthas supports living inside a browser. The communication between arthas and browser is via websocket. + +* [Web Console](web-console.md) + +## Other features + +* [Async support](async.md) * [log the output](save-log.md) * [batch](batch-support.md) * [how to use ognl](https://github.com/alibaba/arthas/issues/11) From f26ad12b8ece4e2b89362de2e083bb95911d2e55 Mon Sep 17 00:00:00 2001 From: LHearen Date: Fri, 28 Sep 2018 18:40:06 +0800 Subject: [PATCH 38/46] fix some logic and descriptions issues in doc --- site/src/site/sphinx/en/stack.md | 2 +- site/src/site/sphinx/en/tt.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/site/src/site/sphinx/en/stack.md b/site/src/site/sphinx/en/stack.md index 6b373341d..ce43a730d 100644 --- a/site/src/site/sphinx/en/stack.md +++ b/site/src/site/sphinx/en/stack.md @@ -1,7 +1,7 @@ stack ===== -Print out the full call stack trace containing the current method. +Print out the full call stack trace *till* the current method. Most of the time, we know the method being invoked but not always we know **HOW being invoked**; `stack` can be a great help to locate the *source* for you. diff --git a/site/src/site/sphinx/en/tt.md b/site/src/site/sphinx/en/tt.md index b0a134d73..a005e8f49 100644 --- a/site/src/site/sphinx/en/tt.md +++ b/site/src/site/sphinx/en/tt.md @@ -112,7 +112,7 @@ Advanced: ### Check context of the call -Using `tt -i ` to check a specific record. +Using `tt -i ` to check a specific calling details. ``` $ From 5839afb3e8cfc8b64581879fb202607e7659c187 Mon Sep 17 00:00:00 2001 From: LHearen Date: Fri, 28 Sep 2018 13:55:27 +0800 Subject: [PATCH 39/46] bug fix when unzip not found --- bin/as.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bin/as.sh b/bin/as.sh index 1c11bf7ae..a7b2e7a5b 100755 --- a/bin/as.sh +++ b/bin/as.sh @@ -76,7 +76,7 @@ default() check_permission() { [ ! -w ${HOME} ] \ - && exit_on_err 1 "permission denied, ${HOME} is not writeable." + && exit_on_err 1 "permission denied, ${HOME} is not writable." } @@ -179,7 +179,8 @@ update_if_necessary() || return 1 # unzip arthas lib - unzip ${temp_target_lib_zip} -d ${temp_target_lib_dir} || (rm -rf ${temp_target_lib_dir} && return 1) + unzip ${temp_target_lib_zip} -d ${temp_target_lib_dir} || (rm -rf ${temp_target_lib_dir} \ + ${ARTHAS_LIB_DIR}/${update_version} && return 1) # rename mv ${temp_target_lib_dir} ${target_lib_dir} || return 1 From 2024795196830071e0fa834554902027254b3390 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Sat, 29 Sep 2018 14:25:14 +0800 Subject: [PATCH 40/46] fix doc links --- README.md | 4 ++-- site/src/site/sphinx/en/web-console.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0a4b7815b..c9eb14d75 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ English version is on the way, if you would like to contribute, please leave a m #### Dashboard -* https://alibaba.github.io/arthas/dashboard +* https://alibaba.github.io/arthas/en/dashboard ![dashboard](site/src/site/sphinx/_static/dashboard.png) @@ -297,7 +297,7 @@ $ classloader #### Web Console -* https://alibaba.github.io/arthas/web-console +* https://alibaba.github.io/arthas/en/web-console ![web console](site/src/site/sphinx/_static/web-console-local.png) diff --git a/site/src/site/sphinx/en/web-console.md b/site/src/site/sphinx/en/web-console.md index 98aa68465..a785da9a0 100644 --- a/site/src/site/sphinx/en/web-console.md +++ b/site/src/site/sphinx/en/web-console.md @@ -1,7 +1,7 @@ Web Console === -Arthas supports the Web Console. After attach success, the user can access: [http://localhost:8563/] (http://localhost:8563/). +Arthas supports the Web Console. After attach success, the user can access: [http://localhost:8563/](http://localhost:8563/). The user can fill in the IP and connect the remote arthas on other machines. From fdbe1a48ea634b6d96781b9d49a9f74469ed42ec Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Sun, 30 Sep 2018 15:16:59 +0800 Subject: [PATCH 41/46] add comment --- .../main/java/com/taobao/arthas/agent/AgentBootstrap.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/agent/src/main/java/com/taobao/arthas/agent/AgentBootstrap.java b/agent/src/main/java/com/taobao/arthas/agent/AgentBootstrap.java index 77e1091a1..ddf9923b3 100644 --- a/agent/src/main/java/com/taobao/arthas/agent/AgentBootstrap.java +++ b/agent/src/main/java/com/taobao/arthas/agent/AgentBootstrap.java @@ -146,6 +146,13 @@ public class AgentBootstrap { } private static void bind(Instrumentation inst, ClassLoader agentLoader, String args) throws Throwable { + /** + *
+         * Configure configure = Configure.toConfigure(args);
+         * int javaPid = configure.getJavaPid();
+         * ArthasBootstrap bootstrap = ArthasBootstrap.getInstance(javaPid, inst);
+         * 
+ */ Class classOfConfigure = agentLoader.loadClass(ARTHAS_CONFIGURE); Object configure = classOfConfigure.getMethod(TO_CONFIGURE, String.class).invoke(null, args); int javaPid = (Integer) classOfConfigure.getMethod(GET_JAVA_PID).invoke(configure); From 86d1d4bfb7bb88266ea9ed13733071a6f69f8099 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Sun, 30 Sep 2018 15:20:41 +0800 Subject: [PATCH 42/46] improve get pid logic --- .../arthas/core/util/ApplicationUtils.java | 32 +++++++++++++++++++ .../taobao/arthas/core/util/Constants.java | 3 +- 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 core/src/main/java/com/taobao/arthas/core/util/ApplicationUtils.java diff --git a/core/src/main/java/com/taobao/arthas/core/util/ApplicationUtils.java b/core/src/main/java/com/taobao/arthas/core/util/ApplicationUtils.java new file mode 100644 index 000000000..8f17aba41 --- /dev/null +++ b/core/src/main/java/com/taobao/arthas/core/util/ApplicationUtils.java @@ -0,0 +1,32 @@ +package com.taobao.arthas.core.util; + +import java.lang.management.ManagementFactory; + +/** + * + * @author hengyunabc 2018-09-30 + * + */ +public class ApplicationUtils { + + private static String PID = "-1"; + + static { + // https://stackoverflow.com/a/7690178 + String jvmName = ManagementFactory.getRuntimeMXBean().getName(); + int index = jvmName.indexOf('@'); + + if (index > 0) { + try { + PID = Long.toString(Long.parseLong(jvmName.substring(0, index))); + } catch (Throwable e) { + // ignore + } + } + } + + public static String getPid() { + return PID; + } + +} diff --git a/core/src/main/java/com/taobao/arthas/core/util/Constants.java b/core/src/main/java/com/taobao/arthas/core/util/Constants.java index ad44cd31f..7a4517181 100644 --- a/core/src/main/java/com/taobao/arthas/core/util/Constants.java +++ b/core/src/main/java/com/taobao/arthas/core/util/Constants.java @@ -1,7 +1,6 @@ package com.taobao.arthas.core.util; import java.io.File; -import java.lang.management.ManagementFactory; import com.taobao.arthas.core.view.Ansi; @@ -46,7 +45,7 @@ public interface Constants { /** * 当前进程PID */ - String PID = ManagementFactory.getRuntimeMXBean().getName().split("@")[0]; + String PID = ApplicationUtils.getPid(); /** * 缓存目录 From da4f2172da04198c8e132c4b2c699bfef33e5ac8 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Sun, 30 Sep 2018 16:18:56 +0800 Subject: [PATCH 43/46] fix ObjectViewTest TimeZone problem. --- .../java/com/taobao/arthas/core/view/ObjectViewTest.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/test/java/com/taobao/arthas/core/view/ObjectViewTest.java b/core/src/test/java/com/taobao/arthas/core/view/ObjectViewTest.java index 8237bc3f7..5c38f35cd 100644 --- a/core/src/test/java/com/taobao/arthas/core/view/ObjectViewTest.java +++ b/core/src/test/java/com/taobao/arthas/core/view/ObjectViewTest.java @@ -8,6 +8,7 @@ import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.TimeZone; /** * @author ralf0131 2018-07-10 10:55. @@ -190,13 +191,14 @@ public class ObjectViewTest { @Test public void testDate() { - Date d = new Date(1531204354961L); + Date d = new Date(1531204354961L - TimeZone.getDefault().getRawOffset() + + TimeZone.getTimeZone("GMT+8").getRawOffset()); ObjectView objectView = new ObjectView(d, 3); String expected = "@Date[2018-07-10 14:32:34,961]"; Assert.assertEquals(expected, objectView.draw()); } - @Test + @Test public void testNestedClass() { ObjectView objectView = new ObjectView(new NestedClass(100), 3); From 5a775f99325b9e4daa3bfed4a91f2af3f7bb1442 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Sun, 30 Sep 2018 15:29:20 +0800 Subject: [PATCH 44/46] add travis and codecov support. fix #19 --- .travis.yml | 38 ++++++++++++++++++++++++++++++++++++++ pom.xml | 13 +++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..5a540d697 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,38 @@ +language: generic +sudo: false + +jdk: + - openjdk7 + - openjdk8 + - openjdk9 + - openjdk10 + - openjdk11 + - oraclejdk7 + - oraclejdk8 + - oraclejdk9 + - oraclejdk10 + - oraclejdk11 + +cache: + directories: + - "$HOME/.m2/repository" + - "$HOME/.m2/wrapper" +script: + - ./mvnw clean cobertura:cobertura package -P full -Dsphinx.binUrl=https://github.com/hengyunabc/sphinx-binary/releases/download/v0.4.0.1/sphinx.linux-x86_64 + +after_success: + - bash <(curl -s https://codecov.io/bash) + +notifications: + email: false + +deploy: + provider: releases + api_key: + - secure: "V+omzrcAJ/awN3EsDkiELejjInz/rpgPLdyb4uZrcQnqhagbHYE+nY2KcjPEtRBVNkqlh6dxIIsUFvKrs5kxe5EVvI6rLQeZLFMqWUeNfWuhbuQWCV9ZPyQiqXCqNicj+LLHArzQRLx5w5YBvxdzMuXSWo1ZE4wy+c3koprulUSjr6XhNPKyyasq4EXKMXuLCjcvBVPHhXviG59Jbshb2lRHbkxMqYeLhWi/gUOBRbNC1CmcGGAMviFX7HpBOx5fMaVKPR7rzcULw3lXnLhdSwhXJ6ybnsN/osfN8zAx6XZIwvwvVQ12yM8S9eVthnjblFh+WKwOT1AS6hHFXkMTjh1FE5CtUVu+sFbGIngJ4C4O78VzWCKvH/IrIi4p2IkF+fcu8USnm7YZGuyoAwe3O5PqmWBuQV0iCEx0IGo/nPwVzj1+jnz38Go/DP1aVDJZMenysBNxi4l45d3J3CgMPvF00DDQKvxYrkBjdnByANrOisZPjIeUOc7GsWoDLCK9jZtXMID2NM+ehQnDbOJ3BS2Bjg7ojPc0Rw2yJjbzwNqaMiOPXp2ym/5DpaB/l5k2gSi2NCRUFCXhFNRCq9ChFXv+pYJwk0e17sleGvo6tnFDVCR6lFcXrYo/vGC43bL1dT4rY8E6VSRlE0jfoXdFFp4jw3v3a+DqVLGVC9UcTpw=" + file_glob: true + file: "packaging/target/*.zip" + skip_cleanup: true + on: + tags: true + diff --git a/pom.xml b/pom.xml index be84ff8ac..ef569e0c9 100644 --- a/pom.xml +++ b/pom.xml @@ -225,6 +225,19 @@ + + + org.codehaus.mojo + cobertura-maven-plugin + 2.7 + + + html + xml + + + + From d98af5cc5a7cc3358176727533f68779c68a7650 Mon Sep 17 00:00:00 2001 From: hengyunabc Date: Sun, 30 Sep 2018 19:58:57 +0800 Subject: [PATCH 45/46] add badge into README.md --- README.md | 7 +++++++ README_CN.md | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/README.md b/README.md index c9eb14d75..934c85cbd 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,13 @@ ![arthas](site/src/site/sphinx/arthas.png) +[![Build Status](https://travis-ci.org/alibaba/arthas.svg?branch=master)](https://travis-ci.org/alibaba/arthas) +[![codecov](https://codecov.io/gh/alibaba/arthas/branch/master/graph/badge.svg)](https://codecov.io/gh/alibaba/arthas) +![maven](https://img.shields.io/maven-central/v/com.taobao.arthas/arthas-packaging.svg) +![license](https://img.shields.io/github/license/alibaba/arthas.svg) +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/alibaba/arthas.svg)](http://isitmaintained.com/project/alibaba/arthas "Average time to resolve an issue") +[![Percentage of issues still open](http://isitmaintained.com/badge/open/alibaba/arthas.svg)](http://isitmaintained.com/project/alibaba/arthas "Percentage of issues still open") + `Arthas` is a Java Diagnostic tool open sourced by Alibaba. Arthas help developers in trouble-shooting production issues for Java applications without modifying code or restarting servers. diff --git a/README_CN.md b/README_CN.md index 453666df8..4f38bee59 100644 --- a/README_CN.md +++ b/README_CN.md @@ -4,6 +4,13 @@ ![arthas](site/src/site/sphinx/arthas.png) +[![Build Status](https://travis-ci.org/alibaba/arthas.svg?branch=master)](https://travis-ci.org/alibaba/arthas) +[![codecov](https://codecov.io/gh/alibaba/arthas/branch/master/graph/badge.svg)](https://codecov.io/gh/alibaba/arthas) +![maven](https://img.shields.io/maven-central/v/com.taobao.arthas/arthas-packaging.svg) +![license](https://img.shields.io/github/license/alibaba/arthas.svg) +[![Average time to resolve an issue](http://isitmaintained.com/badge/resolution/alibaba/arthas.svg)](http://isitmaintained.com/project/alibaba/arthas "Average time to resolve an issue") +[![Percentage of issues still open](http://isitmaintained.com/badge/open/alibaba/arthas.svg)](http://isitmaintained.com/project/alibaba/arthas "Percentage of issues still open") + English version goes [here](README.md). `Arthas` 是Alibaba开源的Java诊断工具,深受开发者喜爱。 From b267a234d36b08858ee8da0f21875244985ea049 Mon Sep 17 00:00:00 2001 From: ufukoz Date: Fri, 5 Oct 2018 15:27:44 +0300 Subject: [PATCH 46/46] Add tests for a couple of methods of TypeRenderUtils --- .../arthas/core/util/TypeRenderUtilsTest.java | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 core/src/test/java/com/taobao/arthas/core/util/TypeRenderUtilsTest.java diff --git a/core/src/test/java/com/taobao/arthas/core/util/TypeRenderUtilsTest.java b/core/src/test/java/com/taobao/arthas/core/util/TypeRenderUtilsTest.java new file mode 100644 index 000000000..f90f93e6e --- /dev/null +++ b/core/src/test/java/com/taobao/arthas/core/util/TypeRenderUtilsTest.java @@ -0,0 +1,117 @@ +package com.taobao.arthas.core.util; + +import org.junit.Test; + +import java.io.Serializable; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class TypeRenderUtilsTest { + + + public class TestClass implements Serializable { + private int testField; + public char anotherTestField; + + public int testMethod(int i, boolean b) { + return 0; + } + + public void anotherTestMethod() throws NullPointerException { + + } + } + + @Test + public void testDrawInterface() { + assertThat(TypeRenderUtils.drawInterface(String.class), is(equalTo("java.io.Serializable,java.lang.Comparable,java.lang.CharSequence"))); + assertThat(TypeRenderUtils.drawInterface(TestClass.class), is(equalTo("java.io.Serializable"))); + assertThat(TypeRenderUtils.drawInterface(Serializable.class), is(equalTo(""))); + } + + @Test + public void testDrawParametersForMethod() throws NoSuchMethodException { + Class[] classesOfParameters = new Class[2]; + classesOfParameters[0] = int.class; + classesOfParameters[1] = boolean.class; + + assertThat(TypeRenderUtils.drawParameters(TestClass.class.getMethod("testMethod", classesOfParameters)), is(equalTo("int\nboolean"))); + assertThat(TypeRenderUtils.drawParameters(TestClass.class.getMethod("anotherTestMethod")), is(equalTo(""))); + + assertThat(TypeRenderUtils.drawParameters(String.class.getMethod("charAt", int.class)), is(equalTo("int"))); + assertThat(TypeRenderUtils.drawParameters(String.class.getMethod("isEmpty")), is(equalTo(""))); + } + + @Test(expected = NoSuchMethodException.class) + public void testDrawParametersForMethodThrowsException() throws NoSuchMethodException { + assertThat(TypeRenderUtils.drawParameters(TestClass.class.getMethod("method")), is(equalTo(""))); + } + + @Test + public void testDrawParametersForConstructor() throws NoSuchMethodException { + Class[] classesOfParameters = new Class[3]; + classesOfParameters[0] = char[].class; + classesOfParameters[1] = int.class; + classesOfParameters[2] = int.class; + + assertThat(TypeRenderUtils.drawParameters(String.class.getConstructor(classesOfParameters)), is(equalTo("[]\nint\nint"))); + assertThat(TypeRenderUtils.drawParameters(String.class.getConstructor()), is(equalTo(""))); + } + + @Test(expected = NoSuchMethodException.class) + public void testDrawParametersForConstructorThrowsException() throws NoSuchMethodException { + assertThat(TypeRenderUtils.drawParameters(TestClass.class.getConstructor()), is(equalTo(""))); + } + + @Test + public void testDrawReturn() throws NoSuchMethodException { + Class[] classesOfParameters = new Class[2]; + classesOfParameters[0] = int.class; + classesOfParameters[1] = boolean.class; + + assertThat(TypeRenderUtils.drawReturn(TestClass.class.getMethod("testMethod", classesOfParameters)), is(equalTo("int"))); + assertThat(TypeRenderUtils.drawReturn(TestClass.class.getMethod("anotherTestMethod")), is(equalTo("void"))); + + assertThat(TypeRenderUtils.drawReturn(String.class.getMethod("isEmpty")), is(equalTo("boolean"))); + } + + @Test(expected = NoSuchMethodException.class) + public void testDrawReturnThrowsException() throws NoSuchMethodException { + assertThat(TypeRenderUtils.drawReturn(TestClass.class.getMethod("method")), is(equalTo(""))); + } + + @Test + public void testDrawExceptionsForMethod() throws NoSuchMethodException { + Class[] classesOfParameters = new Class[2]; + classesOfParameters[0] = int.class; + classesOfParameters[1] = boolean.class; + + assertThat(TypeRenderUtils.drawExceptions(TestClass.class.getMethod("testMethod", classesOfParameters)), is(equalTo(""))); + assertThat(TypeRenderUtils.drawExceptions(TestClass.class.getMethod("anotherTestMethod")), is(equalTo("java.lang.NullPointerException"))); + + assertThat(TypeRenderUtils.drawExceptions(String.class.getMethod("getBytes", String.class)), is(equalTo("java.io.UnsupportedEncodingException"))); + } + + @Test(expected = NoSuchMethodException.class) + public void testDrawExceptionsForMethodThrowsException() throws NoSuchMethodException { + assertThat(TypeRenderUtils.drawExceptions(TestClass.class.getMethod("method")), is(equalTo(""))); + } + + @Test + public void testDrawExceptionsForConstructor() throws NoSuchMethodException { + Class[] classesOfConstructorParameters = new Class[2]; + classesOfConstructorParameters[0] = byte[].class; + classesOfConstructorParameters[1] = String.class; + + assertThat(TypeRenderUtils.drawExceptions(String.class.getConstructor()), is(equalTo(""))); + assertThat(TypeRenderUtils.drawExceptions(String.class.getConstructor(classesOfConstructorParameters)), is(equalTo("java.io.UnsupportedEncodingException"))); + } + + @Test(expected = NoSuchMethodException.class) + public void testDrawExceptionsForConstructorThrowsException() throws NoSuchMethodException { + assertThat(TypeRenderUtils.drawExceptions(TestClass.class.getConstructor()), is(equalTo(""))); + } + +} \ No newline at end of file