tag: java diagnostic stack online debugging time-consuming deadlock arthas Alibaba
Arthas
Arthas is an open source Java diagnostic tool of Alibaba, which is deeply loved by developers.
Official website documents: https://arthas.aliyun.com/doc/
When you encounter the following similar problems and are helpless, Arthas can help you solve them:
- Which jar package is this class loaded from? Why are all kinds of related exceptions reported?
- Why didn't the code I changed execute? Am I not commit ted? Wrong branch?
- You can't debug online when you encounter a problem. Can you only republish it by adding a log?
- There is a problem with the data processing of a user online, but it is also impossible to debug online and reproduce offline!
- Is there a global perspective to view the health of the system?
- Is there any way to monitor the real-time running status of the JVM?
- How to quickly locate application hotspots and generate flame diagrams?
- How do I find an instance of a class directly from within the JVM?
Arthas supports JDK 6 +, Linux/Mac/Windows, adopts command-line interaction mode, and provides rich Tab automatic completion functions to further facilitate problem location and diagnosis.
1. Installation
1.1 quick installation
1.1.1 use Arthas boot (recommended)
Download arthas-boot.jar and start it in Java jar mode:
curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar
Print help information:
java -jar arthas-boot.jar -h
If the download speed is slow, you can use aliyun's image:
java -jar arthas-boot.jar --repo-mirror aliyun --use-http
1.1.2 as.sh installation
Arthas supports one click installation on Linux/Unix/Mac and other platforms. Please copy and paste the following contents into the command line, and then click enter to execute:
curl -L https://arthas.aliyun.com/install.sh | sh
The above command will download the startup script file as.sh to the current directory. You can put it anywhere or add it to $PATH.
Execute. / as.sh directly under the shell to enter the interactive interface.
You can also execute. / as.sh -h to get more parameter information.
1.2 full installation (online environment without access to external network)
# java -jar arthas-boot.jar [INFO] arthas-boot version: 3.5.3 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 24438 org.elasticsearch.bootstrap.Elasticsearch 1 [ERROR] Can not read arthas version from: https://arthas.aliyun.com/api/latest_version [ERROR] Can not find Arthas under local: /root/.arthas/lib and remote repo mirror: aliyun [ERROR] Unable to download arthas from remote server, please download the full package according to wiki: https://github.com/alibaba/arthas
When using the quick installation method to connect Java services to the online environment, it is likely that Arthas cannot obtain jar packages such as Arthas core and cannot run because the online environment has no external network access rights.
At this time, you need to install the Arthas package in full.
Installation method: (package size 13MB)
#### Get arthas full packet curl -Lo arthas-packaging-latest-bin.zip 'https://arthas.aliyun.com/download/latest_version?mirror=aliyun' unzip -d arthas-latest-bin arthas-packaging-latest-bin.zip #### Start running java -jar ahthas-boot.jar [INFO] arthas-boot version: 3.5.4 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 27878 /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar 1 [INFO] arthas home: /root [INFO] Try to attach process 27878 [INFO] Attach process 27878 success. [INFO] arthas-client connect 127.0.0.1 3658 ,---. ,------. ,--------.,--. ,--. ,---. ,---. / O \ | .--. ''--. .--'| '--' | / O \ ' .-' | .-. || '--'.' | | | .--. || .-. |`. `-. | | | || |\ \ | | | | | || | | |.-' | `--' `--'`--' '--' `--' `--' `--'`--' `--'`-----' wiki https://arthas.aliyun.com/doc tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html version 3.5.4 main_class pid 27878 time 2021-09-07 19:31:47
1.3 installation by rpm/deb
See official documents for this part
2. Quick start
arthas needs to use the jps command, so make sure the openjdk devel package is installed.
jps || yum -y install java-1.8.0-openjdk-devel
Run arthas:
# java -jar arthas-boot.jar [INFO] arthas-boot version: 3.5.3 [INFO] Process 5201 already using port 3658 [INFO] Process 5201 already using port 8563 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 5201 cloud-access-auth-1.18.1.jar [2]: 14419 tsf-stack-base-1.0.0.jar [3]: 27862 cloud-access-gateway-1.18.1.jar [4]: 6550 tsfmanager-operation-1.29.1.jar
Tip 1: when the process list given by arthas cannot determine the process information, we can enter jps -lmv on the command line to view the detailed java process information to determine the java process number we want to view.
Tip 2: when the following information is prompted:
Arthas script version: 3.0.4 Calculating attach execution time... Attaching to 24110 using version 3.0.4... Start arthas failed, exception stack trace: java.lang.InternalError: instrument library is missing in target VM at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:105) at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:84) at com.taobao.arthas.core.Arthas.<init>(Arthas.java:25) at com.taobao.arthas.core.Arthas.main(Arthas.java:96) Caused by: com.sun.tools.attach.AgentLoadException: Failed to load agent library at sun.tools.attach.LinuxVirtualMachine.execute(LinuxVirtualMachine.java:224) at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:58) at sun.tools.attach.HotSpotVirtualMachine.loadAgentLibrary(HotSpotVirtualMachine.java:79) at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:103) ... 3 more attach to target jvm (24110) failed, check /root/logs/arthas/arthas.log or stderr of target jvm for any exceptions.
We need to restart the process, then run arthas and connect to the background java process.
The following java process number is the Java service running on the current host. Enter the number to enter the interactive interface of arthas.
[INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 5201 cloud-access-auth-1.18.1.jar [2]: 14419 tsf-stack-base-1.0.0.jar [3]: 27862 cloud-access-gateway-1.18.1.jar [4]: 6550 tsfmanager-operation-1.29.1.jar 1 [INFO] local lastest version: 3.5.3, remote lastest version: 3.5.4, try to download from remote. [INFO] Start download arthas from remote server: https://arthas.aliyun.com/download/3.5.4?mirror=aliyun [INFO] Download arthas success. [INFO] arthas home: /root/.arthas/lib/3.5.4/arthas [INFO] The target process already listen port 3658, skip attach. [INFO] arthas-client connect 127.0.0.1 3658 ,---. ,------. ,--------.,--. ,--. ,---. ,---. / O \ | .--. ''--. .--'| '--' | / O \ ' .-' | .-. || '--'.' | | | .--. || .-. |`. `-. | | | || |\ \ | | | | | || | | |.-' | `--' `--'`--' '--' `--' `--' `--'`--' `--'`-----' wiki https://arthas.aliyun.com/doc tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html version 3.5.3 main_class pid 5201 time 2021-09-03 09:55:42 [arthas@5201]$
When the above color bar ARTHAS character prompt appears, it means that it has been normally connected to the specified Java process, and then enter the following arthas@PID Command prompt.
3. Function use
3.1 dashboard instruction -- overview of JVM information
Type dashboard enter at the arthas command prompt to display the information of the current process. Press q to exit.
The dashboard will output the JVM information of the java process in real time, including thread, process, memory, stack, and current system runtime information.
[arthas@5201]$ dashboard -h USAGE: dashboard [-h] [-i <value>] [-n <value>] SUMMARY: Overview of target jvm's thread, memory, gc, vm, tomcat info. EXAMPLES: dashboard dashboard -n 10 dashboard -i 2000 WIKI: https://arthas.aliyun.com/doc/dashboard OPTIONS: -h, --help this help -i, --interval <value> The interval (in ms) between two executions, default is 5000 ms. -n, --number-of-execution <value> The number of times this command will be executed.
3.2 help instruction
This instruction is used to list the subcommands supported by all arthas interactive interfaces.
[arthas@5201]$ help NAME DESCRIPTION help Display Arthas Help auth Authenticates the current session keymap Display all the available keymap for the specified connection. sc Search all the classes loaded by JVM sm Search the method of classes loaded by JVM classloader Show classloader info jad Decompile class getstatic Show the static field of a class monitor Monitor method execution statistics, e.g. total/success/failure count, average rt, fail rate, etc. stack Display the stack trace for the specified class and method thread Display thread info, thread stack trace Trace the execution time of specified method invocation. watch Display the input/output parameter, return object, and thrown exception of specified method invocation tt Time Tunnel jvm Display the target JVM information perfcounter Display the perf counter information. ognl Execute ognl expression. mc Memory compiler, compiles java files into bytecode and class files in memory. redefine Redefine classes. @see Instrumentation#redefineClasses(ClassDefinition...) retransform Retransform classes. @see Instrumentation#retransformClasses(Class...) dashboard Overview of target jvm's thread, memory, gc, vm, tomcat info. dump Dump class byte array from JVM heapdump Heap dump options View and change various Arthas options cls Clear the screen reset Reset all the enhanced classes version Display Arthas version session Display current session information sysprop Display, and change the system properties. sysenv Display the system env. vmoption Display, and update the vm diagnostic options. logger Print logger info, and update the logger level history Display command history cat Concatenate and print files base64 Encode and decode using Base64 representation echo write arguments to the standard output pwd Return working directory name mbean Display the mbean information grep grep command for pipes. tee tee command for pipes. profiler Async Profiler. https://github.com/jvm-profiling-tools/async-profiler vmtool jvm tool stop Stop/Shutdown Arthas server and exit the console.
For each subcommand, you can follow - h to further obtain help usage information.
3.3 thread instruction
[arthas@5201]$ thread -h USAGE: thread [--all] [-h] [-b] [--lockedMonitors] [--lockedSynchronizers] [-i <value>] [--state <value>] [-n <value>] [id] SUMMARY: Display thread info, thread stack EXAMPLES: thread thread 51 thread -n -1 thread -n 5 thread -b thread -i 2000 thread --state BLOCKED WIKI: https://arthas.aliyun.com/doc/thread OPTIONS: --all Display all thread results instead of the first page -h, --help this help -b, --include-blocking-thread Find the thread who is holding a lock that blocks the most number of threads. --lockedMonitors Find the thread info with lockedMonitors flag, default value is false. --lockedSynchronizers Find the thread info with lockedSynchronizers flag, default value is false. -i, --sample-interval <value> Specify the sampling interval (in ms) when calculating cpu usage. --state <value> Display the thead filter by the state. NEW, RUNNABLE, TIMED_WAITING, WAITING, BLOCKED, TERMINATED is optional. -n, --top-n-threads <value> The number of thread(s) to show, ordered by cpu utilization, -1 to show all. <id> Show thread stack
$ thread -i 5000 ## Obtain the calculation summary data with a time span of 5s $ thread -n 3 ## Sort according to CPU utilization and obtain the stack information of three threads from high to low $ thread -b ## View only the stack information of deadlock threads $ thread --lockedSynchronizers ## View thread stack information for synchronizer deadlocks only
3.4 stop / exit
Stop: stop and exit the Arthas consol e, and exit the steps normally.
Exit: only leave the arthas console, but the arthas task bound to the Java process will not exit.
[SHELL]# java -jar arthas-boot.jar [INFO] arthas-boot version: 3.5.3 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 5201 cloud-access-auth-1.18.1.jar [2]: 14419 tsf-stack-base-1.0.0.jar [3]: 27862 cloud-access-gateway-1.18.1.jar [4]: 6550 tsfmanager-operation-1.29.1.jar 1 [INFO] arthas home: /root/.arthas/lib/3.5.4/arthas [INFO] Try to attach process 5201 [INFO] Attach process 5201 success. [INFO] arthas-client connect 127.0.0.1 3658 ,---. ,------. ,--------.,--. ,--. ,---. ,---. / O \ | .--. ''--. .--'| '--' | / O \ ' .-' | .-. || '--'.' | | | .--. || .-. |`. `-. | | | || |\ \ | | | | | || | | |.-' | `--' `--'`--' '--' `--' `--' `--'`--' `--'`-----' wiki https://arthas.aliyun.com/doc tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html version 3.5.4 main_class pid 5201 time 2021-09-03 13:05:51 [arthas@5201]$ exit [SHELL]# java -jar arthas-boot.jar [INFO] arthas-boot version: 3.5.3 [INFO] Process 5201 already using port 3658 ## Since the binding between Arthas and java process was not shut down last time, it was detected that Arthas was still bound to 5201 process when it was restarted. [INFO] Process 5201 already using port 8563 [INFO] Found existing java process, please choose one and input the serial number of the process, eg : 1. Then hit ENTER. * [1]: 5201 cloud-access-auth-1.18.1.jar [2]: 14419 tsf-stack-base-1.0.0.jar [3]: 27862 cloud-access-gateway-1.18.1.jar [4]: 6550 tsfmanager-operation-1.29.1.jar
We confirm this with jstack -l 5201
[root@VM-0-4-centos ~]# jstack -l 5201 | more 2021-09-03 13:08:16 Full thread dump OpenJDK 64-Bit Server VM (25.302-b08 mixed mode): "arthas-NettyHttpTelnetBootstrap-3-3" #169 daemon prio=5 os_prio=0 tid=0x00007f314000b800 nid=0x5632 runnable [0x00007f30cb51a000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x00000000e8cafb00> (a com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x00000000e8caf8a8> (a java.util.Collections$UnmodifiableSet) - locked <0x00000000e8caf790> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101) at com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68) at com.alibaba.arthas.deps.io.netty.channel.nio.NioEventLoop.select(NioEventLoop.java:810) at com.alibaba.arthas.deps.io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:457) at com.alibaba.arthas.deps.io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) at com.alibaba.arthas.deps.io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at com.alibaba.arthas.deps.io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - None "arthas-NettyHttpTelnetBootstrap-3-2" #168 daemon prio=5 os_prio=0 tid=0x00007f314000a000 nid=0x51ce runnable [0x00007f30d09f9000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method) at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269) at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x00000000e8cac058> (a com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySet) - locked <0x00000000e8cabe00> (a java.util.Collections$UnmodifiableSet) - locked <0x00000000e8cabce8> (a sun.nio.ch.EPollSelectorImpl) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97) at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:101) at com.alibaba.arthas.deps.io.netty.channel.nio.SelectedSelectionKeySetSelector.select(SelectedSelectionKeySetSelector.java:68)
We can see the java stack information of 5201 process, and the thread with arthas is running.
Normal exit steps:
[arthas@5201]$ stop Resetting all enhanced classes ... Affect(class count: 0 , method count: 0) cost in 0 ms, listenerId: 0 Arthas Server is going to shutdown... [arthas@5201]$ session (f0151617-7fd2-4b4b-b79f-31d366a72fc5) is closed because server is going to shutdown. [SHELL]# jstack -l 5201 | more 2021-09-03 13:10:16 Full thread dump OpenJDK 64-Bit Server VM (25.302-b08 mixed mode): "Abandoned connection cleanup thread" #51 daemon prio=5 os_prio=0 tid=0x00007f30e0246000 nid=0x1d86 in Object.wait() [0x00007f3120393000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144) - locked <0x00000000e3280300> (a java.lang.ref.ReferenceQueue$Lock) at com.mysql.jdbc.AbandonedConnectionCleanupThread.run(AbandonedConnectionCleanupThread.java:64) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - <0x00000000e3280390> (a java.util.concurrent.ThreadPoolExecutor$Worker) "Tomcat JDBC Pool Cleaner[1450495309:1630634377161]" #50 daemon prio=5 os_prio=0 tid=0x00007f30e01e4800 nid=0x1d85 in Object.wait() [0x00007f3120494000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.util.TimerThread.mainLoop(Timer.java:552) - locked <0x00000000e3280540> (a java.util.TaskQueue) at java.util.TimerThread.run(Timer.java:505) Locked ownable synchronizers: - None
You can see that after closing the arthas diagnostic program with the stop instruction, the arthas thread binding on the java process also exits.
3.5 watch command ⭐ -- Methods perform data observation
The watch instruction is one of the most commonly used instructions in Arthas. It can obtain the input parameters of the specified package, class and method, the internal object of its own class method and the returned object value.
[arthas@5201]$ watch -h USAGE: watch [-b] [-e] [--exclude-class-pattern <value>] [-x <value>] [-f] [-h] [-n <value>] [--listenerId <value>] [-E] [-M <value>] [-s] [-v] class-pattern method-pattern [express] [condition-express] SUMMARY: Display the input/output parameter, return object, and thrown exception of specified method invocation The express may be one of the following expression (evaluated dynamically): target : the object clazz : the object's class method : the constructor or method params : the parameters array of method params[0..n] : the element of parameters array returnObj : the returned object of method throwExp : the throw exception of method isReturn : the method ended by return isThrow : the method ended by throwing exception #cost : the execution time in ms of method invocation Examples: watch org.apache.commons.lang.StringUtils isBlank watch org.apache.commons.lang.StringUtils isBlank '{params, target, returnObj, throwExp}' -x 2 watch *StringUtils isBlank params[0] params[0].length==1 watch *StringUtils isBlank params '#cost>100' watch -f *StringUtils isBlank params watch *StringUtils isBlank params[0] watch -E -b org\.apache\.commons\.lang\.StringUtils isBlank params[0] watch javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter WIKI: https://arthas.aliyun.com/doc/watch OPTIONS: -b, --before Watch before invocation -e, --exception Watch after throw exception --exclude-class-pattern <value> exclude class name pattern, use either '.' or '/' as separator -x, --expand <value> Expand level of object (1 by default) -f, --finish Watch after invocation, enable by default -h, --help this help -n, --limits <value> Threshold of execution times --listenerId <value> The special listenerId -E, --regex Enable regular expression to match (wildcard matching by default) -M, --sizeLimit <value> Upper size limit in bytes for the result (10 * 1024 * 1024 by default) -s, --success Watch after successful invocation -v, --verbose Enables print verbose information, default value false. <class-pattern> The full qualified class name you want to watch <method-pattern> The method name you want to watch <express> The content you want to watch, written by ognl. Default value is '{params, target, returnObj}' Examples: params params[0] 'params[0]+params[1]' '{params[0], target, returnObj}' returnObj throwExp target clazz method <condition-express> Conditional expression in ognl style, for example: TRUE : 1==1 TRUE : true FALSE : false TRUE : 'params.length>=0' FALSE : 1==2 '#cost>100'
Parameter description
watch has many parameters, mainly because it can observe objects in four different scenes
Parameter name | Parameter description |
---|---|
class-pattern | Class name expression match |
method-pattern | Method name matches expression |
express | Observation expression, default value: {params, target, returnObj} |
condition-express | Conditional expression |
[b] | Observe before method call |
[e] | Observe after method abnormality |
[s] | Observe after the method returns |
[f] | Observe after the method ends (normal return and exception return) |
[E] | Enable regular expression matching. The default is wildcard matching |
[x:] | Specifies the attribute traversal depth of the output result, which is 1 by default |
The key point here is the observation expression, which is mainly composed of #OGNL Expression composition, so you can write "{params,returnObj}". As long as it is a legal ognl expression, it can be normally supported.
There are many observation dimensions, mainly reflected in the data structure of the parameter Advice. The Advice parameter encapsulates all the information of the notification node. Please refer to Expression core variable Description of the node in.
Use examples:
I need to observe the login method information of cloud-access-auth-1.18.1.jar process when processing login information. The log is as follows:
13:42:54.205 INFO [http-nio-7001-exec-4] c.t.c.access.sso.service.impl.AuthenticateService - [Access Auth] account login parameter. accountName:qcloudAdmin ,password:******
Get the specified class name as AuthenticateService.
We take it to Arthas to watch:
### Registration is abbreviated in the log file, so I use wildcard to match the class name. I also use * to replace the second parameter method name, all matching [arthas@5201]$ watch *AuthenticateService * Press Q or Ctrl+C to abort. Affect(class count: 2 , method count: 6) cost in 130 ms, listenerId: 16 ### From the output information, we can see that there are two classes and a total of six methods in all the codes of the Java process
Let's click the login button to see what actions can be observed in the watch:
[arthas@5201]$ watch *AuthenticateService * Press Q or Ctrl+C to abort. Affect(class count: 2 , method count: 6) cost in 130 ms, listenerId: 16 #### The first method starts executing Begin method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 13:51:25; [cost=2.217281ms] result=@ArrayList[ @Object[][isEmpty=false;size=3], @AuthenticateService[com.tencent.cloud.access.sso.service.impl.AuthenticateService@f5cadbf], @AccessAuthPrincipal[com.tencent.cloud.access.sso.model.AccessAuthPrincipal@72f71bf6], ] #### End of first method execution #### The second method starts executing Begin method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.updateSession location=AtExit ts=2021-09-03 13:51:25; [cost=0.956478ms] result=@ArrayList[ @Object[][isEmpty=false;size=2], @AuthenticateService[com.tencent.cloud.access.sso.service.impl.AuthenticateService@f5cadbf], @AuthenticationResponse[com.tencent.cloud.access.sso.model.AuthenticationResponse@6b2bae10], ] #### The second method executes exit End ..............
In the output information, we can see that the first line has the complete method path and the obtained exit state location.
- AtExit: indicates normal exit.
- AtExceptionExit: indicates an abnormal exit.
The second line has the start timestamp of method execution and cost overhead, and the last one is the result of watch.
Here, the ArrayList array of result is a powerful part of the watch instruction. It contains three objects by default:
- params: input parameter, usually array, here is @ Object object
- target: the current this object in operation, that is, the class object itself. Here is the @ AuthenticateService entity class object
- returnObj: returns the object value. Here is the returned @ AccessAuthPrincipal object
We re execute the watch instruction. This time, we specify the class name and method name exactly, and add a - x parsing depth parameter:
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login -x 2 Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 2) cost in 74 ms, listenerId: 17 method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 14:10:15; [cost=3.289679ms] result=@ArrayList[ @Object[][ @String[qcloudAdmin], @String[Bgi8c0yC+IAvRLkuQRy6kLQ6T2J/9PNrL6G/+KX9ppE=], @String[127.0.0.1], ], @AuthenticateService[ log=@Logger[Logger[com.tencent.cloud.access.sso.service.impl.AuthenticateService]], sessionDAO=@RedisSessionDAO[com.tencent.cloud.access.sso.shiro.RedisSessionDAO@61813e98], accountSessionService=@AccountSessionService[com.tencent.cloud.access.account.service.impl.AccountSessionService@30e815ac], accessAuthRealm=@AccessAuthRealm[com.tencent.cloud.access.sso.shiro.AccessAuthRealm@1faea5], accountService=@AccountService[com.tencent.cloud.access.account.service.impl.AccountService@197459d8], ssoProperties=@SsoProperties[com.tencent.cloud.access.sso.config.SsoProperties@461879b2], securityManager=@DefaultSecurityManager[org.apache.shiro.mgt.DefaultSecurityManager@3b0f92f0], ssoService=@QCloudSsoService[com.tencent.cloud.access.sso.service.impl.QCloudSsoService@4f8704f5], userService=@UserService[com.tencent.cloud.access.user.service.impl.UserService@5e69da74], ], @AccessAuthPrincipal[ serialVersionUID=@Long[-2856270666386831504], accountName=@String[qcloudAdmin], userId=null, accountId=@String[account-96a79v5b], password=@String[VYUQeJrC5EJq21t/f9rb1Djm+4+eanqXY3ZkW2oiiwA=], serviceCode=null, isAdmin=null, loginName=null, serialVersionUID=@Long[8229738167949958388], token=@String[54158a08d8104de57a855249eb6ffe06], serialVersionUID=@Long[-4556824360581761962], appId=null, subAccountUin=null, uin=null, requestId=null, region=null, kv=null, ], ] method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 14:10:15; [cost=9.571541ms] result=@ArrayList[ @Object[][ @LoginRequest[com.tencent.cloud.access.sso.model.LoginRequest@3dd2bbb0], ], @AuthenticateService[ log=@Logger[Logger[com.tencent.cloud.access.sso.service.impl.AuthenticateService]], sessionDAO=@RedisSessionDAO[com.tencent.cloud.access.sso.shiro.RedisSessionDAO@61813e98], accountSessionService=@AccountSessionService[com.tencent.cloud.access.account.service.impl.AccountSessionService@30e815ac], accessAuthRealm=@AccessAuthRealm[com.tencent.cloud.access.sso.shiro.AccessAuthRealm@1faea5], accountService=@AccountService[com.tencent.cloud.access.account.service.impl.AccountService@197459d8], ssoProperties=@SsoProperties[com.tencent.cloud.access.sso.config.SsoProperties@461879b2], securityManager=@DefaultSecurityManager[org.apache.shiro.mgt.DefaultSecurityManager@3b0f92f0], ssoService=@QCloudSsoService[com.tencent.cloud.access.sso.service.impl.QCloudSsoService@4f8704f5], userService=@UserService[com.tencent.cloud.access.user.service.impl.UserService@5e69da74], ], @AuthenticationResponse[ serialVersionUID=@Long[-6134589862066278677], token=@String[54158a08d8104de57a855249eb6ffe06], accountId=@String[account-96a79v5b], changePwd=@String[N], users=@ArrayList[isEmpty=false;size=1], ], ] ..............
The - x option of the watch instruction indicates the object depth of the three stages of parsing. The default value is 1, that is, only the object layer is parsed, and the next-level attributes of the object are not parsed.
Through the above instructions, we have obtained more detailed information about the input parameter, this object and return value, which are analyzed as follows:
params method input parameters:
- @String[qcloudAdmin]: parameter 1, user name
- @String[Bgi8c0yC+IAvRLkuQRy6kLQ6T2J/9PNrL6G/+KX9ppE =]: password encryption string
- @String[127.0.0.1]: source host information
The object inside this method:
- log=@Logger: defines the Logger object
- sessionDAO=@RedisSessionDAO: session data entry, RedisSessionDAO object
- accountSessionService=@AccountSessionService: private object
- ........
returnObj return value object, here is @ AccessAuthPrincipal object:
- serialVersionUID: user UID
- accountName: login user name
- Password: user password encryption string
- token: token string
- ........
3.5.1 conditional expression filtering
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login '{params[0]=qcloudAdmin,returnObj}' -x 2
The returned information of diagnosis contains params[0] and returnObj objects, and only gets the method call with input parameter params[0] == "qcloudAdmin", and the final resolution depth is 2.
Only calls that meet the conditions will be captured by Arthas.
3.5.2 observe abnormal information
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login '{params[0],throwExp}' -e -x 2
- -e: Indicates observation after throwing an exception
- The second parameter of the express observation expression is throwExp: the variable representing the exception information is throwExp
3.5.3 filter by method
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login '{params[0],returnObj}' '#cost>200' -x 2
- The fourth parameter condition express of the watch instruction is #cost > 200, which means that the diagnostic processing takes more than 200ms to be captured and output.
- -x 2: the parsing depth is 2.
3.5.4 only observe the properties of the current object
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login 'target' -x 3 Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 2) cost in 76 ms, listenerId: 23 method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 14:48:33; [cost=3.189525ms] result=@AuthenticateService[ log=@Logger[ serialVersionUID=@Long[5454405123156820674], FQCN=@String[ch.qos.logback.classic.Logger], name=@String[com.tencent.cloud.access.sso.service.impl.AuthenticateService], level=null, effectiveLevelInt=@Integer[20000], parent=@Logger[ serialVersionUID=@Long[5454405123156820674], FQCN=@String[ch.qos.logback.classic.Logger], name=@String[com.tencent.cloud.access.sso.service.impl], level=null, effectiveLevelInt=@Integer[20000], parent=@Logger[Logger[com.tencent.cloud.access.sso.service]], childrenList=@CopyOnWriteArrayList[isEmpty=false;size=2], aai=null, additive=@Boolean[true], loggerContext=@LoggerContext[ch.qos.logback.classic.LoggerContext[default]], ], childrenList=null, aai=null, additive=@Boolean[true], loggerContext=@LoggerContext[ DEFAULT_PACKAGING_DATA=@Boolean[false], root=@Logger[Logger[ROOT]], size=@Integer[501], noAppenderWarning=@Integer[0], loggerContextListenerList=@ArrayList[isEmpty=false;size=1], loggerCache=@ConcurrentHashMap[isEmpty=false;size=501], loggerContextRemoteView=@LoggerContextVO[LoggerContextVO{name='default', propertyMap={}, birthTime=1630634095948}], turboFilterList=@TurboFilterList[isEmpty=true;size=0], packagingDataEnabled=@Boolean[false], maxCallerDataDepth=@Integer[8], resetCount=@Integer[2], frameworkPackages=@ArrayList[isEmpty=true;size=0], birthTime=@Long[1630634095948], name=@String[default], sm=@BasicStatusManager[ch.qos.logback.core.BasicStatusManager@612c57fb], propertyMap=@HashMap[isEmpty=true;size=0], objectMap=@HashMap[isEmpty=false;size=6], configurationLock=@LogbackLock[ch.qos.logback.core.spi.LogbackLock@36566db5], scheduledExecutorService=null, scheduledFutures=@ArrayList[isEmpty=true;size=0], lifeCycleManager=@LifeCycleManager[ch.qos.logback.core.LifeCycleManager@44477e6], started=@Boolean[false], ], ], sessionDAO=@RedisSessionDAO[ .............
By extending our thinking, we can directly observe the information of the underlying jdbc connection through one call:
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.AuthenticateService login 'target.userService.userDao.jdbcTemplate.dataSource.pool.poolProperties.url' -x 2 Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 2) cost in 69 ms, listenerId: 34 method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 15:09:55; [cost=2.682966ms] result=@String[jdbc:mysql://*.*.*.*:3306/access_auth?useSSL=false&characterEncoding=utf8] method=com.tencent.cloud.access.sso.service.impl.AuthenticateService.login location=AtExit ts=2021-09-03 15:09:55; [cost=21.373065ms] result=@String[jdbc:mysql://*.*.*.*:3306/access_auth?useSSL=false&characterEncoding=utf8]
Here, from the top level down, we get the call, which involves the jdbc dataSource connection configuration information of database query.
result returns a String object with the value JDBC: MySQL: / / *. *. *): 3306 / access_ auth?useSSL=false&characterEncoding=utf8.
3.5.5 exclude specified classes
[arthas@5201]$ watch com.tencent.cloud.access.sso.service.impl.* * 'target' -x 1 --exclude-class-pattern AuthorizeService | grep --color AuthorizeService Press Q or Ctrl+C to abort.
- --Exclude class pattern: excludes the specified class
3.6 Trace command ⭐
Method calls the path internally and outputs the time-consuming data on each node on the method path
The trace command can actively search the method call path corresponding to class pattern / method pattern, render and count all the performance overhead on the whole call link and track the call link
Parameter description
Parameter name | Parameter description |
---|---|
class-pattern | Class name expression match |
method-pattern | Method name matches expression |
condition-express | Conditional expression |
[E] | Enable regular expression matching. The default is wildcard matching |
[n:] | Number of command executions |
#cost | Method execution time |
The key point here is the observation expression, which is mainly composed of #OGNL Expression composition, so you can write "{params,returnObj}". As long as it is a legal ognl expression, it can be normally supported.
There are many observation dimensions, mainly reflected in the data structure of the parameter Advice. The Advice parameter encapsulates all the information of the notification node.
Please refer to Expression core variable Description of the node in.
- For special usage, please refer to: https://github.com/alibaba/arthas/issues/71
- OGNL expression official website: https://commons.apache.org/proper/commons-ognl/language-guide.html
In many cases, we only want to see the trace results after the rt of a method is greater than a certain time. Now Arthas can filter the results according to the execution time of the method. For example, trace * stringutils isblank '#cost > 100' means that the trace results will be output when the execution time exceeds 100ms.
All three commands, watch/stack/trace, support #cost
Use examples:
[arthas@5201]$ trace com.tencent.cloud.access.sso.service.impl.AuthenticateService login Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 2) cost in 114 ms, listenerId: 49 `---ts=2021-09-03 15:37:52;thread_name=http-nio-7001-exec-5;id=18;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@1cfd053 `---[6.69059ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:login() +---[0.045058ms] com.tencent.cloud.access.sso.model.LoginRequest:getOpt() #87 +---[0.011503ms] com.tencent.cloud.access.sso.constant.LoginType:getType() #88 +---[0.004858ms] com.tencent.cloud.access.sso.constant.LoginType:getType() #89 +---[0.005082ms] com.tencent.cloud.access.sso.model.LoginRequest:getAccountName() #93 +---[0.005074ms] com.tencent.cloud.access.sso.model.LoginRequest:getPassword() #94 +---[min=0.002257ms,max=0.010395ms,total=0.012652ms,count=2] org.springframework.util.StringUtils:isEmpty() #95 +---[0.008128ms] com.tencent.cloud.access.sso.config.SsoProperties:isPasswordTextPrintable() #100 +---[0.084201ms] org.slf4j.Logger:info() #99 +---[0.00653ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:<init>() #101 +---[0.004871ms] com.tencent.cloud.access.sso.model.LoginRequest:getRemoteHost() #102 +---[3.317607ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:login() #102 | `---[3.285177ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:login() | +---[0.008045ms] org.apache.shiro.authc.UsernamePasswordToken:<init>() #139 | +---[0.011232ms] org.apache.shiro.subject.SimplePrincipalCollection:<init>() #141 | +---[0.00843ms] org.apache.shiro.subject.support.DelegatingSubject:<init>() #142 | +---[0.015667ms] org.apache.shiro.util.ThreadContext:bind() #143 | +---[1.051658ms] org.apache.shiro.subject.support.DelegatingSubject:login() #144 | +---[0.988623ms] org.apache.shiro.subject.support.DelegatingSubject:getSession() #145 | +---[0.015629ms] org.apache.shiro.session.Session:getId() #146 | +---[0.323618ms] org.apache.shiro.subject.support.DelegatingSubject:getPrincipal() #147 | +---[0.009258ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:setToken() #149 | +---[0.007608ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:setAccountName() #150 | +---[0.429798ms] org.apache.shiro.session.Session:setAttribute() #151 | `---[0.207347ms] com.tencent.cloud.access.account.service.IAccountSessionService:bind() #152 +---[0.010654ms] com.tencent.cloud.access.account.Account:<init>() #103 +---[0.824315ms] com.tencent.cloud.access.account.service.IAccountService:find() #103 +---[0.006474ms] com.tencent.cloud.access.account.Account:getLock() #104 +---[0.004144ms] com.tencent.cloud.access.account.Account:getChangePassword() #107 +---[0.005663ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:setChangePwd() #107 +---[0.004683ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:getToken() #108 +---[0.00414ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:setToken() #108 +---[0.003733ms] com.tencent.cloud.access.account.Account:getAccountId() #109 +---[0.005164ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:setAccountId() #109 +---[0.002866ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:setAccountName() #110 +---[0.00399ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:getAccountId() #112 +---[0.014922ms] com.tencent.cloud.access.user.User:<init>() #112 +---[0.004781ms] com.tencent.cloud.access.user.User:setAppIsolate() #113 +---[0.83272ms] com.tencent.cloud.access.user.service.IUserService:findAccountList() #114 +---[0.006398ms] com.tencent.cloud.access.user.User:getUserId() #116 +---[0.005214ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:setUserId() #116 +---[0.00349ms] com.tencent.cloud.access.sso.model.AccessAuthPrincipal:getToken() #118 +---[0.002987ms] com.tencent.cloud.access.user.User:getUserId() #118 +---[0.887095ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:updateSession() #118 `---[0.004734ms] com.tencent.cloud.access.sso.model.AuthenticationResponse:setUsers() #120 `---ts=2021-09-03 15:37:52;thread_name=http-nio-7001-exec-1;id=14;is_daemon=true;priority=5;TCCL=org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedWebappClassLoader@1cfd053 `---[1.28437ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:login() +---[0.003596ms] com.tencent.cloud.access.sso.model.LoginRequest:getOpt() #87 +---[0.006076ms] com.tencent.cloud.access.sso.constant.LoginType:getType() #88 +---[0.002865ms] com.tencent.cloud.access.sso.constant.LoginType:getType() #89 +---[0.010558ms] com.tencent.cloud.access.sso.model.LoginRequest:getAccessToken() #123 +---[0.003959ms] com.tencent.cloud.access.sso.model.LoginRequest:getUid() #124 +---[0.003368ms] org.springframework.util.StringUtils:isEmpty() #125 +---[0.002671ms] org.springframework.util.StringUtils:isEmpty() #128 `---[1.166953ms] com.tencent.cloud.access.sso.service.impl.AuthenticateService:updateSession() #131
3.6.1 time consuming filter diagnosis
[arthas@5201]$ trace com.tencent.cloud.access.sso.service.impl.AuthenticateService login '#cost > 2000'
- #Cost > 2000: capture only paths with an overhead time greater than 2000ms.
3.6.2 only one call of filtering method
[arthas@5201]$ trace com.tencent.cloud.access.sso.service.impl.AuthenticateService login -n 1
Capture a call to the specified method only once, and then exit the task.
3.7 sysprop instruction -- get or set process system properties
sysprop is mainly used to view and set the system property information of the current process.
Use examples
View the system properties of the current java process
[arthas@27878]$ sysprop KEY VALUE ------------------------------------------------------------------------- awt.toolkit sun.awt.X11.XToolkit file.encoding.pkg sun.io java.specification.version 1.8 sun.cpu.isalist sun.jnu.encoding UTF-8 java.class.path /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar java.vm.vendor Tencent sun.arch.data.model 64 java.vendor.url http://jdk.oa.com/ catalina.useNaming false user.timezone Asia/Shanghai org.jboss.logging.provider slf4j os.name Linux java.vm.specification.version 1.8 @appId tsf-ratelimit user.country US sun.java.launcher SUN_STANDARD sun.boot.library.path /data/TencentKona-8.0.2-252/jre/lib/amd64 sun.java.command /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar sun.cpu.endian little user.home /root user.language en java.specification.vendor Oracle Corporation java.home /data/TencentKona-8.0.2-252/jre file.separator / line.separator java.vm.specification.vendor Oracle Corporation java.specification.name Java Platform API Specification java.awt.graphicsenv sun.awt.X11GraphicsEnvironment java.awt.headless true LOG_LEVEL_PATTERN %5p [bootstrap,%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}] sun.boot.class.path /data/TencentKona-8.0.2-252/jre/lib/resources.jar:/data/TencentKona-8.0.2-252/jre/lib/rt.jar:/data/TencentKona-8.0.2-252/jre/lib/sunrsasign.jar:/data/TencentKona-8.0.2-252/jre/lib/jsse.jar:/data/TencentKona-8.0.2-2 52/jre/lib/jce.jar:/data/TencentKona-8.0.2-252/jre/lib/charsets.jar:/data/TencentKona-8.0.2-252/jre/lib/jfr.jar:/data/TencentKona-8.0.2-252/jre/classes java.protocol.handler.pkgs org.springframework.boot.loader sun.management.compiler HotSpot 64-Bit Tiered Compilers java.runtime.version 1.8.0_252-b1 java.net.preferIPv4Stack true user.name root path.separator : os.version 3.10.0-1127.19.1.el7.x86_64 java.endorsed.dirs /data/TencentKona-8.0.2-252/jre/lib/endorsed java.runtime.name OpenJDK Runtime Environment file.encoding UTF-8 spring.beaninfo.ignore true sun.nio.ch.bugLevel java.vm.name OpenJDK 64-Bit Server VM LOG_FILE /var/log/tsf-oss/tsf-ratelimit/tsf-ratelimit java.vendor.url.bug http://ce.oa.com/bia java.io.tmpdir /tmp catalina.home /tmp/tomcat.8220305148167761737.23000 java.version 1.8.0_252 user.dir /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1 os.arch amd64 PID 27878 java.vm.specification.name Java Virtual Machine Specification java.awt.printerjob sun.print.PSPrinterJob sun.os.patch.level unknown catalina.base /tmp/tomcat.8220305148167761737.23000 loader.path /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/config java.library.path /data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib::/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib java.vm.info mixed mode, sharing java.vendor Tencent java.vm.version 25.252-b1 java.ext.dirs /data/TencentKona-8.0.2-252/jre/lib/ext:/usr/java/packages/lib/ext sun.io.unicode.encoding UnicodeLittle java.class.version 52.0
Temporarily set the system properties of the current process
[arthas@29749]$ sysprop java.class.path /data/jdk/latest Successfully changed the system property. KEY VALUE ----------------------------------------------------------------------------------- java.class.path /data/jdk/latest
3.8 logger instruction -- * view or set logger
Parameter description
[arthas@29749]$ logger -h USAGE: logger [-c <value>] [--classLoaderClass <value>] [-h] [--include-no-appender] [-l <value>] [-n <value>] SUMMARY: Print logger info, and update the logger level Examples: logger logger -c 327a647b logger -c 327a647b --name ROOT --level debug logger --include-no-appender WIKI: https://arthas.aliyun.com/doc/logger OPTIONS: -c, --classloader <value> classLoader hashcode, if no value is set, default value is SystemClassLoader --classLoaderClass <value> The class name of the special class's classLoader. -h, --help this help --include-no-appender include the loggers which don't have appenders, default value false -l, --level <value> set logger level -n, --name <value> logger name
Use examples
Set the log level of the ROOT appender of the logger
##### Get logger class information [arthas@29749]$ logger name ROOT class ch.qos.logback.classic.Logger classLoader org.springframework.boot.loader.LaunchedURLClassLoader@5674cd4d classLoaderHash 5674cd4d level INFO effectiveLevel INFO ...................... ##### Set the ROOT name log level to DEBUG [arthas@29749]$ logger -c 5674cd4d -n ROOT -l DEBUG
3.9 heapdump instruction -- heap dump
Parameter description
[arthas@29749]$ heapdump -h USAGE: heapdump [-h] [-l] [file] SUMMARY: Heap dump Examples: heapdump ## Save the hprof file to the current directory heapdump --live ## Active object heapdump --live /tmp/dump.hprof WIKI: https://arthas.aliyun.com/doc/heapdump OPTIONS: -h, --help this help -l, --live Dump only live objects; if not specified, all objects in the heap are dumped. <file> Output file
3.10 SC instruction -- get the list of loaded classes
Parameter description
[arthas@29749]$ sc -h USAGE: sc [-c <value>] [--classLoaderClass <value>] [-d] [-x <value>] [-f] [-h] [-n <value>] [-E] class-pattern SUMMARY: Search all the classes loaded by JVM EXAMPLES: sc -d org.apache.commons.lang.StringUtils sc -d org/apache/commons/lang/StringUtils sc -d *StringUtils sc -d -f org.apache.commons.lang.StringUtils sc -E org\\.apache\\.commons\\.lang\\.StringUtils WIKI: https://arthas.aliyun.com/doc/sc OPTIONS: -c, --classloader <value> The hash code of the special class's classLoader --classLoaderClass <value> The class name of the special class's classLoader. -d, --details Display the details of class -x, --expand <value> Expand level of object (0 by default) -f, --field Display all the member variables -h, --help this help -n, --limits <value> Maximum number of matching classes with details (100 by default) -E, --regex Enable regular expression to match (wildcard matching by default) <class-pattern> Class name pattern, use either '.' or '/' as separator
Use examples
#### Get the list of loaded package names and class names according to the wildcard [arthas@29749]$ sc com.tencent.tsf.* com.sun.proxy.$Proxy132 com.sun.proxy.$Proxy143 com.tencent.tsf.TsfApplicationStarter com.tencent.tsf.TsfApplicationStarter$$EnhancerBySpringCGLIB$$e6e6d3dc com.tencent.tsf.common.TsfBaseEntity com.tencent.tsf.common.TsfPage com.tencent.tsf.common.TsfPageQuery com.tencent.tsf.common.aop.ControllerCommonLog ..............
-d parameter to obtain the basic information of a specific class:
[arthas@29749]$ sc com.tencent.tsf.TsfApplicationStarter -d class-info com.tencent.tsf.TsfApplicationStarter code-source file:/data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar!/BOOT-INF/lib/tsf-common-1.29.1.jar!/ name com.tencent.tsf.TsfApplicationStarter isInterface false isAnnotation false isEnum false isAnonymousClass false isArray false isLocalClass false isMemberClass false isPrimitive false isSynthetic false simple-name TsfApplicationStarter modifier public annotation org.springframework.boot.autoconfigure.SpringBootApplication,org.springframework.cloud.client.discovery.EnableDiscoveryClient,org.springframework.cloud.netflix.feign.EnableFeignClients,org.springframework.transaction.annotation.EnableTransactionManag ement,org.springframework.scheduling.annotation.EnableScheduling,org.springframework.context.annotation.EnableAspectJAutoProxy interfaces super-class +-java.lang.Object class-loader +-org.springframework.boot.loader.LaunchedURLClassLoader@5674cd4d +-sun.misc.Launcher$AppClassLoader@70dea4e +-sun.misc.Launcher$ExtClassLoader@65e2dbf3 classLoaderHash 5674cd4d class-info com.tencent.tsf.TsfApplicationStarter$$EnhancerBySpringCGLIB$$e6e6d3dc code-source file:/data/tsf/tsf-oss/tsf-ratelimit/tsf-ratelimit-1.29.1/lib/tsf-ratelimit-1.29.1.jar!/BOOT-INF/lib/tsf-common-1.29.1.jar!/ name com.tencent.tsf.TsfApplicationStarter$$EnhancerBySpringCGLIB$$e6e6d3dc isInterface false isAnnotation false isEnum false isAnonymousClass false isArray false isLocalClass false isMemberClass false isPrimitive false isSynthetic false simple-name TsfApplicationStarter$$EnhancerBySpringCGLIB$$e6e6d3dc modifier public annotation interfaces org.springframework.context.annotation.ConfigurationClassEnhancer$EnhancedConfiguration super-class +-com.tencent.tsf.TsfApplicationStarter +-java.lang.Object class-loader +-org.springframework.boot.loader.LaunchedURLClassLoader@5674cd4d +-sun.misc.Launcher$AppClassLoader@70dea4e +-sun.misc.Launcher$ExtClassLoader@65e2dbf3 classLoaderHash 5674cd4d Affect(row-cnt:2) cost in 17 ms.
3.11 sm instruction -- get the method information of the specified class
This instruction parameter is similar to the sc instruction parameter.
Use examples:
## Get a list of all methods of the com.tencent.tsf.common.TsfPageQuery class [arthas@29749]$ sm com.tencent.tsf.common.TsfPageQuery * com.tencent.tsf.ratelimit.domain.Ratelimit <init>(Lcom/tencent/tsf/ratelimit/domain/Ratelimit;)V com.tencent.tsf.ratelimit.domain.Ratelimit <init>()V com.tencent.tsf.ratelimit.domain.Ratelimit toString()Ljava/lang/String; com.tencent.tsf.ratelimit.domain.Ratelimit getRules()Ljava/util/List; com.tencent.tsf.ratelimit.domain.Ratelimit lambda$containsIn$0(Lcom/tencent/tsf/ratelimit/domain/Ratelimit$Rule;Lcom/tencent/tsf/ratelimit/domain/Ratelimit$Rule;)Z com.tencent.tsf.ratelimit.domain.Ratelimit setRules(Ljava/util/List;)V com.tencent.tsf.ratelimit.domain.Ratelimit isValidRequest(Z)Z com.tencent.tsf.ratelimit.domain.Ratelimit getRequestIdentity()Ljava/lang/String; com.tencent.tsf.ratelimit.domain.Ratelimit setNamespaceId(Ljava/lang/String;)V com.tencent.tsf.ratelimit.domain.Ratelimit containsIn(Ljava/util/List;)Z com.tencent.tsf.ratelimit.domain.Ratelimit isDimensionConflict(Ljava/util/List;)Z com.tencent.tsf.ratelimit.domain.Ratelimit getNamespaceId()Ljava/lang/String; com.tencent.tsf.ratelimit.domain.Ratelimit getServiceName()Ljava/lang/String; com.tencent.tsf.ratelimit.domain.Ratelimit setServiceName(Ljava/lang/String;)V com.tencent.tsf.common.proxy.Application <init>()V com.tencent.tsf.common.proxy.Application setApplicationId(Ljava/lang/String;)V com.tencent.tsf.common.proxy.Application getMicroserviceType()Ljava/lang/String; com.tencent.tsf.common.proxy.Application setMicroserviceType(Ljava/lang/String;)V com.tencent.tsf.common.proxy.Application getApplicationId()Ljava/lang/String; com.tencent.tsf.ratelimit.proxy.Microservice <init>()V com.tencent.tsf.ratelimit.proxy.Microservice setMicroserviceName(Ljava/lang/String;)V com.tencent.tsf.ratelimit.proxy.Microservice setNamespaceId(Ljava/lang/String;)V com.tencent.tsf.ratelimit.proxy.Microservice getMicroserviceName()Ljava/lang/String; com.tencent.tsf.ratelimit.proxy.Microservice getNamespaceId()Ljava/lang/String; com.tencent.tsf.ratelimit.proxy.Microservice getMicroserviceId()Ljava/lang/String; com.tencent.tsf.ratelimit.proxy.Microservice setMicroserviceId(Ljava/lang/String;)V com.tencent.tsf.common.TsfPageQuery <init>()V com.tencent.tsf.common.TsfPageQuery clear()V com.tencent.tsf.common.TsfPageQuery getOffset()Ljava/lang/Integer; com.tencent.tsf.common.TsfPageQuery setOffset(Ljava/lang/Integer;)V com.tencent.tsf.common.TsfPageQuery initDefault()V com.tencent.tsf.common.TsfPageQuery setSearchWord(Ljava/lang/String;)V com.tencent.tsf.common.TsfPageQuery getOrderType()Ljava/lang/Integer; com.tencent.tsf.common.TsfPageQuery getOrderTypeStr()Ljava/lang/String; com.tencent.tsf.common.TsfPageQuery setOrderType(Ljava/lang/Integer;)V com.tencent.tsf.common.TsfPageQuery getOrderBy()Ljava/lang/String; com.tencent.tsf.common.TsfPageQuery setOrderBy(Ljava/lang/String;)V com.tencent.tsf.common.TsfPageQuery getRealPage()I com.tencent.tsf.common.TsfPageQuery transerPageQuery(Lcom/tencent/tsf/common/TsfPageQuery;)V com.tencent.tsf.common.TsfPageQuery getSearchWordLikeStr()Ljava/lang/String; com.tencent.tsf.common.TsfPageQuery getLimit()Ljava/lang/Integer; com.tencent.tsf.common.TsfPageQuery setLimit(Ljava/lang/Integer;)V com.tencent.tsf.common.TsfPageQuery getSearchWord()Ljava/lang/String; Affect(row-cnt:43) cost in 12 ms.
3.12 monitor instruction -- method execution monitoring
This instruction is a non real-time return instruction. By default, the statistical value is returned once every 120s.
Statistics include the total number, success times, failure times, average execution rate, failure ratio and other information of method execution in the interval time period.
Parameter description
[arthas@8738]$ monitor -h USAGE: monitor [-b] [-c <value>] [--exclude-class-pattern <value>] [-h] [-n <value>] [--listenerId <value>] [-E <value>] [-v] class-pattern method-pattern [condition-express] SUMMARY: Monitor method execution statistics, e.g. total/success/failure count, average rt, fail rate, etc. Examples: monitor org.apache.commons.lang.StringUtils isBlank monitor org.apache.commons.lang.StringUtils isBlank -c 5 monitor org.apache.commons.lang.StringUtils isBlank params[0]!=null monitor -b org.apache.commons.lang.StringUtils isBlank params[0]!=null monitor -E org\.apache\.commons\.lang\.StringUtils isBlank WIKI: https://arthas.aliyun.com/doc/monitor OPTIONS: -b, --before Evaluate the condition-express before method invoke -c, --cycle <value> The monitor interval (in seconds), 60 seconds by default --exclude-class-pattern <value> exclude class name pattern, use either '.' or '/' as separator -h, --help this help -n, --limits <value> Threshold of execution times --listenerId <value> The special listenerId -E, --regex <value> Enable regular expression to match (wildcard matching by default) -v, --verbose Enables print verbose information, default value false. <class-pattern> Path and classname of Pattern Matching <method-pattern> Method of Pattern Matching <condition-express> Conditional expression in ognl style, for example: TRUE : 1==1 TRUE : true FALSE : false TRUE : 'params.length>=0' FALSE : 1==2 '#cost>100'
Use examples
[arthas@8738]$ monitor com.tencent.tsf.resource.ns.dao.NamespaceDao * Press Q or Ctrl+C to abort. Affect(class count: 1 , method count: 15) cost in 104 ms, listenerId: 6 timestamp class method total success fail avg-rt(ms) fail-rate ---------------------------------------------------------------------------------------------------------------------------------------------------- 2021-09-09 18:26:58 com.tencent.tsf.resource.ns.dao.NamespaceDao countList 12 12 0 1.08 0.00% 2021-09-09 18:26:58 com.tencent.tsf.resource.ns.dao.NamespaceDao getAuthWhereClause 28 28 0 0.18 0.00% 2021-09-09 18:26:58 com.tencent.tsf.resource.ns.dao.NamespaceDao findList 2 2 0 1.09 0.00%