命令
dashboard
dashboard
命令可以查看当前系统的实时数据面板。
输入 Q 或者 Ctrl+C 可以退出dashboard命令。
thread
thread 1
命令会打印线程ID 1的栈。
Arthas支持管道,可以用thread 1 | grep 'main('
查找到main class。
可以看到main class是demo.MathGame:
$ thread 1 | grep 'main('
at demo.MathGame.main(MathGame.java:17)
Sc
可以通过 sc 命令来查找JVM里已加载的类:
sc -d *MathGame
如果搜索的是接口,还会搜索所有的实现类。比如查看所有的Filter实现类:
sc javax.servlet.Filter
通过-d参数,可以打印出类加载的具体信息,很方便查找类加载问题。
sc -d javax.servlet.Filter
sc支持通配,比如搜索所有的StringUtils:
sc *StringUtils
sm
sm命令则是查找类的具体函数。比如:
sm java.math.RoundingMode
通过-d参数可以打印函数的具体属性:
sm -d java.math.RoundingMode
也可以查找特定的函数,比如查找构造函数:
sm java.math.RoundingMode <init>
Jad
可以通过 jad 命令来反编译代码:
jad demo.MathGame
jad com.example.demo.arthas.user.UserController
通过–source-only参数可以只打印出在反编译的源代码:
jad --source-only com.example.demo.arthas.user.UserController
Watch
通过watch命令可以查看函数的参数/返回值/异常信息。
watch demo.MathGame primeFactors returnObj
输入 Q 或者 Ctrl+C 退出watch命令。
Exit/Stop
退出Arthas
用 exit
或者quit
命令可以退出Arthas。
退出Arthas之后,还可以再次用java -jar arthas-boot.jar
来连接。
彻底退出Arthas
exit/quit命令只是退出当前session,arthas server还在目标进程中运行。
想完全退出Arthas,可以执行 stop
命令。
进阶
查看JVM信息
下面介绍Arthas里查看JVM信息的命令。
sysprop
sysprop
可以打印所有的System Properties信息。
也可以指定单个key:sysprop java.version
也可以通过grep来过滤:sysprop | grep user
可以设置新的value: sysprop testKey testValue
sysenv
sysenv
命令可以获取到环境变量。和sysprop命令类似。
jvm
jvm
命令会打印出JVM的各种详细信息。
dashboard
dashboard
命令可以查看当前系统的实时数据面板。
输入 Q
或者 Ctrl+C 可以退出dashboard命令。
pipeline
Arthas支持在pipeline之后,执行一些简单的命令,比如:
sysprop | grep java
sysprop | wc -l
Ognl
在Arthas里,有一个单独的ognl
命令,可以动态执行代码。
调用static函数
ognl '@java.lang.System@out.println("hello ognl")'
可以检查Terminal 1
里的进程输出,可以发现打印出了hello ognl。
查找UserController的ClassLoader
sc -d com.example.demo.arthas.user.UserController | grep classLoaderHash
$ sc -d com.example.demo.arthas.user.UserController | grep classLoaderHash
classLoaderHash 1be6f5c3
注意hashcode是变化的,需要先查看当前的ClassLoader信息,提取对应ClassLoader的hashcode。
如果你使用-c
,你需要手动输入hashcode:-c <hashcode>
$ ognl -c 1be6f5c3 @com.example.demo.arthas.user.UserController@logger
对于只有唯一实例的ClassLoader可以通过--classLoaderClass
指定class name,使用起来更加方便:
$ 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]],
]
--classLoaderClass
的值是ClassLoader的类名,只有匹配到唯一的ClassLoader实例时才能工作,目的是方便输入通用命令,而-c 是动态变化的。
获取静态类的静态字段
获取UserController类里的logger字段:
ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader
@com.example.demo.arthas.user.UserController@logger
还可以通过-x参数控制返回值的展开层数。比如:
ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader
-x 2
@com.example.demo.arthas.user.UserController@logger
执行多行表达式,赋值给临时变量,返回一个List
ognl '#value1=@System@getProperty("java.home"),
#value2=@System@getProperty("java.runtime.name"),
{#value1, #value2}'
$ 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],
]
更多
在Arthas里ognl表达式是很重要的功能,在很多命令里都可以使用ognl表达式。
一些更复杂的用法,可以参考:
OGNL特殊用法请参考:https://github.com/alibaba/arthas/issues/71
OGNL表达式官方指南:https://commons.apache.org/proper/commons-ognl/language-guide.html