update doc

This commit is contained in:
hengyunabc committed 2018-09-21 17:49:43 +08:00
1 parent 711c3fe925
commit 5b8ade6f24
28 files changed
+3159 -71

No files matched your search

+114
View File
@@ -0,0 +1,114 @@
stack
=====
Print out the full call stack trace containing 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.
### Parameters
|Name|Specification|
|---:|:---|
|*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|
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.
Attention:
1. `$cost` can be used in `watch/stack/trace`;
2. using `#cost` in Arthas 3.0 instead of `$cost`.
Advanced:
* [Critical fields in expression](advice-class.md)
* [Special usage](https://github.com/alibaba/arthas/issues/71)
* [OGNL official guide](https://commons.apache.org/proper/commons-ognl/language-guide.html)
### Usage
The quoting rules: if there are quotes within the expression, use another type of quotes to quote the whole expression.
```
$ stack com.alibaba.sample.petstore.dal.dao.ProductDao getProductById 'params[0]=="K9-BD-01"'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 51 ms.
thread_name="http-bio-8080-exec-4" thread_id=0x4a;is_daemon=true;priority=5;
@com.alibaba.sample.petstore.dal.dao.ibatis.IbatisProductDao.getProductById()
at com.alibaba.sample.petstore.web.store.module.screen.ItemList.execute(ItemList.java:50)
at com.alibaba.sample.petstore.web.store.module.screen.ItemList$$FastClassByCGLIB$$40b2f45f.invoke(<generated>:-1)
at net.sf.cglib.reflect.FastMethod.invoke(FastMethod.java:53)
at com.alibaba.citrus.service.moduleloader.impl.adapter.MethodInvoker.invoke(MethodInvoker.java:70)
at com.alibaba.citrus.service.moduleloader.impl.adapter.DataBindingAdapter.executeAndReturn(DataBindingAdapter.java:41)
at com.alibaba.citrus.turbine.pipeline.valve.PerformScreenValve.performScreenModule(PerformScreenValve.java:111)
at com.alibaba.citrus.turbine.pipeline.valve.PerformScreenValve.invoke(PerformScreenValve.java:74)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.PerformActionValve.invoke(PerformActionValve.java:73)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invoke(PipelineImpl.java:210)
......
thread_name="http-bio-8080-exec-2" thread_id=0x48;is_daemon=true;priority=5;
@com.alibaba.sample.petstore.dal.dao.ibatis.IbatisProductDao.getProductById()
at com.alibaba.sample.petstore.web.store.module.screen.ItemList.execute(ItemList.java:50)
at com.alibaba.sample.petstore.web.store.module.screen.ItemList$$FastClassByCGLIB$$40b2f45f.invoke(<generated>:-1)
at net.sf.cglib.reflect.FastMethod.invoke(FastMethod.java:53)
at com.alibaba.citrus.service.moduleloader.impl.adapter.MethodInvoker.invoke(MethodInvoker.java:70)
at com.alibaba.citrus.service.moduleloader.impl.adapter.DataBindingAdapter.executeAndReturn(DataBindingAdapter.java:41)
at com.alibaba.citrus.turbine.pipeline.valve.PerformScreenValve.performScreenModule(PerformScreenValve.java:111)
at com.alibaba.citrus.turbine.pipeline.valve.PerformScreenValve.invoke(PerformScreenValve.java:74)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.PerformActionValve.invoke(PerformActionValve.java:73)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
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:
```
$ stack com.alibaba.sample.petstore.web.store.module.screen.ItemList execute #cost>30
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 123 ms.
stack com.alibaba.sample.petstore.web.store.module.screen.ItemList execute #cost>30
thread_name=http-nio-8080-exec-10;id=31;is_daemon=true;priority=5;TCCL=com.taobao.pandora.boot.embedded.tomcat.TomcatEmbeddedWebappClassLoader
@com.alibaba.sample.petstore.web.store.module.screen.ItemList.execute()
at com.alibaba.sample.petstore.web.store.module.screen.ItemList$$FastClassByCGLIB$$40b2f45f.invoke(<generated>:-1)
at net.sf.cglib.reflect.FastMethod.invoke(FastMethod.java:53)
at com.alibaba.citrus.service.moduleloader.impl.adapter.MethodInvoker.invoke(MethodInvoker.java:70)
at com.alibaba.citrus.service.moduleloader.impl.adapter.DataBindingAdapter.executeAndReturn(DataBindingAdapter.java:41)
at com.alibaba.citrus.turbine.pipeline.valve.PerformScreenValve.performScreenModule(PerformScreenValve.java:111)
at com.alibaba.citrus.turbine.pipeline.valve.PerformScreenValve.invoke(PerformScreenValve.java:74)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.PerformActionValve.invoke(PerformActionValve.java:73)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
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)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invoke(PipelineImpl.java:210)
at com.alibaba.citrus.service.pipeline.impl.valve.LoopValve.invokeBody(LoopValve.java:105)
at com.alibaba.citrus.service.pipeline.impl.valve.LoopValve.invoke(LoopValve.java:83)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.PageAuthorizationValve.invoke(PageAuthorizationValve.java:105)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.CheckCsrfTokenValve.invoke(CheckCsrfTokenValve.java:123)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.AnalyzeURLValve.invoke(AnalyzeURLValve.java:126)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.SetLoggingContextValve.invoke(SetLoggingContextValve.java:66)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.PrepareForTurbineValve.invoke(PrepareForTurbineValve.java:52)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invoke(PipelineImpl.java:210)
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)
.........
```
+76
View File
@@ -0,0 +1,76 @@
Start Arthas
=====
## Interactive Mode
```bash
./as.sh
```
```sh
➜ bin git:(develop) ✗ ./as.sh
Found existing java process, please choose one and hit RETURN.
[1]: 3088 org.jetbrains.idea.maven.server.RemoteMavenServer
* [2]: 12872 org.apache.catalina.startup.Bootstrap
[3]: 2455
Attaching to 12872...
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
$
```
## Non-Interactive Mode
Startup script is as follows:
```bash
./as.sh <PID>[@IP:PORT]
```
### Parameter Description
* PID: Target Java process ID(Make sure that the user executing the command has sufficient permissions to operate the target Java process.)
* IP: The address that Arthas Server listens on, the default value is `127.0.0.1`. Arthas allows multiple users to access simultaneously without interfering with each other.
* PORT: Arthas Server port,the default value is 3658
### Sample
* If you do not specify IP and PORT, the default is 127.0.0.1 and 3658
> ./as.sh 12345
Equivalent to:
> ./as.sh 12356@127.0.0.1:3658
### Remote Diagnosis
After starting Arthas Server, users can use `telnet` connect to the remote Arthas Server, for example:
```bash
telnet 192.168.1.119 3658
```
### sudo Support
If you need to switch users, such as `admin`, you need to add the -H parameter.
```bash
sudo -u admin -H ./as.sh 12345
```
### Windows Support
`as.bat` script only supports one parameter: pid
```bash
as.bat <pid>
```
+108
View File
@@ -0,0 +1,108 @@
trace
=====
Track the `class-pattern` & `method-pattern` matched method calling trace and print the time cost in each call.
### Parameters
|Name|Specification|
|---:|:---|
|*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|
|`#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.
Attention:
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)
* [OGNL official guide](https://commons.apache.org/proper/commons-ognl/language-guide.html)
### Usage
A demo:
```java
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
List<String> list2 = new ArrayList<String>();
list2.add("c");
list2.add("d");
int len = add(list, list2);
}
private static int add(List<String> list, List<String> list2) {
int i = 10;
while (i >= 0) {
try {
hehe(i);
} catch (Throwable t) {
t.printStackTrace();
}
i--;
}
list.addAll(list2);
return list.size();
}
private static void hehe(int i) {
if (i == 0) {
throw new RuntimeException("ZERO");
}
}
```
Tracing down method `add`:
```shell
$ trace com.alibaba.sample.petstore.web.store.module.screen.ItemList add params.length==2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 144 ms.
`---Tracing...
`---[2ms]com.alibaba.sample.petstore.web.store.module.screen.ItemList:add()
+---[0,0,0ms,11]com.alibaba.sample.petstore.web.store.module.screen.ItemList:hehe() [throws Exception]
+---[1ms]java.lang.Throwable:printStackTrace()
+---[0ms]java.util.List:addAll()
`---[0ms]java.util.List:size()
```
Filtering by time cost:
```shell
$ trace com.alibaba.sample.petstore.web.store.module.screen.ItemList execute #cost>4
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 159 ms.
trace com.alibaba.sample.petstore.web.store.module.screen.ItemList execute #cost>4
`---thread_name=http-nio-8080-exec-5;id=2c;is_daemon=true;priority=5;TCCL=com.taobao.pandora.boot.embedded.tomcat.TomcatEmbeddedWebappClassLoader
`---[8.866586ms] com.alibaba.sample.petstore.web.store.module.screen.ItemList:execute()
+---[2.847106ms] com.alibaba.sample.petstore.biz.StoreManager:getAllProductItems()
+---[0.765544ms] com.alibaba.sample.petstore.dal.dao.ProductDao:getProductById()
+---[0.021204ms] com.alibaba.sample.petstore.dal.dataobject.Product:getCategoryId()
+---[1.341532ms] com.alibaba.sample.petstore.dal.dao.CategoryDao:getCategoryById()
`---[min=0.005428ms,max=0.094064ms,total=0.105228ms,count=3] com.alibaba.citrus.turbine.Context:put()
```
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;
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;
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.
+194
View File
@@ -0,0 +1,194 @@
tt
==
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.
### Usage
Let's record the whole calling contexts:
```java
$ tt -t -n 3 *Test print
Press Ctrl+D or Ctrl+X to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 115 ms.
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| INDEX | TIMESTAMP | COST(ms) | IS-RET | IS-EXP | OBJECT | CLASS | METHOD |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1007 | 2015-07-26 12:23:21 | 138 | true | false | 0x42cc13a0 | GaOgnlUtilsTest | print |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1008 | 2015-07-26 12:23:22 | 143 | true | false | 0x42cc13a0 | GaOgnlUtilsTest | print |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1009 | 2015-07-26 12:23:23 | 130 | true | false | 0x42cc13a0 | GaOgnlUtilsTest | print |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
$
```
#### F.Y.I
- `-t`
record the calling context of the method `*Test.print`
- `-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)
#### Property
|Name|Specification|
|---|---|
|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|
|OBJECT|`hashCode()` of the object invoking the method|
|CLASS|class name of the object invoking the method|
|METHOD|method being invoked|
#### Condition expression
Tips:
1. `tt -t *Test print params[0].length==1` with different amount 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.
Advanced:
* [Critical fields in expression](advice-class.md)
* [Special usage](https://github.com/alibaba/arthas/issues/71)
* [OGNL official guide](https://commons.apache.org/proper/commons-ognl/language-guide.html)
### Searching for records
#### A specified time range
```
$ tt -l
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| INDEX | TIMESTAMP | COST(ms) | IS-RET | IS-EXP | OBJECT | CLASS | METHOD |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1000 | 2015-07-26 01:16:27 | 130 | true | false | 0x42cc13a0 | GaOgnlUtilsTest | print |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1001 | 2015-07-26 01:16:27 | 0 | false | true | 0x42cc13a0 | GaOgnlUtilsTest | printAddress |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1002 | 2015-07-26 01:16:28 | 119 | true | false | 0x42cc13a0 | GaOgnlUtilsTest | print |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1003 | 2015-07-26 01:16:28 | 0 | false | true | 0x42cc13a0 | GaOgnlUtilsTest | printAddress |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1004 | 2015-07-26 12:21:56 | 130 | true | false | 0x42cc13a0 | GaOgnlUtilsTest | print |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1005 | 2015-07-26 12:21:57 | 138 | true | false | 0x42cc13a0 | GaOgnlUtilsTest | print |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1006 | 2015-07-26 12:21:58 | 130 | true | false | 0x42cc13a0 | GaOgnlUtilsTest | print |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
Affect(row-cnt:7) cost in 2 ms.
$
```
#### A specified method
```
$ tt -s method.name=="printAddress"
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| INDEX | TIMESTAMP | COST(ms) | IS-RET | IS-EXP | OBJECT | CLASS | METHOD |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1001 | 2015-07-26 01:16:27 | 0 | false | true | 0x42cc13a0 | GaOgnlUtilsTest | printAddress |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
| 1003 | 2015-07-26 01:16:28 | 0 | false | true | 0x42cc13a0 | GaOgnlUtilsTest | printAddress |
+----------+----------------------+------------+----------+----------+-----------------+--------------------------------+--------------------------------+
Affect(row-cnt:2) cost in 55 ms.
$
```
Advanced:
* [Critical fields in expression](advice-class.md)
### Check context of the call
Using `tt -i <index>` to check a specific record.
```
$
$ tt -i 1003
+-----------------+------------------------------------------------------------------------------------------------------+
| INDEX | 1003 |
+-----------------+------------------------------------------------------------------------------------------------------+
| GMT-CREATE | 2015-07-26 01:16:28 |
+-----------------+------------------------------------------------------------------------------------------------------+
| COST(ms) | 0 |
+-----------------+------------------------------------------------------------------------------------------------------+
| OBJECT | 0x42cc13a0 |
+-----------------+------------------------------------------------------------------------------------------------------+
| CLASS | GaOgnlUtilsTest |
+-----------------+------------------------------------------------------------------------------------------------------+
| METHOD | printAddress |
+-----------------+------------------------------------------------------------------------------------------------------+
| IS-RETURN | false |
+-----------------+------------------------------------------------------------------------------------------------------+
| IS-EXCEPTION | true |
+-----------------+------------------------------------------------------------------------------------------------------+
| PARAMETERS[0] | Address@53448f87 |
+-----------------+------------------------------------------------------------------------------------------------------+
| THROW-EXCEPTION | java.lang.RuntimeException: test |
| | at GaOgnlUtilsTest.printAddress(Unknown Source) |
| | at GaOgnlUtilsTest.<init>(Unknown Source) |
| | at GaOgnlUtilsTest.main(Unknown Source) |
+-----------------+------------------------------------------------------------------------------------------------------+
Affect(row-cnt:1) cost in 1 ms.
$
```
### 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`.
```
$ tt -i 1003 -p
+-----------------+---------------------------------------------------------------------------------------------------------+
| RE-INDEX | 1003 |
+-----------------+---------------------------------------------------------------------------------------------------------+
| GMT-REPLAY | 2015-07-26 17:29:51 |
+-----------------+---------------------------------------------------------------------------------------------------------+
| OBJECT | 0x42cc13a0 |
+-----------------+---------------------------------------------------------------------------------------------------------+
| CLASS | GaOgnlUtilsTest |
+-----------------+---------------------------------------------------------------------------------------------------------+
| METHOD | printAddress |
+-----------------+---------------------------------------------------------------------------------------------------------+
| PARAMETERS[0] | Address@53448f87 |
+-----------------+---------------------------------------------------------------------------------------------------------+
| IS-RETURN | false |
+-----------------+---------------------------------------------------------------------------------------------------------+
| IS-EXCEPTION | true |
+-----------------+---------------------------------------------------------------------------------------------------------+
| THROW-EXCEPTION | java.lang.RuntimeException: test |
| | at GaOgnlUtilsTest.printAddress(GaOgnlUtilsTest.java:78) |
| | at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) |
| | at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) |
| | at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) |
| | at java.lang.reflect.Method.invoke(Method.java:483) |
| | at com.github.ompc.Arthas.util.GaMethod.invoke(GaMethod.java:81) |
| | at com.github.ompc.Arthas.command.TimeTunnelCommand$6.action(TimeTunnelCommand.java:592) |
| | at com.github.ompc.Arthas.server.DefaultCommandHandler.execute(DefaultCommandHandler.java:175) |
| | at com.github.ompc.Arthas.server.DefaultCommandHandler.executeCommand(DefaultCommandHandler.java:83) |
| | at com.github.ompc.Arthas.server.GaServer$4.run(GaServer.java:329) |
| | at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) |
| | at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) |
| | at java.lang.Thread.run(Thread.java:745) |
+-----------------+---------------------------------------------------------------------------------------------------------+
replay time fragment[1003] success.
Affect(row-cnt:1) cost in 3 ms.
$
```
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.
+300
View File
@@ -0,0 +1,300 @@
watch
=====
Monitor the methods in data aspect including `return value`, `exceptions` and `parameters`.
With the help of [OGNL](https://en.wikipedia.org/wiki/OGNL), you can easily check the details of the variables.
### Parameters & Options
There are four different usage scenarios for `watch` command, which makes it the most 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|
|[e]|encountering exceptions|
|[s]|returned normally|
|[f]|returned normally and abnormally|
|[E]|turn on regx 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`.
Advanced:
* [Critical fields in expression](advice-class.md)
* [Special usage](https://github.com/alibaba/arthas/issues/71)
* [OGNL official guide](https://commons.apache.org/proper/commons-ognl/language-guide.html)
### Usage
A demo:
```java
public void execute() {
List<String> list = new ArrayList<String>();
list.add("a");
list.add("b");
List<String> list2 = new ArrayList<String>();
list2.add("c");
list2.add("d");
int len = add(list, list2);
}
private static int add(List<String> list, List<String> list2) {
list.addAll(list2);
return list.size();
}
```
#### Check the `out-parameters`and `return value`
```shell
$ watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "{params,returnObj}" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 44 ms.
@ArrayList[
@Object[][
@ArrayList[isEmpty=false;size=4],
@ArrayList[isEmpty=false;size=2],
],
@Integer[4],
]
```
#### Check `in-parameters`
```shell
$ watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "{params,returnObj}" -x 2 -b
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 48 ms.
@ArrayList[
@Object[][
@ArrayList[isEmpty=false;size=2],
@ArrayList[isEmpty=false;size=2],
],
null,
]
```
Compared to the previous *check*:
1. size of `params[0]` is `2` instead of `4`;
2. `return value` is `null` since it's `-b`.
#### Check *before* and *after* at the same time
```shell
$ watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "{params,returnObj}" -x 2 -b -s
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 59 ms.
@ArrayList[
@Object[][
@ArrayList[isEmpty=false;size=2],
@ArrayList[isEmpty=false;size=2],
],
null,
]
@ArrayList[
@Object[][
@ArrayList[isEmpty=false;size=4],
@ArrayList[isEmpty=false;size=2],
],
@Integer[4],
]
```
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
```shell
$ watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "{params,returnObj}" -x 3
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 59 ms.
@ArrayList[
@Object[][
@ArrayList[
@String[a],
@String[b],
@String[c],
@String[d],
],
@ArrayList[
@String[c],
@String[d],
],
],
@Integer[4],
]
```
#### Using condition expressions to locate specific call
```shell
$ watch com.alibaba.sample.petstore.biz.impl.UserManagerImpl testAdd "{params, returnObj}" "params[0].equals('aaa')" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 29 ms.
@ArrayList[
@Object[][
@String[aaa],
@String[bbb],
],
@Integer[6],
]
```
#### Check `exceptions`
```shell
$ watch com.alibaba.sample.petstore.biz.impl.UserManagerImpl testAdd "{params, throwExp}" -e -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 29 ms.
@ArrayList[
@Object[][
@String[aaa],
@String[bbb],
],
java.lang.NullPointerException
at com.alibaba.sample.petstore.biz.impl.UserManagerImpl.testAdd(UserManagerImpl.java:75)
at com.alibaba.sample.petstore.biz.impl.UserManagerImpl.register(UserManagerImpl.java:60)
at com.alibaba.sample.petstore.web.user.module.action.RegisterAction.doRegister(RegisterAction.java:45)
at com.alibaba.sample.petstore.web.user.module.action.RegisterAction$$FastClassByCGLIB$$ad5428f1.invoke(<generated>)
at net.sf.cglib.reflect.FastMethod.invoke(FastMethod.java:53)
at com.alibaba.citrus.service.moduleloader.impl.adapter.MethodInvoker.invoke(MethodInvoker.java:70)
at com.alibaba.citrus.service.moduleloader.impl.adapter.AbstractModuleEventAdapter.executeAndReturn(AbstractModuleEventAdapter.java:100)
at com.alibaba.citrus.service.moduleloader.impl.adapter.AbstractModuleEventAdapter.execute(AbstractModuleEventAdapter.java:58)
at com.alibaba.citrus.turbine.pipeline.valve.PerformActionValve.invoke(PerformActionValve.java:63)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
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)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invoke(PipelineImpl.java:210)
at com.alibaba.citrus.service.pipeline.impl.valve.LoopValve.invokeBody(LoopValve.java:105)
at com.alibaba.citrus.service.pipeline.impl.valve.LoopValve.invoke(LoopValve.java:83)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.PageAuthorizationValve.invoke(PageAuthorizationValve.java:105)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.CheckCsrfTokenValve.invoke(CheckCsrfTokenValve.java:123)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.AnalyzeURLValve.invoke(AnalyzeURLValve.java:126)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.SetLoggingContextValve.invoke(SetLoggingContextValve.java:66)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.turbine.pipeline.valve.PrepareForTurbineValve.invoke(PrepareForTurbineValve.java:52)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invokeNext(PipelineImpl.java:157)
at com.alibaba.citrus.service.pipeline.impl.PipelineImpl$PipelineContextImpl.invoke(PipelineImpl.java:210)
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)
at com.alibaba.citrus.webx.servlet.WebxFrameworkFilter.doFilter(WebxFrameworkFilter.java:152)
at com.alibaba.citrus.webx.servlet.FilterBean.doFilter(FilterBean.java:148)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at com.alibaba.citrus.webx.servlet.SetLoggingContextFilter.doFilter(SetLoggingContextFilter.java:61)
at com.alibaba.citrus.webx.servlet.FilterBean.doFilter(FilterBean.java:148)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at com.taobao.tomcat.valves.ContextLoadFilterValve.invoke(ContextLoadFilterValve.java:152)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:429)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1760)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1719)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745),
]
```
#### Filter based on time cost
```shell
$ watch com.alibaba.sample.petstore.web.store.module.screen.ItemList add "{params,returnObj}" #cost>200 -x 3
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 59 ms.
@ArrayList[
@Object[][
@ArrayList[
@String[a],
@String[b],
@String[c],
@String[d],
],
@ArrayList[
@String[c],
@String[d],
],
],
@Integer[4],
]
```
F.Y.I
`#cost>200` (`ms`) filter out all invokings that take less than `200ms`.
#### Check the global properties of the target object
`target` stands for the current object.
```
$ watch com.taobao.container.web.arthas.rest.MyAppsController myFavoriteApps 'target'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 128 ms.
ts=2017-10-31 18:45:55;result=@MyAppsController[
myFavAppsMapper=@$Proxy131[org.apache.ibatis.binding.MapperProxy@563e97f3],
getAppNameAndIdByEmpId=@$Proxy135[HardCodedTarget(type=GetAppNameAndIdByEmpId, url=http://hello.com)],
enableWebConsoleAppsMapper=@$Proxy132[org.apache.ibatis.binding.MapperProxy@7d51e4a8],
]
```
`target.field_name` stands for a global property of the current object.
```
$ watch com.taobao.container.web.arthas.rest.MyAppsController myFavoriteApps 'target.myFavAppsMapper'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 126 ms.
ts=2017-10-31 18:46:17;result=@$Proxy131[
m1=@Method[public boolean java.lang.Object.equals(java.lang.Object)],
m2=@Method[public java.lang.String java.lang.Object.toString()],
m5=@Method[public abstract java.util.List com.taobao.container.dal.arthas.mapper.MyFavAppsMapper.listFavApps(java.util.Map)],
m3=@Method[public abstract int com.taobao.container.dal.arthas.mapper.MyFavAppsMapper.delete(java.lang.String,java.lang.String,java.lang.String)],
m4=@Method[public abstract long com.taobao.container.dal.arthas.mapper.MyFavAppsMapper.insert(com.taobao.container.dal.arthas.domain.MyFavAppsDO)],
m0=@Method[public native int java.lang.Object.hashCode()],
]
```