Measure Spring RestTemplate HTTP request time
You can use AOP and the built in PerformanceMonitorInterceptor of Spring. You need to correctly define which methods of which calss you want to intercept then you can measure. You can configure it something like this:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"> <bean id="springMonitoredService" class="com.myorg.service.springmon.MyServiceSpringImpl"/> <bean id="springMonitoringAspectInterceptor" class="org.springframework.aop.interceptor.PerformanceMonitorInterceptor"> <property name="loggerName" value="com.myorg.SPRING_MONITOR"/> </bean> <aop:config> <aop:pointcut id="springMonitoringPointcut" expression="execution(* java.net.HttpURLConnection.connect(..))"/> <aop:advisor pointcut-ref="springMonitoringPointcut" advice-ref="springMonitoringAspectInterceptor"/> </aop:config></beans>
You can use Stopwatch to do that.
public class PerfRequestSyncInterceptor implements ClientHttpRequestInterceptor { private final static Logger LOG = LoggerFactory.getLogger(PerfRequestSyncInterceptor.class); @Override public ClientHttpResponse intercept(HttpRequest hr, byte[] bytes, ClientHttpRequestExecution chre) throws IOException { StopWatch stopwatch = StopWatch.createStarted(); ClientHttpResponse response = chre.execute(hr, bytes); stopwatch.stop(); LOG.info("method=" + hr.getMethod() + ", uri="+hr.getURI() + ", response_time=" + stopwatch.elapsed(TimeUnit.MILLISECONDS) + ", response_code=" + response.getStatusCode().value()); return response; }}
And in the class where restTemplate is instanced
private final List<ClientHttpRequestInterceptor> requestInterceptors = new ArrayList<>();requestInterceptors.add(new PerfRequestSyncInterceptor());this.restTemplate.setInterceptors(requestInterceptors);
Add the Stopwatch dependency for maven:
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>r05</version></dependency>
I want to measure the time of the HTTP GET request of a RestTemplate.getForObject call without the the time needed for parsing the response
I had the same requirements. I want to know the server response time to gauge how long it takes the server to respond without any RestTemplate response processing. I added two interceptors to the HttpClientBuilder
with a map so I could measure the time between the low level request and response.
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();// Attach interceptorsResponseTimeInterceptor interceptor = new ResponseTimeInterceptor();httpClientBuilder.addInterceptorFirst( (HttpRequestInterceptor) interceptor );httpClientBuilder.addInterceptorFirst( (HttpResponseInterceptor) interceptor );// Use client with RestTemplate or on its ownHttpClient client = httpClientBuilder.build();
Here is the minimal dual-duty interceptor:
public class ResponseTimeInterceptor implements HttpRequestInterceptor, HttpResponseInterceptor { private final Map<HttpContext, Long> requestMap = new MaxSizeHashMap<>( 50 ); @Override public void process( HttpRequest httpRequest, HttpContext httpContext ) throws HttpException, IOException { requestMap.put( httpContext, System.currentTimeMillis() ); } @Override public void process( HttpResponse httpResponse, HttpContext httpContext ) throws HttpException, IOException { long startTime = requestMap.getOrDefault( httpContext, 0L ); long diff = System.currentTimeMillis() - startTime; System.out.println( "Response time: " + diff + "ms" ); }}
After the response interceptor returns, the response data continues into the RestTemplate response handler.
Note: The MaxSizeHashMap
is taken from https://stackoverflow.com/a/5601377.