import{_ as e,o as p,c as o,a as s,b as i,w as c,d as a,e as n,r as l}from"./app.5024572d.js";const u={},r=a(`

groovy

TIP

Arthas support groovy scripting to allow user to use script like BTrace. It is possible to use if/for/switch/while in groovy scripting, but has more limitations compared to BTrace.

Limitations

  1. Prohibit from alternating the original logic. Like watch command, The major purpose of scripting is monitoring and observing.
  2. Only allow to monitor at the stages of before/success/exception/finish on one method.

Parameters

ParameterExplanation
class-patternclass name pattern
method-patternmethod name pattern
script-filepaththe absolute path of the groovy script
[S]match all sub classes
[E]enable regex match, the default is wildcard match

Note: the third parameter script-filepath must be the absolute path of the groovy script, for example /tmp/test.groovy. It is not recommended to use relative path, e.g. ./test.groovy.

Explanation on the important callbacks

/**
 * Listeners for script to enhance the class
 */
interface ScriptListener {

    /**
     * When the script is created
     *
     * @param output Output
     */
    void create(Output output);

    /**
     * When the script is destroyed
     *
     * @param output Output
     */
    void destroy(Output output);

    /**
     * Before the method executes
     *
     * @param output Output
     * @param advice Advice
     */
    void before(Output output, Advice advice);

    /**
     * After the method returns
     *
     * @param output Output
     * @param advice Advice
     */
    void afterReturning(Output output, Advice advice);

    /**
     * After the method throws exceptions
     *
     * @param output Output
     * @param advice Advice
     */
    void afterThrowing(Output output, Advice advice);

}

Advice parameter

`,10),d=s("code",null,"Advice",-1),k=n(" contains all information necessary for notification. Refer to "),v=n("expression core parameters"),m=n(" for more details."),b=a(`

Output parameter

There are three methods in Output, used for outputting the corresponding text.

/**
 * Output
 */
interface Output {

    /**
     * Output text without line break
     *
     * @param string Text to output
     * @return this
     */
    Output print(String string);

    /**
     * Output text with line break
     *
     * @param string Text to output
     * @return this
     */
    Output println(String string);

    /**
     * Finish outputting from the script
     *
     * @return this
     */
    Output finish();

}

A groovy sample script to output logs

import com.taobao.arthas.core.command.ScriptSupportCommand
import com.taobao.arthas.core.util.Advice

import static java.lang.String.format

/**
 * Output method logs
 */
public class Logger implements ScriptSupportCommand.ScriptListener {

    @Override
    void create(ScriptSupportCommand.Output output) {
        output.println("script create.");
    }

    @Override
    void destroy(ScriptSupportCommand.Output output) {
        output.println("script destroy.");
    }

    @Override
    void before(ScriptSupportCommand.Output output, Advice advice) {
        output.println(format("before:class=%s;method=%s;paramslen=%d;%s;",
                advice.getClazz().getSimpleName(),
                advice.getMethod().getName(),
                advice.getParams().length, advice.getParams()))
    }

    @Override
    void afterReturning(ScriptSupportCommand.Output output, Advice advice) {
        output.println(format("returning:class=%s;method=%s;",
                advice.getClazz().getSimpleName(),
                advice.getMethod().getName()))
    }

    @Override
    void afterThrowing(ScriptSupportCommand.Output output, Advice advice) {
        output.println(format("throwing:class=%s;method=%s;",
                advice.getClazz().getSimpleName(),
                advice.getMethod().getName()))
    }
}

Run the script like this:

$ groovy com.alibaba.sample.petstore.dal.dao.ProductDao getProductById /Users/zhuyong/middleware/arthas/scripts/Logger.groovy -S
script create.
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 102 ms.
before:class=IbatisProductDao;method=getProductById;paramslen=1;[Ljava.lang.Object;@45df64fc;
returning:class=IbatisProductDao;method=getProductById;
before:class=IbatisProductDao;method=getProductById;paramslen=1;[Ljava.lang.Object;@5b0e2d00;
returning:class=IbatisProductDao;method=getProductById;
`,7);function h(g,f){const t=l("RouterLink");return p(),o("div",null,[r,s("p",null,[d,k,i(t,{to:"/en/doc/advice-class.html"},{default:c(()=>[v]),_:1}),m]),b])}const w=e(u,[["render",h],["__file","groovy.html.vue"]]);export{w as default};