@ -1,5 +1,5 @@
/ *
/ *
* Copyright 2012 - 20 19 the original author or authors .
* Copyright 2012 - 20 20 the original author or authors .
*
*
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* Licensed under the Apache License , Version 2.0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* you may not use this file except in compliance with the License .
@ -18,6 +18,8 @@ package org.springframework.boot.actuate.metrics.web.client;
import java.io.IOException ;
import java.io.IOException ;
import java.net.URI ;
import java.net.URI ;
import java.util.Deque ;
import java.util.LinkedList ;
import java.util.Map ;
import java.util.Map ;
import java.util.concurrent.TimeUnit ;
import java.util.concurrent.TimeUnit ;
@ -41,7 +43,7 @@ import org.springframework.web.util.UriTemplateHandler;
* /
* /
class MetricsClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
class MetricsClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
private static final ThreadLocal < String> urlTemplate = new NamedThreadLocal< > ( "Rest Template URL Template" ) ;
private static final ThreadLocal < Deque< String> > urlTemplate = new UrlTemplateThreadLocal( ) ;
private final MeterRegistry meterRegistry ;
private final MeterRegistry meterRegistry ;
@ -96,22 +98,24 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
finally {
finally {
getTimeBuilder ( request , response ) . register ( this . meterRegistry ) . record ( System . nanoTime ( ) - startTime ,
getTimeBuilder ( request , response ) . register ( this . meterRegistry ) . record ( System . nanoTime ( ) - startTime ,
TimeUnit . NANOSECONDS ) ;
TimeUnit . NANOSECONDS ) ;
if ( urlTemplate . get ( ) . isEmpty ( ) ) {
urlTemplate . remove ( ) ;
urlTemplate . remove ( ) ;
}
}
}
}
}
UriTemplateHandler createUriTemplateHandler ( UriTemplateHandler delegate ) {
UriTemplateHandler createUriTemplateHandler ( UriTemplateHandler delegate ) {
return new UriTemplateHandler ( ) {
return new UriTemplateHandler ( ) {
@Override
@Override
public URI expand ( String url , Map < String , ? > arguments ) {
public URI expand ( String url , Map < String , ? > arguments ) {
urlTemplate . set ( url ) ;
urlTemplate . get( ) . push ( url ) ;
return delegate . expand ( url , arguments ) ;
return delegate . expand ( url , arguments ) ;
}
}
@Override
@Override
public URI expand ( String url , Object . . . arguments ) {
public URI expand ( String url , Object . . . arguments ) {
urlTemplate . set ( url ) ;
urlTemplate . get( ) . push ( url ) ;
return delegate . expand ( url , arguments ) ;
return delegate . expand ( url , arguments ) ;
}
}
@ -120,8 +124,21 @@ class MetricsClientHttpRequestInterceptor implements ClientHttpRequestIntercepto
private Timer . Builder getTimeBuilder ( HttpRequest request , ClientHttpResponse response ) {
private Timer . Builder getTimeBuilder ( HttpRequest request , ClientHttpResponse response ) {
return this . autoTimer . builder ( this . metricName )
return this . autoTimer . builder ( this . metricName )
. tags ( this . tagProvider . getTags ( urlTemplate . get ( ) , request , response ) )
. tags ( this . tagProvider . getTags ( urlTemplate . get ( ) .poll ( ) , request , response ) )
. description ( "Timer of RestTemplate operation" ) ;
. description ( "Timer of RestTemplate operation" ) ;
}
}
private static final class UrlTemplateThreadLocal extends NamedThreadLocal < Deque < String > > {
private UrlTemplateThreadLocal ( ) {
super ( "Rest Template URL Template" ) ;
}
@Override
protected Deque < String > initialValue ( ) {
return new LinkedList < > ( ) ;
}
}
}
}