15
15
package com .google .api .client .util ;
16
16
17
17
import com .google .api .client .http .HttpHeaders ;
18
+ import com .google .api .client .http .HttpRequest ;
18
19
import com .google .api .client .http .HttpResponse ;
19
20
import com .google .api .client .http .HttpStatusCodes ;
21
+ import com .google .common .annotations .VisibleForTesting ;
20
22
21
23
import io .opencensus .contrib .http .util .HttpPropagationUtil ;
22
24
import io .opencensus .trace .BlankSpan ;
23
25
import io .opencensus .trace .EndSpanOptions ;
26
+ import io .opencensus .trace .NetworkEvent ;
27
+ import io .opencensus .trace .NetworkEvent .Type ;
24
28
import io .opencensus .trace .Span ;
25
29
import io .opencensus .trace .Status ;
26
30
import io .opencensus .trace .Tracer ;
27
31
import io .opencensus .trace .Tracing ;
28
32
import io .opencensus .trace .propagation .TextFormat ;
29
33
30
34
import java .io .IOException ;
35
+ import java .util .Collections ;
36
+ import java .util .concurrent .atomic .AtomicLong ;
31
37
import java .util .logging .Level ;
32
38
import java .util .logging .Logger ;
33
39
import javax .annotation .Nullable ;
@@ -42,26 +48,49 @@ public class OpenCensusUtils {
42
48
43
49
private static final Logger LOGGER = Logger .getLogger (OpenCensusUtils .class .getName ());
44
50
51
+ /**
52
+ * Span name for tracing {@link HttpRequest#execute()}.
53
+ */
54
+ public static final String SPAN_NAME_HTTP_REQUEST_EXECUTE =
55
+ "Sent." + HttpRequest .class .getName () + ".execute" ;
56
+
45
57
/**
46
58
* OpenCensus tracing component.
47
59
* When no OpenCensus implementation is provided, it will return a no-op tracer.
48
60
*/
49
- static Tracer tracer = Tracing .getTracer ();
61
+ private static Tracer tracer = Tracing .getTracer ();
62
+
63
+ /**
64
+ * Sequence id generator for message event.
65
+ */
66
+ private static AtomicLong idGenerator = new AtomicLong ();
67
+
68
+ /**
69
+ * Whether spans should be recorded locally. Defaults to true.
70
+ */
71
+ private static volatile boolean isRecordEvent = true ;
50
72
51
73
/**
52
74
* {@link TextFormat} used in tracing context propagation.
53
75
*/
54
76
@ Nullable
55
- static TextFormat propagationTextFormat = null ;
77
+ @ VisibleForTesting
78
+ static volatile TextFormat propagationTextFormat = null ;
56
79
57
80
/**
58
- * {@link TextFormat.Setter} for {@link activeTextFormat }.
81
+ * {@link TextFormat.Setter} for {@link #propagationTextFormat }.
59
82
*/
60
83
@ Nullable
61
- static TextFormat .Setter propagationTextFormatSetter = null ;
84
+ @ VisibleForTesting
85
+ static volatile TextFormat .Setter propagationTextFormatSetter = null ;
62
86
63
87
/**
64
88
* Sets the {@link TextFormat} used in context propagation.
89
+ *
90
+ * <p>This API allows users of google-http-client to specify other text format, or disable context
91
+ * propagation by setting it to {@code null}. It should be used along with {@link
92
+ * #setPropagationTextFormatSetter} for setting purpose. </p>
93
+ *
65
94
* @param textFormat the text format.
66
95
*/
67
96
public static void setPropagationTextFormat (@ Nullable TextFormat textFormat ) {
@@ -70,12 +99,28 @@ public static void setPropagationTextFormat(@Nullable TextFormat textFormat) {
70
99
71
100
/**
72
101
* Sets the {@link TextFormat.Setter} used in context propagation.
102
+ *
103
+ * <p>This API allows users of google-http-client to specify other text format setter, or disable
104
+ * context propagation by setting it to {@code null}. It should be used along with {@link
105
+ * #setPropagationTextFormat} for setting purpose. </p>
106
+ *
73
107
* @param textFormatSetter the {@code TextFormat.Setter} for the text format.
74
108
*/
75
109
public static void setPropagationTextFormatSetter (@ Nullable TextFormat .Setter textFormatSetter ) {
76
110
propagationTextFormatSetter = textFormatSetter ;
77
111
}
78
112
113
+ /**
114
+ * Sets whether spans should be recorded locally.
115
+ *
116
+ * <p> This API allows users of google-http-client to turn on/off local span collection. </p>
117
+ *
118
+ * @param recordEvent record span locally if true.
119
+ */
120
+ public static void setIsRecordEvent (boolean recordEvent ) {
121
+ isRecordEvent = recordEvent ;
122
+ }
123
+
79
124
/**
80
125
* Returns the tracing component of OpenCensus.
81
126
*
@@ -85,15 +130,27 @@ public static Tracer getTracer() {
85
130
return tracer ;
86
131
}
87
132
133
+ /**
134
+ * Returns whether spans should be recorded locally.
135
+ *
136
+ * @return whether spans should be recorded locally.
137
+ */
138
+ public static boolean isRecordEvent () {
139
+ return isRecordEvent ;
140
+ }
141
+
88
142
/**
89
143
* Propagate information of current tracing context. This information will be injected into HTTP
90
144
* header.
145
+ *
146
+ * @param span the span to be propagated.
147
+ * @param headers the headers used in propagation.
91
148
*/
92
- public static void propagateTracingContext (HttpHeaders headers ) {
93
- Preconditions .checkNotNull (headers );
149
+ public static void propagateTracingContext (Span span , HttpHeaders headers ) {
150
+ Preconditions .checkArgument (span != null , "span should not be null." );
151
+ Preconditions .checkArgument (headers != null , "headers should not be null." );
94
152
if (propagationTextFormat != null && propagationTextFormatSetter != null ) {
95
- Span span = tracer .getCurrentSpan ();
96
- if (span != null && !span .equals (BlankSpan .INSTANCE )) {
153
+ if (!span .equals (BlankSpan .INSTANCE )) {
97
154
propagationTextFormat .inject (span .getContext (), headers , propagationTextFormatSetter );
98
155
}
99
156
}
@@ -107,7 +164,7 @@ public static void propagateTracingContext(HttpHeaders headers) {
107
164
*/
108
165
public static EndSpanOptions getEndSpanOptions (@ Nullable Integer statusCode ) {
109
166
// Always sample the span, but optionally export it.
110
- EndSpanOptions .Builder builder = EndSpanOptions .builder (). setSampleToLocalSpanStore ( true ) ;
167
+ EndSpanOptions .Builder builder = EndSpanOptions .builder ();
111
168
if (statusCode == null ) {
112
169
builder .setStatus (Status .UNKNOWN );
113
170
} else if (!HttpStatusCodes .isSuccess (statusCode )) {
@@ -139,6 +196,48 @@ public static EndSpanOptions getEndSpanOptions(@Nullable Integer statusCode) {
139
196
return builder .build ();
140
197
}
141
198
199
+ /**
200
+ * Records a new message event which contains the size of the request content.
201
+ * Note that the size represents the message size in application layer, i.e., content-length.
202
+ *
203
+ * @param span The {@code span} in which the send event occurs.
204
+ * @param size Size of the request.
205
+ */
206
+ public static void recordSentMessageEvent (Span span , long size ) {
207
+ recordMessageEvent (span , size , Type .SENT );
208
+ }
209
+
210
+ /**
211
+ * Records a new message event which contains the size of the response content.
212
+ * Note that the size represents the message size in application layer, i.e., content-length.
213
+ *
214
+ * @param span The {@code span} in which the receive event occurs.
215
+ * @param size Size of the response.
216
+ */
217
+ public static void recordReceivedMessageEvent (Span span , long size ) {
218
+ recordMessageEvent (span , size , Type .RECV );
219
+ }
220
+
221
+ /**
222
+ * Records a message event of a certain {@link NetowrkEvent.Type}.
223
+ * This method is package protected since {@link NetworkEvent} might be deprecated in future
224
+ * releases.
225
+ *
226
+ * @param span The {@code span} in which the event occurs.
227
+ * @param size Size of the message.
228
+ * @param eventType The {@code NetworkEvent.Type} of the message event.
229
+ */
230
+ @ VisibleForTesting
231
+ static void recordMessageEvent (Span span , long size , Type eventType ) {
232
+ Preconditions .checkArgument (span != null , "span should not be null." );
233
+ if (size < 0 ) size = 0 ;
234
+ NetworkEvent event = NetworkEvent
235
+ .builder (eventType , idGenerator .getAndIncrement ())
236
+ .setUncompressedMessageSize (size )
237
+ .build ();
238
+ span .addNetworkEvent (event );
239
+ }
240
+
142
241
static {
143
242
try {
144
243
propagationTextFormat = HttpPropagationUtil .getCloudTraceFormat ();
@@ -149,7 +248,16 @@ public void put(HttpHeaders carrier, String key, String value) {
149
248
}
150
249
};
151
250
} catch (Exception e ) {
152
- LOGGER .log (Level .WARNING , "Cannot initiate OpenCensus modules, tracing disabled" , e );
251
+ LOGGER .log (
252
+ Level .WARNING , "Cannot initialize default OpenCensus HTTP propagation text format." , e );
253
+ }
254
+
255
+ try {
256
+ Tracing .getExportComponent ().getSampledSpanStore ().registerSpanNamesForCollection (
257
+ Collections .<String >singletonList (SPAN_NAME_HTTP_REQUEST_EXECUTE ));
258
+ } catch (Exception e ) {
259
+ LOGGER .log (
260
+ Level .WARNING , "Cannot register default OpenCensus span names for collection." , e );
153
261
}
154
262
}
155
263
0 commit comments