arthas神器

您所在的位置:网站首页 今日映画什么意思呀 arthas神器

arthas神器

2024-01-03 13:23| 来源: 网络整理| 查看: 265

目录

一、原因

二、watch主要功能

三、使用

1、下载

2、测试类代码

四、示例

1、查看方法出参和返回值

2、查看类对象的属性

3、过滤不需要的请求

4、没有办法输出局部变量的值

5、查看方法耗时

五、arthas idea插件

一、原因

        曾经,线上出了问题又定位不到问题原因,就开始抓耳挠腮,一遍一遍仔细看代码,到底是哪里可能出错了呢?然后在可能出错的地方加上日志,然后重新部署,再看输出日志;发现不行,还需要输出这个方法中的这个参数,然后再重新部署;一遍一遍循环往复,甚是繁琐。心想就没有一个想debug那样可以在线时时查看的功能么?

        自从我接触了arthas,我被它强大的功能所折服。当我第一次看到同事使用arthas输出线上程序中任意方法的请求参数时心中一惊,还有这么神奇的工具呢?自此开启了我对arthas的崇拜之路。

        但是刚开始感觉还是会有点繁琐,不会过滤请求、不会看成员变量,有时候想看方法中某一参数的值,但是又不知道该怎么看,还是很苦恼。

        因此决定仔细学习一下arthas到底有哪些功能,都能做什么,这么好用的神器,不会用不是白白可惜了。

二、watch主要功能

1、查看方法入参、返回值

2、过滤无用的输出

3、查看类中的成员变量

4、无法查看方法中的局部变量

首先附上官方文档,更详细、更多的资料可以查看官方文档

watch — Arthas 3.6.2 文档

参数名称参数说明class-pattern类名表达式匹配method-pattern方法名表达式匹配express观察表达式condition-express条件表达式[b]在方法调用之前观察[e]在方法异常之后观察[s]在方法返回之后观察[f]在方法结束之后(正常返回和异常返回)观察[E]开启正则表达式匹配,默认为通配符匹配x指定输出结果的属性遍历深度,默认为 1n指定执行次数

        这部分可以先跳过,看完下面例子回过头来再看,这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj,target,throwExp}",只要是一个合法的 ognl 表达式,都能被正常支持。

params:表示方法入参,可以通过params[0]获取指定位置的参数,可以用于过滤请求条件使用;

returnObj:表示方法返回参数;

target:表示类对象,可以通过target查看成员变量的值;

throwExp:表示异常;

特别说明:

watch 命令定义了4个观察事件点,即 -b 方法调用前,-e 方法异常后,-s 方法返回后,-f 方法结束后

4个观察事件点 -b、-e、-s 默认关闭,-f 默认打开,当指定观察点被打开后,在相应事件点会对观察表达式进行求值并输出

这里要注意方法入参和方法出参的区别,有可能在中间被修改导致前后不一致,除了 -b 事件点 params 代表方法入参外,其余事件都代表方法出参

当使用 -b 时,由于观察事件点是在方法调用前,此时返回值或异常均不存在

三、使用 1、windows下载

下载地址

https://alibaba.github.io/arthas/arthas-boot.jar

2、linux下载

wget https://arthas.aliyun.com/arthas-boot.jar

直接用java -jar的方式启动,首先启动我们的demo项目,然后在启动arthas

2、测试类代码

DemoController类

package com.demo.controller; import com.demo.model.UserModel; import com.demo.service.DemoService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoController { @Autowired private DemoService demoService; @RequestMapping("/user") @GetMapping public String list(String name){ UserModel userModel = new UserModel(); userModel.setName(name); return demoService.getUser(name, userModel); } }

DemoService类

package com.demo.service; import com.demo.model.UserModel; import org.springframework.stereotype.Service; @Service public class DemoService { private static String PATH = "/home"; private String user; public String getUser(String name, UserModel userModel) { user = "zhangsan"; return userModel.getName(); } }

UserModel类

package com.demo.model; import lombok.Data; @Data public class UserModel { public UserModel(){} public UserModel(String id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } private String id; private String name; private Integer age; } 四、示例 1、查看方法入参和返回值

watch com.demo.service.DemoService getUser '{params,returnObj}' -x 3

2、查看类对象的属性

watch com.demo.service.DemoService getUser 'target' -x 2

查看类中静态变量,PATH为类中的静态成员变量

getstatic com.demo.service.DemoService PATH  -x 2

3、过滤不需要的请求

        实际使用中会有不相关的请求调用我们的目标方法,可以通过添加过滤条件,只输出我们自己请求的日志,params[0]=='demo'表示只有当第一个参数等于demo时才输出。

watch com.demo.service.DemoService getUser "{params,returnObj}" "params[0]=='demo'" -x 4

        当我们请求参数为demo1时,控制台并没有输出日志,当参数为demo时,可以正常输出。

采用参数UserModel对象中的属性过滤也是可以的,如下面示例:

watch com.demo.service.DemoService getUser "{params,returnObj}" "params[1].name=='demo'" -x 4

4、没有办法输方法中出局部变量的值(这点需要强调一下) public void A(){ String index = 0; String b = B(); String index = b; } public String B(){ return "B"; }

        比如上边的,想查看index最后的值是不可以的,我们只能通过拦截B()方法获取到b的值,却没有办法获取不是通过方法调用赋值的局部变量。

        很多时候,我们想输出方法中某一个变量的值,但是到目前为止还没有找到好的方法,只能获取赋值给这个参数的方法的返回值来确定,这是一个比较遗憾的地方。

        watch 虽然很方便和灵活,但需要提前想清楚观察表达式的拼写,这对排查问题而言要求太高,因为很多时候我们并不清楚问题出自于何方,只能靠蛛丝马迹进行猜测。

        这个时候如果能记录下当时方法调用的所有入参和返回值、抛出的异常会对整个问题的思考与判断非常有帮助。

        同时还有更多命令和方法协同使用来定位问题,比如:

1)trace获得一个方法的调用路径;

2)tt: 记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。

        我也还在进一步学习、使用中,以后有了更多的总结再来补充。

5、查看方法耗时

        当遇到执行时间比较长的接口,我们想知道时间到底消耗在哪里,但是手动去输出每个方法又太繁琐,这时候arthas告诉你,让我来!一个trace命令轻松搞定。

        比如我们想查看DemoController#list()方法的内部耗时,只需要执行下面的命令,就可以看的一清二楚。

trace com.demo.controller.DemoController list

五、arthas idea插件

        有了arthas这种神器可以线上输出日志,但是watch语法还是不够简单,因此Idea arthas 插件就此横空出世,插件安装成功后,只需要将光标放置在具体的类、字段、方法上面 右键选择需要执行的命令,部分会有窗口弹出、根据界面操作获取命令;部分直接获取命令复制到了剪切板 ,自己启动arthas 后粘贴即可执行。

复制出来的命令:

watch com.demo.service.DemoService getUser '{params,returnObj,throwExp}' -v -n 5 -x 3 '1==1'



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3