7
环境信息
- Arthas 版本: 3.6.3
- 待观察方法,请求localhost:8080/common/getTopDeviceBrand?startTime=2022-05-11 00:00:00&endTime=2022-05-17 23:59:59&appVersion=62*4572752.0.0.7.20220506102153&appId=62
public Result getTopTerm(TrendRequest trendRequest, boolean isDeviceBrand) throws Exception { if (BuglyStatInfoService.checkRequest(trendRequest)) { return Result.error(Status.REQUEST_PARAMS_NOT_VALID_ERROR); } AppInfo appInfo = appInfoDao.getByAppId(trendRequest.getAppId()); trendRequest.setAppId(100000); isDeviceBrand = false; if (appInfo == null) { return Result.error("appInfo is null"); } //中间省略 return Result.success(appInfo); }
- HTTP API方式,命令行watch XXX.StatService getTopTerm '{params}' -b -e -s -x 4,拉取结果,结果不正常,为出参
{ "accessPoint": "AtEnter", "className": "XXX.StatService", "cost": 0.0077, "expand": 4, "jobId": 4, "methodName": "getTopTerm", "sizeLimit": 10485760, "ts": "2022-06-17 11:57:54", "type": "watch", "value": [ [ { "appId": 100000, "appVersion": "4572752.0.0.7.20220506102153", "endTime": "2022-05-17 23:59:59", "startTime": "2022-05-11 00:00:00" }, true ] ] },
- 命令行方式watch XXX.StatService getTopTerm '{params}' -b -e -s -x 4,结果正常,为入参
method=XXX.StatService.getTopTerm location=AtEnter ts=2022-06-17 11:51:25; [cost=0.0077ms] result=@ArrayList[ @Object[][ @TrendRequest[ startTime=@String[2022-05-11 00:00:00], endTime=@String[2022-05-17 23:59:59], exceptionType=null, appId=@Integer[62], appVersion=@String[62*4572752.0.0.7.20220506102153], channelEnum=null, ], @Boolean[true], ], ]
@hengyunabc 个人分析,可能有误,麻烦帮忙指正
参数trendRequest是引用类型,isDeviceBrand是基础类型,方法中间对参数做了修改
在使用命令行时,执行到atEnter方法时,直接就输出了,不存在问题
在使用HTTP API时,执行到atEnter方法时,将结果存入内存队列,再执行到atExit方法时,也将结果存入内存队列,这两个结果中的params中的部分的TrendRequest指向同一个地址,所以导致AtEnter的结果是出参。
请问,在WatchAdviceListener的watching方法,如果是AtEnter,是不是应该处理一下,比如用深拷贝(如果用序列化实现深拷贝就会转为Map,获取不到变量名),有没有其它更好的方法?
Object value = getExpressionResult(command.getExpress(), advice, cost);
WatchModel model = new WatchModel();
model.setTs(new Date());
model.setCost(cost);
model.setValue(value);