Home

Awesome

arthas

codecov maven license Average time to resolve an issue Percentage of issues still open

Arthas-MVEL use MVEL as first-class command parser and support all of the features of Arthas.

MVEL is a expression language just like OGNL but supports more features such as loop and function.

Installation

Download Arthas-MVEL from Release

Than launch it:

java -jar arthas-boot.jar

Usage

Use Arthas-MVEL just like arthas.


// support all commands of arthas
$ classloader
 name                                       numberOfInstances  loadedCountTotal
 sun.misc.Launcher$AppClassLoader           1                  28077
 com.taobao.arthas.agent.ArthasClassloader  3                  3847
 BootstrapClassLoader                       1                  3588
 sun.reflect.DelegatingClassLoader          320                320
 sun.misc.Launcher$ExtClassLoader           1                  10
 sun.reflect.misc.MethodUtil                1                  1
Affect(row-cnt:6) cost in 45 ms.


$ version
3.1.2.20190805151842

$ keymap
 Shortcut                         Description                     Name
 // ...

// some mvel expressions
$ abc = 123
@Integer[123]
$ abc = abc * 2
@Integer[246]

// call static function
$ java.lang.System.currentTimeMillis()
@Long[1564990990861]

// import class
$ import java.lang.System
@Class[
    ANNOTATION=@Integer[8192],
    ENUM=@Integer[16384],
    SYNTHETIC=@Integer[4096],
    cachedConstructor=null,
    // more

// call static function without FQCN
$ System.currentTimeMillis()
@Long[1564991009477]

// call function
$ joiner = com.google.common.base.Joiner.on("_")
@Joiner[
    separator=@String[_],
]
$ joiner.join("abc", "efg", "123")
@String[abc_efg_123]

// loop
$ count = 1
@Integer[1]
$ for (int i =0; i < 100; i++) { count = count + 1;}
null
$ count
@Integer[101]

// define a function
$ incrByTime = def (raw, time) { for (int i =0; i < time; i++) { raw = raw + 1;}; raw; }
@PrototypalFunctionInstance[
    resolverFactory=@MapVariableResolverFactory[
        variables=@HashMap[isEmpty=true;size=0],
    ],
]

// call function
$ incrByTime(1, 50)
@Integer[51]

// define a function to load bean
$ getBeanByName = def (name) { com.some.static.function.you.can.getBean(name) }
@PrototypalFunctionInstance[
    resolverFactory=@MapVariableResolverFactory[
        variables=@HashMap[isEmpty=true;size=0],
    ],
]

// call function of bean
// bean "userService" will be loaded by the function "getBeanByName"
$ userService.getById(123L)
@UserModel[
    serialVersionUID=@Long[-8752733010881684427],
    userId=@Long[123L],
    userName=@String[testUserName],
    // ...