mirror of https://github.com/alibaba/arthas.git
remove katacoda
parent
2f5ab94032
commit
18ea7d2736
@ -1 +0,0 @@
|
||||
scenario_root : tutorials/katacoda
|
@ -1,37 +0,0 @@
|
||||
# Interactive Katacoda Online Tutorials for Arthas
|
||||
|
||||
[![](http://shields.katacoda.com/katacoda/arthas/count.svg)](https://www.katacoda.com/arthas "Get your profile on Katacoda.com")
|
||||
|
||||
[中文说明/Chinese Documentation](README_CN.md)
|
||||
|
||||
## Online Tutorial Usages
|
||||
|
||||
1. First visit the online tutorial: https://arthas.aliyun.com/doc/arthas-tutorials.html?language=en , select the course you want to study from the menu:
|
||||
![](https://user-images.githubusercontent.com/43995067/90310125-2a9bf480-df21-11ea-819d-2713f22f4145.png)
|
||||
|
||||
2. The course introduction page will indicate the difficulty of the course and the time required to help you understand the basic information of the course. click `START SCENARIO` to start learning.
|
||||
![](https://user-images.githubusercontent.com/43995067/90310168-9ed69800-df21-11ea-93cf-a01b4a41c66b.png)
|
||||
|
||||
3. Enter the course, the left side is the description of this step, and the right side is a ready terminal, which can be used directly. Click the black blocks on the left to execute commands in the right:
|
||||
![](https://user-images.githubusercontent.com/43995067/90310223-3d62f900-df22-11ea-936c-deb950e61f9e.png)
|
||||
|
||||
4. Click the tab on the right to switch between terminals. Then follow the step-by-step instructions to complete the learning step by step:
|
||||
![](https://user-images.githubusercontent.com/43995067/90310282-b8c4aa80-df22-11ea-8052-3799277b748e.png)
|
||||
|
||||
## Contribution Guide
|
||||
|
||||
If you want to contribute to the Arthas online tutorials, you are welcome to submit pull requests for the Arthas online tutorials.
|
||||
|
||||
Visit https://www.katacoda.com/docs to learn more about creating Katacoda scenarios. You can also refer to the article of Alibaba cloud developer community here(In Chinese): https://developer.aliyun.com/article/752183
|
||||
|
||||
For examples of the scenarios folder, visit https://github.com/katacoda/scenario-example
|
||||
|
||||
After that, if you have finished doing writing jobs, You just need to put your scenarios folder here in this folder, and add links in the related pages, that's all.
|
||||
|
||||
Menu page source code is at https://github.com/alibaba/arthas/blob/master/site/src/site/sphinx/_include_html/arthas-tutorials.html
|
||||
|
||||
## About
|
||||
|
||||
This project is a part of [Alibaba Summer of Code 2020](https://www.alibabacloud.com/campaign/summerofcode2020) done by [@HollowMan6](https://github.com/HollowMan6), for more information please visit: https://github.com/HollowMan6/My-Alibaba-Summer-of-Code
|
||||
|
||||
Issue: [#847](https://github.com/alibaba/arthas/issues/847)
|
@ -1,9 +0,0 @@
|
||||
|
||||
可以通过 `jad` 命令来反编译代码:
|
||||
|
||||
`jad com.example.demo.arthas.user.UserController`{{execute T2}}
|
||||
|
||||
|
||||
通过`--source-only`参数可以只打印出在反编译的源代码:
|
||||
|
||||
`jad --source-only com.example.demo.arthas.user.UserController`{{execute T2}}
|
@ -1,30 +0,0 @@
|
||||
|
||||
|
||||
`arthas-boot.jar` supports many parameters and can be viewed by `java -jar arthas-boot.jar -h`{{execute T2}}.
|
||||
|
||||
## Allow external network access
|
||||
|
||||
By default, the arthas server listens for the IP of `127.0.0.1`. If you want remote access, you can use the `--target-ip` option.
|
||||
|
||||
`java -jar arthas-boot.jar --target-ip`{{execute T2}}
|
||||
|
||||
|
||||
## List all versions
|
||||
|
||||
|
||||
`java -jar arthas-boot.jar --versions`{{execute T2}}
|
||||
|
||||
Use the specified version:
|
||||
|
||||
`java -jar arthas-boot.jar --use-version 3.1.0`{{execute T2}}
|
||||
|
||||
## Only listens at the Telnet port and does not listen at the HTTP port.
|
||||
|
||||
`java -jar arthas-boot.jar --telnet-port 9999 --http-port -1`{{execute T2}}
|
||||
|
||||
## Print verbose information
|
||||
|
||||
`java -jar arthas-boot.jar -v`{{execute T2}}
|
||||
|
||||
|
||||
|
@ -1,140 +0,0 @@
|
||||
|
||||
|
||||
The following describes the usage of the `classloader` command.
|
||||
|
||||
First visit the jsp page: https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/hello
|
||||
|
||||
### List all ClassLoaders
|
||||
|
||||
`classloader -l`{{execute T2}}
|
||||
|
||||
```bash
|
||||
$ classloader -l
|
||||
name loadedCount hash parent
|
||||
BootstrapClassLoader 2724 null null
|
||||
com.taobao.arthas.agent.ArthasClassloader@411ce1ab 2009 411ce1ab sun.misc.Launcher$ExtClassLoader@7494e528
|
||||
com.taobao.arthas.agent.ArthasClassloader@22ae1234 1253 22ae1234 sun.misc.Launcher$ExtClassLoader@7494e528
|
||||
org.apache.jasper.servlet.JasperLoader@65361d9a 1 65361d9a TomcatEmbeddedWebappClassLoader
|
||||
context: ROOT
|
||||
delegate: true
|
||||
----------> Parent Classloader:
|
||||
org.springframework.boot.loader.LaunchedURLClassLoader@1be6f5c3
|
||||
|
||||
TomcatEmbeddedWebappClassLoader 0 8546cd5 org.springframework.boot.loader.LaunchedURLClassLoader@1be6f5c3
|
||||
context: ROOT
|
||||
delegate: true
|
||||
----------> Parent Classloader:
|
||||
org.springframework.boot.loader.LaunchedURLClassLoader@1be6f5c3
|
||||
|
||||
org.springframework.boot.loader.LaunchedURLClassLoader@1be6f5c3 5416 1be6f5c3 sun.misc.Launcher$AppClassLoader@3d4eac69
|
||||
sun.misc.Launcher$AppClassLoader@3d4eac69 45 3d4eac69 sun.misc.Launcher$ExtClassLoader@7494e528
|
||||
sun.misc.Launcher$ExtClassLoader@7494e528 4 7494e528 null
|
||||
```
|
||||
|
||||
* The number of classes loaded by TomcatEmbeddedWebappClassLoader is 0, so in spring boot embedded tomcat, it is just an empty ClassLoader, all the classes are loaded by `LaunchedURLClassLoader`
|
||||
|
||||
|
||||
### List all classes loaded in ClassLoader
|
||||
|
||||
List all classes loaded by `org.apache.jasper.servlet.JasperLoader`:
|
||||
|
||||
`classloader -a --classLoaderClass org.apache.jasper.servlet.JasperLoader`{{execute T2}}
|
||||
|
||||
```bash
|
||||
$ classloader -a --classLoaderClass apache.jasper.servlet.JasperLoader
|
||||
hash:1698045338, org.apache.jasper.servlet.JasperLoader@65361d9a
|
||||
org.apache.jsp.jsp.hello_jsp
|
||||
```
|
||||
|
||||
* PS: Same as `ognl`, you can also use `-c <hashcode>` instead of `--classLoaderClass` to specify
|
||||
|
||||
### Decompile dynamically generated jsp classes
|
||||
|
||||
`jad org.apache.jsp.jsp.hello_jsp`{{execute T2}}
|
||||
|
||||
```bash
|
||||
$ jad org.apache.jsp.jsp.hello_jsp
|
||||
|
||||
ClassLoader:
|
||||
+-org.apache.jasper.servlet.JasperLoader@65361d9a
|
||||
+-TomcatEmbeddedWebappClassLoader
|
||||
context: ROOT
|
||||
...
|
||||
```
|
||||
|
||||
### View the ClassLoader tree
|
||||
|
||||
|
||||
`classloader -t`{{execute T2}}
|
||||
|
||||
```
|
||||
$ classloader -t
|
||||
+-BootstrapClassLoader
|
||||
+-sun.misc.Launcher$ExtClassLoader@28cbbddd
|
||||
+-com.taobao.arthas.agent.ArthasClassloader@8c25e55
|
||||
+-sun.misc.Launcher$AppClassLoader@55f96302
|
||||
+-org.springframework.boot.loader.LaunchedURLClassLoader@1be6f5c3
|
||||
+-TomcatEmbeddedWebappClassLoader
|
||||
context: ROOT
|
||||
delegate: true
|
||||
----------> Parent Classloader:
|
||||
org.springframework.boot.loader.LaunchedURLClassLoader@1be6f5c3
|
||||
|
||||
+-org.apache.jasper.servlet.JasperLoader@21ae0fe2
|
||||
```
|
||||
|
||||
Note: Please replace `<classLoaderHash>` with your classLoaderHash above, then execute the related commands manually in the following steps:
|
||||
|
||||
### List the urls of the ClassLoader
|
||||
|
||||
For example, the hashcode of spring `LaunchedURLClassLoader` viewed above is `1be6f5c3`, and all its urls can be listed by the `-c` parameter:
|
||||
|
||||
`classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader`{{execute T2}}
|
||||
|
||||
```
|
||||
$ classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader
|
||||
jar:file:/home/scrapbook/tutorial/demo-arthas-spring-boot.jar!/BOOT-INF/classes!/
|
||||
jar:file:/home/scrapbook/tutorial/demo-arthas-spring-boot.jar!/BOOT-INF/lib/spring-boot-starter-aop-1.5
|
||||
.13.RELEASE.jar!/
|
||||
...
|
||||
```
|
||||
|
||||
### Load the resource file in the specified ClassLoader
|
||||
|
||||
Load the specified resource file: `classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader -r logback-spring.xml`{{execute T2}}
|
||||
|
||||
```
|
||||
$ classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader -r logback-spring.xml
|
||||
jar:file:/home/scrapbook/tutorial/demo-arthas-spring-boot.jar!/BOOT-INF/classes!/logback-spring.xml
|
||||
```
|
||||
|
||||
### Try to load the specified class
|
||||
|
||||
For example, try loading `java.lang.String` with spring LaunchedURLClassLoader :
|
||||
|
||||
`classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --load java.lang.String`{{execute T2}}
|
||||
|
||||
```
|
||||
$ classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader --load java.lang.String
|
||||
load class success.
|
||||
class-info java.lang.String
|
||||
code-source
|
||||
name java.lang.String
|
||||
isInterface false
|
||||
isAnnotation false
|
||||
isEnum false
|
||||
isAnonymousClass false
|
||||
isArray false
|
||||
isLocalClass false
|
||||
isMemberClass false
|
||||
isPrimitive false
|
||||
isSynthetic false
|
||||
simple-name String
|
||||
modifier final,public
|
||||
annotation
|
||||
interfaces java.io.Serializable,java.lang.Comparable,java.lang.CharSequence
|
||||
super-class +-java.lang.Object
|
||||
class-loader
|
||||
classLoaderHash null
|
||||
```
|
||||
|
@ -1,54 +0,0 @@
|
||||
|
||||
|
||||
In this case, the user can get the spring context, get the bean, and invoke the method.
|
||||
|
||||
### Use the tt command to record the invocation of the specified method
|
||||
|
||||
`tt` is TimeTunnel, which records the parameters and return value of each invocation of the specified method.
|
||||
|
||||
* https://arthas.aliyun.com/doc/tt.html
|
||||
|
||||
`tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod`{{execute T2}}
|
||||
|
||||
Visit: https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/user/1
|
||||
|
||||
You can see that the `tt` command record an invocation:
|
||||
|
||||
```bash
|
||||
$ tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdaptePress Q or Ctrl+C to abort.
|
||||
Affect(class-cnt:1 , method-cnt:1) cost in 252 ms.
|
||||
INDE TIMESTAMP COST( IS-R IS- OBJECT CLASS METHOD
|
||||
X ms) ET EXP
|
||||
-----------------------------------------------------------------------------------------
|
||||
1000 2019-02-15 4.583 true fal 0xc93cf1a RequestMappingHand invokeHandlerMethod
|
||||
15:38:32 923 se lerAdapter
|
||||
```
|
||||
|
||||
### Use the tt command to get the spring context from the invocation record.
|
||||
|
||||
Type `Q`{{execute T2}} or `Ctrl + C` to exit the `tt -t` command above.
|
||||
|
||||
`tt -i 1000 -w 'target.getApplicationContext()'`{{execute T2}}
|
||||
|
||||
```bash
|
||||
$ tt -i 1000 -w 'target.getApplicationContext()'
|
||||
@AnnotationConfigEmbeddedWebApplicationContext[
|
||||
reader=@AnnotatedBeanDefinitionReader[org.springframework.context.annotation.AnnotatedBeanDefinitionReader@2e457641],
|
||||
scanner=@ClassPathBeanDefinitionScanner[org.springframework.context.annotation.ClassPathBeanDefinitionScanner@6eb38026],
|
||||
annotatedClasses=null,
|
||||
basePackages=null,
|
||||
]
|
||||
Affect(row-cnt:1) cost in 439 ms.
|
||||
```
|
||||
|
||||
## Get the spring bean and invoke method
|
||||
|
||||
`tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'`{{execute T2}}
|
||||
|
||||
The result is:
|
||||
|
||||
```bash
|
||||
$ tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'
|
||||
@String[Hello World]
|
||||
Affect(row-cnt:1) cost in 52 ms.
|
||||
```
|
@ -1,56 +0,0 @@
|
||||
|
||||
|
||||
In this case, the user will resolve the HTTP 401 issue.
|
||||
|
||||
Visit: https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/admin
|
||||
|
||||
The result is:
|
||||
|
||||
```
|
||||
Something went wrong: 401 Unauthorized
|
||||
```
|
||||
|
||||
We know that `401` is usually intercepted by the permission-managed `Filter`, so which `Filter` returns 401?
|
||||
|
||||
|
||||
### Track all Filter methods
|
||||
|
||||
Start trace:
|
||||
|
||||
`trace javax.servlet.Filter *`{{execute T2}}
|
||||
|
||||
Visit: https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/admin
|
||||
|
||||
At the deepest level of the call tree, you can find `AdminFilterConfig$AdminFilter` which returns `401`:
|
||||
|
||||
```
|
||||
+---[3.806273ms] javax.servlet.FilterChain:doFilter()
|
||||
| `---[3.447472ms] com.example.demo.arthas.AdminFilterConfig$AdminFilter:doFilter()
|
||||
| `---[0.17259ms] javax.servlet.http.HttpServletResponse:sendError()
|
||||
```
|
||||
|
||||
### Get the call stack through stack command
|
||||
|
||||
From the above result, we can find the method: `HttpServletResponse:sendError()`. So we can use `stack` command to resolved the HTTP `401` issue.
|
||||
|
||||
|
||||
Run:
|
||||
|
||||
`stack javax.servlet.http.HttpServletResponse sendError 'params[0]==401'`{{execute T2}}
|
||||
|
||||
Visit: https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/admin
|
||||
|
||||
The Result:
|
||||
|
||||
```bash
|
||||
$ stack javax.servlet.http.HttpServletResponse sendError 'params[0]==401'
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class-cnt:2 , method-cnt:4) cost in 87 ms.
|
||||
ts=2019-02-15 16:44:06;thread_name=http-nio-8080-exec-6;id=16;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@8546cd5
|
||||
@org.apache.catalina.connector.ResponseFacade.sendError()
|
||||
at com.example.demo.arthas.AdminFilterConfig$AdminFilter.doFilter(AdminFilterConfig.java:38)
|
||||
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
|
||||
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
|
||||
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
|
||||
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
|
||||
```
|
@ -1,39 +0,0 @@
|
||||
|
||||
|
||||
In this case, the user will resolve the HTTP 404 issue.
|
||||
|
||||
Visit: https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/a.txt
|
||||
|
||||
The result is:
|
||||
|
||||
```
|
||||
Something went wrong: 404 Not Found
|
||||
```
|
||||
|
||||
So which servlet is handle this request and returning 404?
|
||||
|
||||
### Trace all the Servlet methods
|
||||
|
||||
Start trace:
|
||||
|
||||
`trace javax.servlet.Servlet * > /tmp/servlet.txt`{{execute T2}}
|
||||
|
||||
Visit: https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/a.txt
|
||||
|
||||
In `Terminal 3`, view the contents of `/tmp/servlet.txt`:
|
||||
|
||||
`less /tmp/servlet.txt`{{execute T3}}
|
||||
|
||||
The contents of `/tmp/servlet.txt` will be more, and you need to be patient to find the longest level in the call tree.
|
||||
|
||||
It can be found that the request is handled by `freemarker`:
|
||||
|
||||
```
|
||||
`---[13.974188ms] org.springframework.web.servlet.ViewResolver:resolveViewName()
|
||||
+---[0.045561ms] javax.servlet.GenericServlet:<init>()
|
||||
+---[min=0.045545ms,max=0.074342ms,total=0.119887ms,count=2] org.springframework.web.servlet.view.freemarker.FreeMarkerView$GenericServletAdapter:<init>()
|
||||
+---[0.170895ms] javax.servlet.GenericServlet:init()
|
||||
| `---[0.068578ms] javax.servlet.GenericServlet:init()
|
||||
| `---[0.021793ms] javax.servlet.GenericServlet:init()
|
||||
`---[0.164035ms] javax.servlet.GenericServlet:getServletContext()
|
||||
```
|
@ -1,53 +0,0 @@
|
||||
|
||||
|
||||
|
||||
In this case, show how to troubleshoot logger conflicts.
|
||||
|
||||
### View the logger system used by the app
|
||||
|
||||
Take `UserController` as an example, it uses slf4j api, but the actual logger system used is logback.
|
||||
|
||||
`ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '@com.example.demo.arthas.user.UserController@logger'`{{execute T2}}
|
||||
|
||||
|
||||
```bash
|
||||
$ ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '@com.example.demo.arthas.user.UserController@logger'
|
||||
@Logger[
|
||||
serialVersionUID=@Long[5454405123156820674],
|
||||
FQCN=@String[ch.qos.logback.classic.Logger],
|
||||
name=@String[com.example.demo.arthas.user.UserController],
|
||||
level=null,
|
||||
effectiveLevelInt=@Integer[20000],
|
||||
parent=@Logger[Logger[com.example.demo.arthas.user]],
|
||||
childrenList=null,
|
||||
aai=null,
|
||||
additive=@Boolean[true],
|
||||
loggerContext=@LoggerContext[ch.qos.logback.classic.LoggerContext[default]],
|
||||
]
|
||||
```
|
||||
|
||||
### Find the configuration file actually loaded by the logback
|
||||
|
||||
|
||||
`ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader '#map1=@org.slf4j.LoggerFactory@getLogger("root").loggerContext.objectMap, #map1.get("CONFIGURATION_WATCH_LIST")'`{{execute T2}}
|
||||
|
||||
|
||||
### Use the classloader command to find possible logger configuration files
|
||||
|
||||
`classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader -r logback-spring.xml`{{execute T2}}
|
||||
|
||||
```
|
||||
$ classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader -r logback-spring.xml
|
||||
jar:file:/Users/hengyunabc/code/java/spring-boot-inside/demo-arthas-spring-boot/target/demo-arthas-spring-boot-0.0.1-SNAPSHOT.jar!/BOOT-INF/classes!/logback-spring.xml
|
||||
|
||||
Affect(row-cnt:1) cost in 13 ms.
|
||||
```
|
||||
You can know the specific source of the loaded configuration.
|
||||
|
||||
You can try to load files that are prone to conflict:
|
||||
|
||||
`classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader -r logback.xml`{{execute T2}}
|
||||
|
||||
`classloader --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader -r log4j.properties`{{execute T2}}
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
|
||||
|
||||
### View all thread information
|
||||
|
||||
`thread`{{execute T2}}
|
||||
|
||||
|
||||
### View the stack of specific threads
|
||||
|
||||
View the stack of thread ID 16:
|
||||
|
||||
`thread 16`{{execute T2}}
|
||||
|
||||
### View the stack of CPU usage TOP N threads
|
||||
|
||||
`thread -n 3`{{execute T2}}
|
||||
|
||||
View the CPU usage TOP N thread stack in 5 seconds
|
||||
|
||||
`thread -n 3 -i 5000`{{execute T2}}
|
||||
|
||||
### Find if the thread is blocked
|
||||
|
||||
`thread -b`{{execute T2}}
|
@ -1,98 +0,0 @@
|
||||
|
||||
|
||||
Currently, visiting http://localhost/user/0 will return a 500 error:
|
||||
|
||||
`curl http://localhost/user/0`{{execute T3}}
|
||||
|
||||
```
|
||||
{"timestamp":1550223186170,"status":500,"error":"Internal Server Error","exception":"java.lang.IllegalArgumentException","message":"id < 1","path":"/user/0"}
|
||||
```
|
||||
|
||||
But what are the specific parameters of the request, what is the exception stack?
|
||||
|
||||
### View the parameters/exception of UserController
|
||||
|
||||
Execute in Arthas:
|
||||
|
||||
`watch com.example.demo.arthas.user.UserController * '{params, throwExp}'`{{execute T2}}
|
||||
|
||||
|
||||
1. The first argument is the class name, which supports wildcards.
|
||||
2. The second argument is the function name, which supports wildcards.
|
||||
|
||||
Visit `curl http://localhost/user/0`{{execute T3}} , the `watch` command will print the parameters and exception
|
||||
|
||||
```bash
|
||||
$ watch com.example.demo.arthas.user.UserController * '{params, throwExp}'
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class-cnt:1 , method-cnt:2) cost in 53 ms.
|
||||
ts=2019-02-15 01:35:25; [cost=0.996655ms] result=@ArrayList[
|
||||
@Object[][isEmpty=false;size=1],
|
||||
@IllegalArgumentException[java.lang.IllegalArgumentException: id < 1],
|
||||
]
|
||||
```
|
||||
|
||||
|
||||
The user can see that the actual thrown exception is `IllegalArgumentException`.
|
||||
|
||||
The user can exit the watch command by typing `Q`{{execute T2}} or `Ctrl+C`.
|
||||
|
||||
If the user want to expand the result, can use the `-x` option:
|
||||
|
||||
`watch com.example.demo.arthas.user.UserController * '{params, throwExp}' -x 2`{{execute T2}}
|
||||
|
||||
### The return value expression
|
||||
|
||||
In the above example, the third argument is the `return value expression`, which is actually an `ognl` expression that supports some built-in objects:
|
||||
|
||||
* loader
|
||||
* clazz
|
||||
* method
|
||||
* target
|
||||
* params
|
||||
* returnObj
|
||||
* throwExp
|
||||
* isBefore
|
||||
* isThrow
|
||||
* isReturn
|
||||
|
||||
You can use these built-in objects in the expressions. For example, return an array:
|
||||
|
||||
`watch com.example.demo.arthas.user.UserController * '{params[0], target, returnObj}'`{{execute T2}}
|
||||
|
||||
|
||||
More references: https://arthas.aliyun.com/doc/en/advice-class.html
|
||||
|
||||
|
||||
### The conditional expression
|
||||
|
||||
The `watch` command supports conditional expressions in the fourth argument, such as:
|
||||
|
||||
`watch com.example.demo.arthas.user.UserController * returnObj 'params[0] > 100'`{{execute T2}}
|
||||
|
||||
When visit https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/user/1 , the `watch` command print nothing.
|
||||
|
||||
When visit https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com/user/101 , the `watch` command will print:
|
||||
|
||||
```bash
|
||||
$ watch com.example.demo.arthas.user.UserController * returnObj 'params[0] > 100'
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class-cnt:1 , method-cnt:2) cost in 47 ms.
|
||||
ts=2019-02-13 19:42:12; [cost=0.821443ms] result=@User[
|
||||
id=@Integer[101],
|
||||
name=@String[name101],
|
||||
]
|
||||
```
|
||||
|
||||
### Capture when an exception occurs
|
||||
|
||||
The `watch` command supports the `-e` option, which means that only requests that throw an exception are caught:
|
||||
|
||||
`watch com.example.demo.arthas.user.UserController * "{params[0],throwExp}" -e`{{execute T2}}
|
||||
|
||||
|
||||
### Filter by cost
|
||||
|
||||
The watch command supports filtering by cost, such as:
|
||||
|
||||
`watch com.example.demo.arthas.user.UserController * '{params, returnObj}' '#cost>200'`{{execute T2}}
|
@ -1,18 +0,0 @@
|
||||
|
||||
|
||||
## reset
|
||||
|
||||
When Arthas executes commands such as watch/trace, it actually modifies the application's bytecode and inserts the enhanced code. These enhancement codes can be removed by explicitly executing the `reset`{{execute T2}} command.
|
||||
|
||||
## Exit/Stop Arthas
|
||||
|
||||
Arthas can be exited with the `exit`{{execute interrupt}} or `quit`{{execute interrupt}} command.
|
||||
|
||||
After exiting Arthas, you can also connect with `java -jar arthas-boot.jar`{{execute interrupt}} again.
|
||||
|
||||
## Stop Arthas
|
||||
|
||||
The `exit/quit` command simply exits the current session and the arthas server still runs in the target process.
|
||||
|
||||
To completely exit Arthas, you can execute the `stop`{{execute interrupt}} command.
|
||||
|
@ -1,8 +0,0 @@
|
||||
|
||||
In the `Advanced Tutorial`, there are most of the advanced usages of Arthas and hope to help you troubleshoot the issue. If you have more tips or questions, please feel free to tell or ask in Issue.
|
||||
|
||||
* Issues: https://github.com/alibaba/arthas/issues
|
||||
* Documentation: https://arthas.aliyun.com/doc/en
|
||||
|
||||
|
||||
If you are using Arthas, please let us know that. Your use is very important to us: [View](https://github.com/alibaba/arthas/issues/111)
|
@ -1,104 +0,0 @@
|
||||
{
|
||||
"title": "Arthas Advanced",
|
||||
"description": "Arthas Advanced",
|
||||
"details": {
|
||||
"steps": [
|
||||
{
|
||||
"title": "Start math-game",
|
||||
"text": "start-demo.md"
|
||||
},
|
||||
{
|
||||
"title": "Start arthas-boot",
|
||||
"text": "arthas-boot.md"
|
||||
},
|
||||
{
|
||||
"title": "JVM Infomation",
|
||||
"text": "jvm-info.md"
|
||||
},
|
||||
{
|
||||
"title": "Tips",
|
||||
"text": "tips.md"
|
||||
},
|
||||
{
|
||||
"title": "sc/sm view loaded classes",
|
||||
"text": "sc-sm.md"
|
||||
},
|
||||
{
|
||||
"title": "Jad",
|
||||
"text": "jad.md"
|
||||
},
|
||||
{
|
||||
"title": "Ognl",
|
||||
"text": "ognl.md"
|
||||
},
|
||||
{
|
||||
"title": "Case: Troubleshooting method invoke exception",
|
||||
"text": "case-watch-method-exception.md"
|
||||
},
|
||||
{
|
||||
"title": "Case: Hotswap code",
|
||||
"text": "case-jad-mc-redefine.md"
|
||||
},
|
||||
{
|
||||
"title": "Case: Change Logger Level",
|
||||
"text": "case-ognl-update-logger-level.md"
|
||||
},
|
||||
{
|
||||
"title": "Case: Troubleshoot logger conflicts",
|
||||
"text": "case-logger-config-problem.md"
|
||||
},
|
||||
{
|
||||
"title": "Case: Get the Spring Context",
|
||||
"text": "case-get-spring-context.md"
|
||||
},
|
||||
{
|
||||
"title": "Case: Troubleshooting HTTP request returns 401",
|
||||
"text": "case-http-401.md"
|
||||
},
|
||||
{
|
||||
"title": "Case: Troubleshooting HTTP request returns 404",
|
||||
"text": "case-http-404.md"
|
||||
},
|
||||
{
|
||||
"title": "Case: The ClassLoaders in Spring Boot application",
|
||||
"text": "case-classloader.md"
|
||||
},
|
||||
{
|
||||
"title": "Case: Find CPU usage Top N threads",
|
||||
"text": "case-thread.md"
|
||||
},
|
||||
{
|
||||
"title": "Web Console",
|
||||
"text": "web-console.md"
|
||||
},
|
||||
{
|
||||
"title": "Exit/Stop",
|
||||
"text": "exit.md"
|
||||
},
|
||||
{
|
||||
"title": "arthas-boot supported options",
|
||||
"text": "arthas-boot-details.md"
|
||||
}
|
||||
],
|
||||
"intro": {
|
||||
"text": "intro.md"
|
||||
},
|
||||
"finish": {
|
||||
"text": "finish.md"
|
||||
}
|
||||
},
|
||||
"environment": {
|
||||
"uilayout": "terminal",
|
||||
"showdashboard": true,
|
||||
"dashboards": [
|
||||
{
|
||||
"name": "Web Port 80",
|
||||
"port": 80
|
||||
}
|
||||
]
|
||||
},
|
||||
"backend": {
|
||||
"imageid": "openjdk:15",
|
||||
"environmentsprotocol": "http"
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
|
||||
|
||||
|
||||
![Arthas](https://arthas.aliyun.com/doc/_images/arthas.png)
|
||||
|
||||
`Arthas` is a Java diagnostic tool open-sourced by Alibaba middleware team. Arthas helps developers in trouble-shooting issues in production environment for Java based applications without modifying code or restarting servers.
|
||||
|
||||
This tutorial takes a normal Spring Boot application as an example to demonstrate the advanced usage of the Arthas.
|
||||
|
||||
* Github: https://github.com/alibaba/arthas
|
||||
* Docs: https://arthas.aliyun.com/doc/en
|
@ -1,8 +0,0 @@
|
||||
The user can decompile the code with the `jad` command:
|
||||
|
||||
`jad com.example.demo.arthas.user.UserController`{{execute T2}}
|
||||
|
||||
|
||||
The `--source-only` option can only print out the source code:
|
||||
|
||||
`jad --source-only com.example.demo.arthas.user.UserController`{{execute T2}}
|
@ -1,29 +0,0 @@
|
||||
|
||||
The following describes the commands for viewing `JVM` information in Arthas.
|
||||
|
||||
### sysprop
|
||||
|
||||
`sysprop`{{execute T2}} can print all System Properties information.
|
||||
|
||||
Specify a single key: `sysprop java.version`{{execute T2}}
|
||||
|
||||
It can also be filtered by `grep`: `sysprop | grep user`{{execute T2}}
|
||||
|
||||
Set a new value: `sysprop testKey testValue`{{execute T2}}
|
||||
|
||||
### sysenv
|
||||
|
||||
The `sysenv`{{execute T2}} command gets the environment variable. Similar to the `sysprop` command.
|
||||
|
||||
|
||||
### jvm
|
||||
|
||||
The `jvm`{{execute T2}} command prints out various details of the `JVM`.
|
||||
|
||||
|
||||
### dashboard
|
||||
|
||||
|
||||
The `dashboard`{{execute T2}} command can view the real-time data panel of the current system.
|
||||
|
||||
Enter `Q`{{execute T2}} or `Ctrl+C` to exit the dashboard command.
|
@ -1,71 +0,0 @@
|
||||
|
||||
The `ognl` command can execute code dynamically.
|
||||
|
||||
### Invoke the static method
|
||||
|
||||
`ognl '@java.lang.System@out.println("hello ognl")'`{{execute T2}}
|
||||
|
||||
The `Terminal 1` will print `hello ognl`.
|
||||
|
||||
|
||||
### Find the ClassLoader of the UserController
|
||||
|
||||
`sc -d com.example.demo.arthas.user.UserController | grep classLoaderHash`{{execute T2}}
|
||||
|
||||
```bash
|
||||
$ sc -d com.example.demo.arthas.user.UserController | grep classLoaderHash
|
||||
classLoaderHash 1be6f5c3
|
||||
```
|
||||
|
||||
Please write down your classLoaderHash here since it's dynamic. In the case here, it's `1be6f5c3`.
|
||||
|
||||
if you use`-c`, you have to manually type hashcode by `-c <hashcode>`.
|
||||
|
||||
```bash
|
||||
$ ognl -c 1be6f5c3 @com.example.demo.arthas.user.UserController@logger
|
||||
```
|
||||
|
||||
For classloader with only one instance, it can be specified by `--classLoaderClass` using class name, which is more convenient to use.
|
||||
|
||||
```bash
|
||||
$ ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader @org.springframework.boot.SpringApplication@logger
|
||||
@Slf4jLocationAwareLog[
|
||||
FQCN=@String[org.apache.commons.logging.LogAdapter$Slf4jLocationAwareLog],
|
||||
name=@String[org.springframework.boot.SpringApplication],
|
||||
logger=@Logger[Logger[org.springframework.boot.SpringApplication]],
|
||||
]
|
||||
```
|
||||
The value of `--classloaderclass` is the class name of classloader. It can only work when it matches a unique classloader instance. The purpose is to facilitate the input of general commands. However, `-c <hashcode>` is dynamic.
|
||||
|
||||
### Get static fields of static classes
|
||||
|
||||
Get the `logger` field of the `UserController` class:
|
||||
|
||||
`ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader @com.example.demo.arthas.user.UserController@logger`{{execute T2}}
|
||||
|
||||
Control the number of expansion layers of the return value with the `-x` parameter. such as:
|
||||
|
||||
`ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader -x 2 @com.example.demo.arthas.user.UserController@logger`{{execute T2}}
|
||||
|
||||
### Execute multi-line expressions
|
||||
|
||||
Return a list:
|
||||
|
||||
`ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'`{{execute T2}}
|
||||
|
||||
```bash
|
||||
$ ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
|
||||
@ArrayList[
|
||||
@String[/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home/jre],
|
||||
@String[Java(TM) SE Runtime Environment],
|
||||
]
|
||||
```
|
||||
|
||||
### More
|
||||
|
||||
The `ognl` expression in Arthas is an important feature, and the `ognl` expression can be used in many commands.
|
||||
|
||||
For some more complicated usages, refer to:
|
||||
|
||||
* For special usage of OGNL, please refer to: https://github.com/alibaba/arthas/issues/71
|
||||
* Official Guide to OGNL Expressions: https://commons.apache.org/dormant/commons-ognl/language-guide.html
|
@ -1,36 +0,0 @@
|
||||
|
||||
|
||||
|
||||
There are some switches in Arthas that can be viewed with the `options`{{execute T2}} command.
|
||||
|
||||
|
||||
View the value of a single option, such as
|
||||
|
||||
`options unsafe`{{execute T2}}
|
||||
|
||||
|
||||
## Allow to enhance the classes of JDK
|
||||
|
||||
By default, `unsafe` is false, ie commands such as `watch`/`trace` do not enhance the JVM class, which is the class starting with `java.*`.
|
||||
|
||||
To enhance the classes in the JVM, execute `options unsafe true`{{execute T2}} to set `unsafe` to true.
|
||||
|
||||
## Print objects in JSON format
|
||||
|
||||
When `json-format` is false, the output is:
|
||||
|
||||
```bash
|
||||
$ ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
|
||||
@ArrayList[
|
||||
@String[/usr/lib/jvm/java-8-oracle/jre],
|
||||
@String[Java(TM) SE Runtime Environment],
|
||||
]
|
||||
```
|
||||
|
||||
`options json-format true`{{execute T2}}
|
||||
|
||||
When `json-format` is true, the output is:
|
||||
|
||||
```bash
|
||||
$ ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#v["/usr/lib/jvm/java-8-oracle/jre","Java(TM) SE Runtime Environment"]
|
||||
```
|
@ -1,33 +0,0 @@
|
||||
|
||||
The commands in Arthas for finding loaded classes.
|
||||
|
||||
### sc
|
||||
|
||||
The `sc` command finds all the classes that the JVM has loaded.
|
||||
|
||||
When search an interface, it also search all implementation classes. For example, look at all the `Filter` implementation classes:
|
||||
|
||||
`sc javax.servlet.Filter`{{execute T2}}
|
||||
|
||||
With the `-d` option, it will print out the specific information of the loaded classes, which is very convenient for finding the class loading problem.
|
||||
|
||||
`sc -d javax.servlet.Filter`{{execute T2}}
|
||||
|
||||
`sc` supports wildcards, such as searching for all `StringUtils`:
|
||||
|
||||
`sc *StringUtils`{{execute T2}}
|
||||
|
||||
### sm
|
||||
|
||||
The `sm` command find the specific method of the class. such as:
|
||||
|
||||
`sm java.math.RoundingMode`{{execute T2}}
|
||||
|
||||
With `-d` option, it will print the deatils of the method.
|
||||
|
||||
`sm -d java.math.RoundingMode`{{execute T2}}
|
||||
|
||||
Find specific methods, such as the constructors:
|
||||
|
||||
`sm java.math.RoundingMode <init>`{{execute T2}}
|
||||
|
@ -1,14 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
Download `demo-arthas-spring-boot.jar`, and start with `java -jar` command:
|
||||
|
||||
`wget https://github.com/hengyunabc/spring-boot-inside/raw/master/demo-arthas-spring-boot/demo-arthas-spring-boot.jar
|
||||
java -jar demo-arthas-spring-boot.jar`{{execute T1}}
|
||||
|
||||
`demo-arthas-spring-boot` is a simple Spring Boot demo, the source code here: [View](https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-arthas-spring-boot)
|
||||
|
||||
After booting, access port 80: https://[[HOST_SUBDOMAIN]]-80-[[KATACODA_HOST]].environments.katacoda.com
|
||||
|
||||
![Demo Web](/arthas/scenarios/common-resources/assets/demo-web.png)
|
@ -1,47 +0,0 @@
|
||||
|
||||
Some tips on using Arthas.
|
||||
|
||||
### help
|
||||
|
||||
Every command in Arthas has help doc. Can be viewed with `-h`. There are `EXAMPLES` and `WIKI` links in the help doc.
|
||||
|
||||
such as:
|
||||
|
||||
`sysprop -h`{{execute T2}}
|
||||
|
||||
### Auto completion
|
||||
|
||||
Arthas supports a wide range of auto-completion features, and you can type `Tab` to get more information when you have doubts about your use.
|
||||
|
||||
For example, after typing `sysprop java.`, enter `Tab`, which will complete the corresponding key:
|
||||
|
||||
```
|
||||
$ sysprop java.
|
||||
java.runtime.name java.protocol.handler.pkgs java.vm.version
|
||||
java.vm.vendor java.vendor.url java.vm.name
|
||||
...
|
||||
```
|
||||
|
||||
|
||||
### Readline shortcut key support
|
||||
|
||||
Arthas supports common command line shortcuts, such as `Ctrl + A` to jump to the beginning of the line, and `Ctrl + E` to jump to the end of the line.
|
||||
|
||||
More shortcuts can be viewed with the `keymap`{{execute T2}} command.
|
||||
|
||||
|
||||
### Completion of history commands
|
||||
|
||||
If you want to execute the previous command again, you can match the previous command by pressing `Up/↑` or `Ddown/↓` when you enter halfway.
|
||||
|
||||
For example, if `sysprop java.version` was executed before, then after entering `sysprop ja`, you can type `Up/↑`, and it will be automatically completed as `sysprop java.version`.
|
||||
|
||||
If you want to see all the history commands, you can also view them with the `history`{{execute T2}} command.
|
||||
|
||||
### pipeline
|
||||
|
||||
Arthas supports some simple commands after the pipeline, such as:
|
||||
|
||||
`sysprop | grep java`{{execute T2}}
|
||||
|
||||
`sysprop | wc -l`{{execute T2}}
|
@ -1,20 +0,0 @@
|
||||
|
||||
|
||||
Arthas supports connections via a Web Socket.
|
||||
|
||||
|
||||
## The Web Console in the tutorial
|
||||
|
||||
http://[[HOST_SUBDOMAIN]]-8563-[[KATACODA_HOST]].environments.katacoda.com/?ip=[[HOST_SUBDOMAIN]]-8563-[[KATACODA_HOST]].environments.katacoda.com&port=80
|
||||
|
||||
> Note: The 80 port is accessed in the tutorial because port forwarding. In the local, you need to access port 8563.
|
||||
|
||||
## Local
|
||||
|
||||
|
||||
When launching locally, you can access Arthas through a browser by visiting http://127.0.0.1:8563/.
|
||||
|
||||
![Arthas WebConsole](/arthas/scenarios/common-resources/assets/web-console.png)
|
||||
|
||||
|
||||
It is recommended to experience it through "Quick Start": https://arthas.aliyun.com/doc/en/quick-start.html
|
@ -1,10 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
下载`math-game.jar`,再用`java -jar`命令启动:
|
||||
|
||||
`wget https://arthas.aliyun.com/math-game.jar
|
||||
java -jar math-game.jar`{{execute T1}}
|
||||
|
||||
`math-game`是一个很简单的程序,它随机生成整数,再执行因式分解,把结果打印出来。如果生成的随机数是负数,则会打印提示信息。
|
@ -1,3 +0,0 @@
|
||||
`dashboard`{{execute T2}} 命令可以查看当前系统的实时数据面板。
|
||||
|
||||
输入 `Q`{{execute T2}} 或者 `Ctrl+C` 可以退出dashboard命令。
|
@ -1,57 +0,0 @@
|
||||
{
|
||||
"title": "Arthas 基础教程",
|
||||
"description": "Arthas 基础教程",
|
||||
"details": {
|
||||
"steps": [
|
||||
{
|
||||
"title": "启动math-game",
|
||||
"text": "arthas-demo.md"
|
||||
},
|
||||
{
|
||||
"title": "启动arthas-boot",
|
||||
"text": "arthas-boot.md"
|
||||
},
|
||||
{
|
||||
"title": "Dashboard",
|
||||
"text": "dashboard.md"
|
||||
},
|
||||
{
|
||||
"title": "Thread",
|
||||
"text": "thread.md"
|
||||
},
|
||||
{
|
||||
"title": "Sc",
|
||||
"text": "sc.md"
|
||||
},
|
||||
{
|
||||
"title": "Jad",
|
||||
"text": "jad.md"
|
||||
},
|
||||
{
|
||||
"title": "Watch",
|
||||
"text": "watch.md"
|
||||
},
|
||||
{
|
||||
"title": "Vmtool",
|
||||
"text": "vmtool.md"
|
||||
},
|
||||
{
|
||||
"title": "Exit/Stop",
|
||||
"text": "exit.md"
|
||||
}
|
||||
],
|
||||
"intro": {
|
||||
"text": "intro.md"
|
||||
},
|
||||
"finish": {
|
||||
"text": "finish.md"
|
||||
}
|
||||
},
|
||||
"environment": {
|
||||
"uilayout": "terminal"
|
||||
},
|
||||
"backend": {
|
||||
"imageid": "openjdk:15",
|
||||
"environmentsprotocol": "http"
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
|
||||
可以通过 `jad` 命令来反编译代码:
|
||||
|
||||
`jad demo.MathGame`{{execute T2}}
|
@ -1,20 +0,0 @@
|
||||
|
||||
通过`vmtool`命令,可以搜索内存对象。
|
||||
|
||||
`vmtool --action getInstances --className java.lang.String --limit 10`{{execute T2}}
|
||||
|
||||
```bash
|
||||
$ vmtool --action getInstances --className java.lang.String --limit 10
|
||||
@String[][
|
||||
@String[com/taobao/arthas/core/shell/session/Session],
|
||||
@String[com.taobao.arthas.core.shell.session.Session],
|
||||
@String[com/taobao/arthas/core/shell/session/Session],
|
||||
@String[com/taobao/arthas/core/shell/session/Session],
|
||||
@String[com/taobao/arthas/core/shell/session/Session.class],
|
||||
@String[com/taobao/arthas/core/shell/session/Session.class],
|
||||
@String[com/taobao/arthas/core/shell/session/Session.class],
|
||||
@String[com/],
|
||||
@String[java/util/concurrent/ConcurrentHashMap$ValueIterator],
|
||||
@String[java/util/concurrent/locks/LockSupport],
|
||||
]
|
||||
```
|
@ -1,6 +0,0 @@
|
||||
|
||||
通过`watch`命令可以查看函数的参数/返回值/异常信息。
|
||||
|
||||
`watch demo.MathGame primeFactors returnObj`{{execute T2}}
|
||||
|
||||
输入 `Q`{{execute T2}} 或者 `Ctrl+C` 退出watch命令。
|
@ -1,11 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
Download `math-game.jar` and start with the `java -jar` command:
|
||||
|
||||
`wget https://arthas.aliyun.com/math-game.jar
|
||||
java -jar math-game.jar`{{execute T1}}
|
||||
|
||||
`math-game` is a very simple program that randomly generates integers, performs factorization, and prints the results.
|
||||
If the generated random number is negative, a error message will be printed.
|
@ -1,3 +0,0 @@
|
||||
The `dashboard`{{execute T2}} command allows you to view the real-time data panel of the current system.
|
||||
|
||||
Enter `Q`{{execute T2}} or `Ctrl+C` to exit the dashboard command.
|
@ -1,13 +0,0 @@
|
||||
|
||||
|
||||
## Exit/Stop Arthas
|
||||
|
||||
Arthas can be exited with the `exit`{{execute interrupt}} or `quit`{{execute interrupt}} command.
|
||||
|
||||
After exiting Arthas, you can also connect with `java -jar arthas-boot.jar`{{execute interrupt}} again.
|
||||
|
||||
## Stop Arthas
|
||||
|
||||
The `exit/quit` command simply exits the current session and the arthas server still runs in the target process.
|
||||
|
||||
To completely exit Arthas, you can execute the `stop`{{execute interrupt}} command.
|
@ -1,6 +0,0 @@
|
||||
|
||||
Through this tutorial, now you know how to use Arthas. More advanced features can be found in the Advanced Guide below.
|
||||
|
||||
* [Arthas Advanced](https://arthas.aliyun.com/doc/arthas-tutorials.html?language=en&id=arthas-advanced)
|
||||
* [Arthas Github](https://github.com/alibaba/arthas)
|
||||
* [Arthas Documentation](https://arthas.aliyun.com/doc/en)
|
@ -1,57 +0,0 @@
|
||||
{
|
||||
"title": "Arthas Basics",
|
||||
"description": "Arthas Basics",
|
||||
"details": {
|
||||
"steps": [
|
||||
{
|
||||
"title": "Start arthas-demo",
|
||||
"text": "arthas-demo.md"
|
||||
},
|
||||
{
|
||||
"title": "Start arthas-boot",
|
||||
"text": "arthas-boot.md"
|
||||
},
|
||||
{
|
||||
"title": "Dashboard",
|
||||
"text": "dashboard.md"
|
||||
},
|
||||
{
|
||||
"title": "Thread",
|
||||
"text": "thread.md"
|
||||
},
|
||||
{
|
||||
"title": "Sc",
|
||||
"text": "sc.md"
|
||||
},
|
||||
{
|
||||
"title": "Jad",
|
||||
"text": "jad.md"
|
||||
},
|
||||
{
|
||||
"title": "Watch",
|
||||
"text": "watch.md"
|
||||
},
|
||||
{
|
||||
"title": "Vmtool",
|
||||
"text": "vmtool.md"
|
||||
},
|
||||
{
|
||||
"title": "Exit/Stop",
|
||||
"text": "exit.md"
|
||||
}
|
||||
],
|
||||
"intro": {
|
||||
"text": "intro.md"
|
||||
},
|
||||
"finish": {
|
||||
"text": "finish.md"
|
||||
}
|
||||
},
|
||||
"environment": {
|
||||
"uilayout": "terminal"
|
||||
},
|
||||
"backend": {
|
||||
"imageid": "openjdk:15",
|
||||
"environmentsprotocol": "http"
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
|
||||
|
||||
|
||||
![Arthas](https://arthas.aliyun.com/doc/_images/arthas.png)
|
||||
|
||||
`Arthas` is a Java diagnostic tool open-sourced by Alibaba middleware team. Arthas helps developers in trouble-shooting issues in production environment for Java based applications without modifying code or restarting servers.
|
||||
|
||||
`Arthas` supports JDK 6+, supports Linux/Mac/Windows.
|
||||
|
||||
* Github: https://github.com/alibaba/arthas
|
||||
* Documentation: https://arthas.aliyun.com/doc/en
|
@ -1,4 +0,0 @@
|
||||
|
||||
The `jad` command can be used to decompile the byte code:
|
||||
|
||||
`jad demo.MathGame`{{execute T2}}
|
@ -1,4 +0,0 @@
|
||||
|
||||
The `sc` command can be used to find the loaded classes in the JVM:
|
||||
|
||||
`sc -d *MathGame`{{execute T2}}
|
@ -1,10 +0,0 @@
|
||||
The `thread 1`{{execute interrupt}} command prints the stack of thread ID 1.
|
||||
|
||||
Arthas supports pipes, and you can find `main class` with `thread 1 | grep 'main('`{{execute T2}}.
|
||||
|
||||
You can see that `main class` is `demo.MathGame`:
|
||||
|
||||
```
|
||||
$ thread 1 | grep 'main('
|
||||
at demo.MathGame.main(MathGame.java:17)
|
||||
```
|
@ -1,20 +0,0 @@
|
||||
|
||||
The `vmtool` command can search object in JVM.
|
||||
|
||||
`vmtool --action getInstances --className java.lang.String --limit 10`{{execute T2}}
|
||||
|
||||
```bash
|
||||
$ vmtool --action getInstances --className java.lang.String --limit 10
|
||||
@String[][
|
||||
@String[com/taobao/arthas/core/shell/session/Session],
|
||||
@String[com.taobao.arthas.core.shell.session.Session],
|
||||
@String[com/taobao/arthas/core/shell/session/Session],
|
||||
@String[com/taobao/arthas/core/shell/session/Session],
|
||||
@String[com/taobao/arthas/core/shell/session/Session.class],
|
||||
@String[com/taobao/arthas/core/shell/session/Session.class],
|
||||
@String[com/taobao/arthas/core/shell/session/Session.class],
|
||||
@String[com/],
|
||||
@String[java/util/concurrent/ConcurrentHashMap$ValueIterator],
|
||||
@String[java/util/concurrent/locks/LockSupport],
|
||||
]
|
||||
```
|
@ -1,5 +0,0 @@
|
||||
The `watch` command can view the parameter/return value/exception of the method.
|
||||
|
||||
`watch demo.MathGame primeFactors returnObj`{{execute T2}}
|
||||
|
||||
Input `Q`{{execute T2}} or `Ctrl+C` to exit the watch command.
|
@ -1,10 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
下载`math-game.jar`,再用`java -jar`命令启动:
|
||||
|
||||
`wget https://arthas.aliyun.com/math-game.jar
|
||||
java -jar math-game.jar`{{execute T1}}
|
||||
|
||||
`math-game`是一个很简单的程序,它随机生成整数,再执行因式分解,把结果打印出来。如果生成的随机数是负数,则会打印提示信息。
|
@ -1,2 +0,0 @@
|
||||
|
||||
异步执行的命令,如果希望停止,可执行`kill`
|
@ -1,11 +0,0 @@
|
||||
|
||||
|
||||
|
||||
|
||||
Download `math-game.jar` and start with the `java -jar` command:
|
||||
|
||||
`wget https://arthas.aliyun.com/math-game.jar
|
||||
java -jar math-game.jar`{{execute T1}}
|
||||
|
||||
`math-game` is a very simple program that randomly generates integers, performs factorization, and prints the results.
|
||||
If the generated random number is negative, a error message will be printed.
|
@ -1,2 +0,0 @@
|
||||
|
||||
Asynchronous jobs in arthas. The idea is borrowed from [linux jobs](http://man7.org/linux/man-pages/man1/jobs.1p.html).
|
@ -1,7 +0,0 @@
|
||||
|
||||
Through this tutorial, now you know Arthas Async Jobs. If you have more tips or questions, please feel free to tell or ask in Issue.
|
||||
|
||||
* Issues: https://github.com/alibaba/arthas/issues
|
||||
* Documentation: https://arthas.aliyun.com/doc/en
|
||||
|
||||
If you are using Arthas, please let us know that. Your use is very important to us: [View](https://github.com/alibaba/arthas/issues/111)
|
@ -1,63 +0,0 @@
|
||||
{
|
||||
"title": "Arthas Async Jobs",
|
||||
"description": "Arthas Async Jobs",
|
||||
"difficulty": "expert",
|
||||
"time": "10 minutes",
|
||||
"details": {
|
||||
"steps": [
|
||||
{
|
||||
"title": "Arthas demo",
|
||||
"text": "arthas-demo.md"
|
||||
},
|
||||
{
|
||||
"title": "Start arthas-boot",
|
||||
"text": "arthas-boot.md"
|
||||
},
|
||||
{
|
||||
"title": "Async Jobs",
|
||||
"text": "async-jobs.md"
|
||||
},
|
||||
{
|
||||
"title": "Use & to run the command in the background",
|
||||
"text": "run-cmd-in-backgd.md"
|
||||
},
|
||||
{
|
||||
"title": "List background jobs",
|
||||
"text": "list-backgd-jobs.md"
|
||||
},
|
||||
{
|
||||
"title": "Suspend and cancel job",
|
||||
"text": "suspend-cancel-job.md"
|
||||
},
|
||||
{
|
||||
"title": "fg/bg, switch the job from the foreground to the background, and vise verse",
|
||||
"text": "switch-foregd-backgd.md"
|
||||
},
|
||||
{
|
||||
"title": "Redirect the output",
|
||||
"text": "redirect-output.md"
|
||||
},
|
||||
{
|
||||
"title": "Stop job",
|
||||
"text": "stop-job.md"
|
||||
},
|
||||
{
|
||||
"title": "Others",
|
||||
"text": "others.md"
|
||||
}
|
||||
],
|
||||
"intro": {
|
||||
"text": "intro.md"
|
||||
},
|
||||
"finish": {
|
||||
"text": "finish.md"
|
||||
}
|
||||
},
|
||||
"environment": {
|
||||
"uilayout": "terminal"
|
||||
},
|
||||
"backend": {
|
||||
"imageid": "openjdk:15",
|
||||
"environmentsprotocol": "http"
|
||||
}
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
|
||||
If you want to list all background jobs, you can execute the jobs command and the results are as follows:
|
||||
|
||||
`jobs`{{execute T2}}
|
||||
|
||||
```bash
|
||||
$ jobs
|
||||
[1]*
|
||||
Running trace demo.MathGame primeFactors &
|
||||
execution count : 49
|
||||
start time : Wed Jul 22 05:47:52 GMT 2020
|
||||
timeout date : Thu Jul 23 05:47:52 GMT 2020
|
||||
session : aa75753d-74f1-4929-a829-7ff965345183 (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: timeout timestamp, when the time exceeds this timestamp, the job will be automatically timeout and exit.
|
@ -1,6 +0,0 @@
|
||||
|
||||
* Support up to 8 commands at the same time to redirect the output to the log files.
|
||||
|
||||
* Do not open too many background jobs at the same time to avoid negative performance effect to the target JVM.
|
||||
|
||||
* If you do not want to stop the Arthas service and continue to perform background tasks, you can exit the Arthas console by executing `quit` command (`stop` command will stop the Arthas service)
|
@ -1,11 +0,0 @@
|
||||
|
||||
The job output can be redirect to the specified file by > or >>, and can be used together with &. By doing this, you can achieve running commands asynchronously, for example:
|
||||
|
||||
`trace demo.MathGame primeFactors >> test.out &`{{execute T2}}
|
||||
|
||||
At this time, the trace command will be executed in the background, and the result will be output to the `test.out` file under the `working directory` of the application. You can continue to execute other commands. And you can view the command execution result in the file. You can execute the `pwd` command to view the `working directory` of the current application.
|
||||
|
||||
`pwd`{{execute T2}}
|
||||
|
||||
`cat test.out`{{execute T2}}
|
||||
|
@ -1,6 +0,0 @@
|
||||
|
||||
For example, execute the trace command in the background:
|
||||
|
||||
`trace demo.MathGame primeFactors &`{{execute T2}}
|
||||
|
||||
By doing this, the current command is put to the background to run, you can continue to execute other commands in the console.
|
@ -1,2 +0,0 @@
|
||||
|
||||
If you want to stop background job, just `kill <job-id>`.
|
@ -1,8 +0,0 @@
|
||||
|
||||
When the job is executing in the foreground, for example, directly executing the command` trace Test t`, or executing the background job command `trace Test t &`, then putting the job back to the foreground via fg command, the console cannot continue to execute other command, but can receive and process the following keyboard events:
|
||||
|
||||
`ctrl + z`: Suspends the job, the job status will change to Stopped, and the job can be restarted by `bg <job-id>` or `fg <job-id>`
|
||||
|
||||
`ctrl + c`: Stops the job
|
||||
|
||||
`ctrl + d`: According to linux semantics this should lead to exit the terminal, right now Arthas has not implemented this yet, therefore simply ignore this keystroke.
|
@ -1,6 +0,0 @@
|
||||
|
||||
* When a job is executed in the background or in suspended status (use `ctrl + z` to suspend job), `fg <job-id>` can transfer the job to the foreground to continue to run.
|
||||
|
||||
* When a job is in suspended status (use `ctrl + z` to suspend job), `bg <job-id>` can put the job to the background to continue to run.
|
||||
|
||||
* A job created by other session can only be put to the foreground to run by using `fg` in the current session.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue