23
23
import com .google .api .client .util .StreamingContent ;
24
24
import com .google .api .client .util .StringUtils ;
25
25
import com .google .common .util .concurrent .ThreadFactoryBuilder ;
26
+ import io .opencensus .common .Scope ;
27
+ import io .opencensus .contrib .http .util .HttpTraceAttributeConstants ;
28
+ import io .opencensus .trace .AttributeValue ;
29
+ import io .opencensus .trace .Span ;
30
+ import io .opencensus .trace .Tracer ;
26
31
import java .io .IOException ;
27
32
import java .io .InputStream ;
28
33
import java .util .Properties ;
@@ -192,6 +197,9 @@ public final class HttpRequest {
192
197
/** Sleeper. */
193
198
private Sleeper sleeper = Sleeper .DEFAULT ;
194
199
200
+ /** OpenCensus tracing component. */
201
+ private final Tracer tracer = OpenCensusUtils .getTracer ();
202
+
195
203
/**
196
204
* Determines whether {@link HttpResponse#getContent()} of this request should return raw input
197
205
* stream or not.
@@ -835,7 +843,13 @@ public HttpResponse execute() throws IOException {
835
843
Preconditions .checkNotNull (requestMethod );
836
844
Preconditions .checkNotNull (url );
837
845
846
+ Span span =
847
+ tracer
848
+ .spanBuilder (OpenCensusUtils .SPAN_NAME_HTTP_REQUEST_EXECUTE )
849
+ .setRecordEvents (OpenCensusUtils .isRecordEvent ())
850
+ .startSpan ();
838
851
do {
852
+ span .addAnnotation ("retry #" + (numRetries - retriesRemaining ));
839
853
// Cleanup any unneeded response from a previous iteration
840
854
if (response != null ) {
841
855
response .ignore ();
@@ -850,6 +864,10 @@ public HttpResponse execute() throws IOException {
850
864
}
851
865
// build low-level HTTP request
852
866
String urlString = url .build ();
867
+ addSpanAttribute (span , HttpTraceAttributeConstants .HTTP_METHOD , requestMethod );
868
+ addSpanAttribute (span , HttpTraceAttributeConstants .HTTP_HOST , url .getHost ());
869
+ addSpanAttribute (span , HttpTraceAttributeConstants .HTTP_PATH , url .getRawPath ());
870
+ addSpanAttribute (span , HttpTraceAttributeConstants .HTTP_URL , urlString );
853
871
854
872
LowLevelHttpRequest lowLevelHttpRequest = transport .buildRequest (requestMethod , urlString );
855
873
Logger logger = HttpTransport .LOGGER ;
@@ -879,11 +897,14 @@ public HttpResponse execute() throws IOException {
879
897
if (!suppressUserAgentSuffix ) {
880
898
if (originalUserAgent == null ) {
881
899
headers .setUserAgent (USER_AGENT_SUFFIX );
900
+ addSpanAttribute (span , HttpTraceAttributeConstants .HTTP_USER_AGENT , USER_AGENT_SUFFIX );
882
901
} else {
883
902
String newUserAgent = originalUserAgent + " " + USER_AGENT_SUFFIX ;
884
903
headers .setUserAgent (newUserAgent );
904
+ addSpanAttribute (span , HttpTraceAttributeConstants .HTTP_USER_AGENT , newUserAgent );
885
905
}
886
906
}
907
+ OpenCensusUtils .propagateTracingContext (span , headers );
887
908
888
909
// headers
889
910
HttpHeaders .serializeHeaders (headers , logbuf , curlbuf , logger , lowLevelHttpRequest );
@@ -967,8 +988,15 @@ public HttpResponse execute() throws IOException {
967
988
lowLevelHttpRequest .setTimeout (connectTimeout , readTimeout );
968
989
lowLevelHttpRequest .setWriteTimeout (writeTimeout );
969
990
991
+ // switch tracing scope to current span
992
+ @ SuppressWarnings ("MustBeClosedChecker" )
993
+ Scope ws = tracer .withSpan (span );
994
+ OpenCensusUtils .recordSentMessageEvent (span , lowLevelHttpRequest .getContentLength ());
970
995
try {
971
996
LowLevelHttpResponse lowLevelHttpResponse = lowLevelHttpRequest .execute ();
997
+ if (lowLevelHttpResponse != null ) {
998
+ OpenCensusUtils .recordReceivedMessageEvent (span , lowLevelHttpResponse .getContentLength ());
999
+ }
972
1000
// Flag used to indicate if an exception is thrown before the response is constructed.
973
1001
boolean responseConstructed = false ;
974
1002
try {
@@ -986,13 +1014,17 @@ public HttpResponse execute() throws IOException {
986
1014
if (!retryOnExecuteIOException
987
1015
&& (ioExceptionHandler == null
988
1016
|| !ioExceptionHandler .handleIOException (this , retryRequest ))) {
1017
+ // static analysis shows response is always null here
1018
+ span .end (OpenCensusUtils .getEndSpanOptions (null ));
989
1019
throw e ;
990
1020
}
991
1021
// Save the exception in case the retries do not work and we need to re-throw it later.
992
1022
executeException = e ;
993
1023
if (loggable ) {
994
1024
logger .log (Level .WARNING , "exception thrown while executing request" , e );
995
1025
}
1026
+ } finally {
1027
+ ws .close ();
996
1028
}
997
1029
998
1030
// Flag used to indicate if an exception is thrown before the response has completed
@@ -1049,6 +1081,8 @@ public HttpResponse execute() throws IOException {
1049
1081
}
1050
1082
}
1051
1083
} while (retryRequest );
1084
+ span .end (OpenCensusUtils .getEndSpanOptions (response == null ? null : response .getStatusCode ()));
1085
+
1052
1086
if (response == null ) {
1053
1087
// Retries did not help resolve the execute exception, re-throw it.
1054
1088
throw executeException ;
@@ -1163,6 +1197,12 @@ public HttpRequest setSleeper(Sleeper sleeper) {
1163
1197
return this ;
1164
1198
}
1165
1199
1200
+ private static void addSpanAttribute (Span span , String key , String value ) {
1201
+ if (value != null ) {
1202
+ span .putAttribute (key , AttributeValue .stringAttributeValue (value ));
1203
+ }
1204
+ }
1205
+
1166
1206
private static String getVersion () {
1167
1207
String version = HttpRequest .class .getPackage ().getImplementationVersion ();
1168
1208
// in a non-packaged environment (local), there's no implementation version to read
0 commit comments