Repository navigation
[Bug] agent录制结果为null #553
Description
Search before asking
- I have searched the existing issues before asking.
AREX Test Service
AREX Java Agent (arextest/arex-agent-java)
Current Behavior
你好!
描述:在录制时,子调用未录取到值返回值为Null,导致上层接口返回值也为Null
猜测:发生远程调用是公司人员内部封装了restTemplate和OKHttp等
具体代码:
代码入口1:
// service-url.menu.validate 实际是一个http://地址
@restclient(url = "${service-url.menu.validate}")
public interface MenuValidatePreOrder extends MenuValidateClient{
@Override
@PostMapping(value = "epl")
ProductRes getProductBetter(@RequestBody StoreVo storeVo);
}
代码入口2:
@target({ElementType.TYPE})
@retention(RetentionPolicy.RUNTIME)
@documented
public @interface RestClient {
String name() default "";
String url() default "";
String path() default "";
}
代码入口3:
@configuration
public class RestClientConfiguration implements BeanDefinitionRegistryPostProcessor {
private static final Logger LOGGER = LoggerFactory.getLogger(RestClientConfiguration.class);
public RestClientConfiguration() {
}
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
Environment environment = (Environment)((DefaultListableBeanFactory)registry).getBean("environment");
String packagePrefix = environment.getProperty("cloud.vo.package.prefix", "com.cloud.vo3");
Reflections reflections = new Reflections(packagePrefix, new Scanner[0]);
Set<Class<?>> restClientClassSet = reflections.getTypesAnnotatedWith(RestClient.class);
Iterator var6 = restClientClassSet.iterator();
AbstractBeanDefinition beanDefinition;
while(var6.hasNext()) {
Class<?> restClientClass = (Class)var6.next();
if (restClientClass.isInterface()) {
Object restClient = restClientClass.cast(Proxy.newProxyInstance(restClientClass.getClassLoader(), new Class[]{restClientClass}, new RestClientHandler()));
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(restClient.getClass());
definition.addConstructorArgValue(new RestClientHandler());
definition.setAutowireMode(1);
beanDefinition = definition.getBeanDefinition();
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, this.getBeanName(restClientClass), new String[0]);
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
}
}
reflections = new Reflections(packagePrefix, new Scanner[]{new MethodAnnotationsScanner()});
Set<Method> methodSet = reflections.getMethodsAnnotatedWith(CustomRestTemplate.class);
Iterator var13 = methodSet.iterator();
while(var13.hasNext()) {
Method method = (Method)var13.next();
String restTemplateName = ((CustomRestTemplate)method.getAnnotation(CustomRestTemplate.class)).value();
if (!RestTemplateFactory.restTemplateRepository.containsKey(restTemplateName)) {
beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(RestTemplate.class);
registry.registerBeanDefinition(restTemplateName, beanDefinition);
RestTemplateFactory.restTemplateRepository.put(restTemplateName, (Object)null);
}
}
String restTemplateName = "urlRestTemplate";
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setBeanClass(RestTemplate.class);
registry.registerBeanDefinition(restTemplateName, beanDefinition);
RestTemplateFactory.restTemplateRepository.put(restTemplateName, (Object)null);
}
代码入口4:
@configuration
public class RestTemplateConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(RestTemplateConfiguration.class);
private static final String CONNECT_TIMEOUT_KEY = "restClient.%s.connectTimeout";
private static final String READ_TIMEOUT_KEY = "restClient.%s.readTimeout";
private static final String USE_OK_HTTP_KEY = "restClient.%s.useOkhttp";
@Autowired
private HttpClient httpClient;
@Autowired
private OkHttpClient okHttpClient;
@Autowired
private Environment environment;
@Autowired(
required = false
)
private PrintReqResponseLog4ClientInterceptor printReqResponseLog4ClientInterceptor;
@Autowired(
required = false
)
private AddTraceInfoHeader4ClientInterceptor addTraceInfoHeader4ClientInterceptor;
public RestTemplateConfiguration() {
}
@Bean
public RestTemplate restTemplate(@Autowired RestTemplate restTemplate) {
LOGGER.info("初始化内部服务调用的RestTemplate");
int connectTimeout = this.properties.getConnectTimeout().intValue() * 1000;
int readTimeout = this.properties.getReadTimeout().intValue() * 1000;
boolean useOkhttp = Boolean.parseBoolean(this.environment.getProperty(String.format("restClient.%s.useOkhttp", "restTemplate"), "false"));
if (useOkhttp) {
restTemplate.setRequestFactory(this.okHttpRequestFactory(this.okHttpClient, connectTimeout, readTimeout));
} else {
restTemplate.setRequestFactory(this.httpClientRequestFactory(this.httpClient, connectTimeout, readTimeout));
}
restTemplate.setErrorHandler(new RestResponseErrorHandler());
this.changeMessageConverter(restTemplate);
return restTemplate;
}
Expected Behavior
您好!
我的预期行为是在Anything else 可以录制到子进程
Steps To Reproduce
您好!
1、在当前行为中,我复制了一些项目中自定义封装的远程调用,我想请问下,处于这种情况,我们arex-agent是不是就是会录制不到自调用的信息。
2、我在社区看到arex-agent不支持公司内部自定义封装的开源插件,想我这种情况,是不是就是不支持,需要开发针对于目标项目适配的插件
3、我将图片贴到Anything else 里了
Anything else
Are you willing to submit a pull request to fix on your own?
- Yes I am willing to submit a pull request on my own!


Activity
[-][Bug] [/-][+][Bug] agent录制结果为null[/+]lucas-myx commentedon Jul 31, 2024
@freedom-zhishui 感谢反馈
restTemplate和okhttp都是支持录制的,而且你的截图显示的是结果为null,并不是没有录制,如果没有录制下来就不会有这条记录,从现象看是只录制了请求参数,响应未录制,这种情况可能是结果无法序列化导致的,可以查下应用的日志信息,如果方便也可以直接在QQ群(656108079)里沟通,谢谢!
freedom-zhishui commentedon Jul 31, 2024
lucas-myx commentedon Dec 12, 2024
查下录制的日志,在挂载arex-agent.jar的目录下会生成log目录,可以搜下arex.record.Http开头的日志