24
24
import static org .junit .Assert .assertThrows ;
25
25
import static org .junit .Assert .assertTrue ;
26
26
import static org .junit .Assert .fail ;
27
+ import static org .junit .Assume .assumeFalse ;
28
+ import static org .junit .Assume .assumeTrue ;
27
29
28
30
import com .google .api .gax .longrunning .OperationTimedPollAlgorithm ;
29
31
import com .google .api .gax .retrying .RetrySettings ;
30
32
import com .google .api .gax .tracing .ApiTracerFactory ;
31
- import com .google .api .gax .tracing .MetricsTracerFactory ;
32
- import com .google .api .gax .tracing .OpenTelemetryMetricsRecorder ;
33
33
import com .google .cloud .NoCredentials ;
34
34
import com .google .cloud .spanner .MockSpannerServiceImpl .SimulatedExecutionTime ;
35
35
import com .google .cloud .spanner .MockSpannerServiceImpl .StatementResult ;
50
50
import io .opentelemetry .sdk .metrics .data .MetricData ;
51
51
import io .opentelemetry .sdk .testing .exporter .InMemoryMetricReader ;
52
52
import java .io .IOException ;
53
+ import java .lang .reflect .Field ;
53
54
import java .net .InetSocketAddress ;
54
55
import java .time .Duration ;
55
56
import java .util .Collection ;
65
66
66
67
@ RunWith (JUnit4 .class )
67
68
public class OpenTelemetryBuiltInMetricsTracerTest extends AbstractNettyMockServerTest {
68
-
69
69
private static final Statement SELECT_RANDOM = Statement .of ("SELECT * FROM random" );
70
-
71
70
private static final Statement UPDATE_RANDOM = Statement .of ("UPDATE random SET foo=1 WHERE id=1" );
72
71
private static InMemoryMetricReader metricReader ;
73
-
74
- private static OpenTelemetry openTelemetry ;
75
-
76
- private static Map <String , String > attributes ;
77
-
78
- private static Attributes expectedCommonBaseAttributes ;
79
- private static Attributes expectedCommonRequestAttributes ;
80
- private static ApiTracerFactory metricsTracerFactory ;
72
+ private static Map <String , String > attributes =
73
+ BuiltInMetricsProvider .INSTANCE .createClientAttributes ();
74
+ private static Attributes expectedCommonBaseAttributes =
75
+ Attributes .builder ()
76
+ .put (BuiltInMetricsConstant .CLIENT_NAME_KEY , "spanner-java/" )
77
+ .put (BuiltInMetricsConstant .CLIENT_UID_KEY , attributes .get ("client_uid" ))
78
+ .put (BuiltInMetricsConstant .INSTANCE_ID_KEY , "i" )
79
+ .put (BuiltInMetricsConstant .DATABASE_KEY , "d" )
80
+ .put (BuiltInMetricsConstant .DIRECT_PATH_ENABLED_KEY , "false" )
81
+ .build ();;
82
+ private static Attributes expectedCommonRequestAttributes =
83
+ Attributes .builder ().put (BuiltInMetricsConstant .DIRECT_PATH_USED_KEY , "false" ).build ();;
81
84
82
85
private static final long MIN_LATENCY = 0 ;
83
86
84
87
private DatabaseClient client ;
85
88
86
- @ BeforeClass
87
- public static void setup () {
89
+ public ApiTracerFactory createMetricsTracerFactory () {
88
90
metricReader = InMemoryMetricReader .create ();
89
91
90
- BuiltInMetricsProvider provider = BuiltInMetricsProvider .INSTANCE ;
91
-
92
92
SdkMeterProviderBuilder meterProvider =
93
93
SdkMeterProvider .builder ().registerMetricReader (metricReader );
94
-
95
94
BuiltInMetricsConstant .getAllViews ().forEach (meterProvider ::registerView );
95
+ OpenTelemetry openTelemetry =
96
+ OpenTelemetrySdk .builder ().setMeterProvider (meterProvider .build ()).build ();
96
97
97
- String client_name = "spanner-java/" ;
98
- openTelemetry = OpenTelemetrySdk .builder ().setMeterProvider (meterProvider .build ()).build ();
99
- attributes = provider .createClientAttributes ();
100
-
101
- expectedCommonBaseAttributes =
102
- Attributes .builder ()
103
- .put (BuiltInMetricsConstant .CLIENT_NAME_KEY , client_name )
104
- .put (BuiltInMetricsConstant .CLIENT_UID_KEY , attributes .get ("client_uid" ))
105
- .put (BuiltInMetricsConstant .INSTANCE_ID_KEY , "i" )
106
- .put (BuiltInMetricsConstant .DATABASE_KEY , "d" )
107
- .put (BuiltInMetricsConstant .DIRECT_PATH_ENABLED_KEY , "false" )
108
- .build ();
109
-
110
- expectedCommonRequestAttributes =
111
- Attributes .builder ().put (BuiltInMetricsConstant .DIRECT_PATH_USED_KEY , "false" ).build ();
112
- metricsTracerFactory =
113
- new BuiltInMetricsTracerFactory (
114
- new BuiltInMetricsRecorder (openTelemetry , BuiltInMetricsConstant .METER_NAME ),
115
- attributes );
98
+ return new BuiltInMetricsTracerFactory (
99
+ new BuiltInMetricsRecorder (openTelemetry , BuiltInMetricsConstant .METER_NAME ), attributes );
116
100
}
117
101
118
102
@ BeforeClass
@@ -123,9 +107,9 @@ public static void setupResults() {
123
107
}
124
108
125
109
@ After
126
- public void clearRequests () {
110
+ public void clearRequests () throws IOException {
127
111
mockSpanner .clearRequests ();
128
- metricReader .forceFlush ();
112
+ metricReader .close ();
129
113
}
130
114
131
115
@ Override
@@ -159,7 +143,7 @@ public void createSpannerInstance() {
159
143
// Setting this to false so that Spanner Options does not register Metrics Tracer
160
144
// factory again.
161
145
.setBuiltInMetricsEnabled (false )
162
- .setApiTracerFactory (metricsTracerFactory )
146
+ .setApiTracerFactory (createMetricsTracerFactory () )
163
147
.build ()
164
148
.getService ();
165
149
client = spanner .getDatabaseClient (DatabaseId .of ("test-project" , "i" , "d" ));
@@ -209,11 +193,92 @@ public void testMetricsSingleUseQuery() {
209
193
long gfeLatencyValue = getAggregatedValue (gfeLatencyMetricData , expectedAttributes );
210
194
assertEquals (fakeServerTiming .get (), gfeLatencyValue , 0 );
211
195
196
+ assertFalse (
197
+ checkIfMetricExists (metricReader , BuiltInMetricsConstant .GFE_CONNECTIVITY_ERROR_NAME ));
212
198
assertFalse (checkIfMetricExists (metricReader , BuiltInMetricsConstant .AFE_LATENCIES_NAME ));
213
199
assertFalse (
214
200
checkIfMetricExists (metricReader , BuiltInMetricsConstant .AFE_CONNECTIVITY_ERROR_NAME ));
215
201
}
216
202
203
+ private boolean isJava8 () {
204
+ return JavaVersionUtil .getJavaMajorVersion () == 8 ;
205
+ }
206
+
207
+ private boolean isWindows () {
208
+ return System .getProperty ("os.name" ).toLowerCase ().contains ("windows" );
209
+ }
210
+
211
+ @ Test
212
+ public void testMetricsSingleUseQueryWithAfeEnabled () throws Exception {
213
+ assumeTrue (isJava8 () && !isWindows ());
214
+ assumeFalse (System .getenv ().containsKey ("SPANNER_DISABLE_AFE_SERVER_TIMING" ));
215
+
216
+ Class <?> classOfMap = System .getenv ().getClass ();
217
+ Field field = classOfMap .getDeclaredField ("m" );
218
+ field .setAccessible (true );
219
+ Map <String , String > writeableEnvironmentVariables =
220
+ (Map <String , String >) field .get (System .getenv ());
221
+
222
+ try {
223
+ writeableEnvironmentVariables .put ("SPANNER_DISABLE_AFE_SERVER_TIMING" , "false" );
224
+
225
+ Stopwatch stopwatch = Stopwatch .createStarted ();
226
+ try (ResultSet resultSet = client .singleUse ().executeQuery (SELECT_RANDOM )) {
227
+ assertTrue (resultSet .next ());
228
+ assertFalse (resultSet .next ());
229
+ }
230
+
231
+ long elapsed = stopwatch .elapsed (TimeUnit .MILLISECONDS );
232
+ Attributes expectedAttributes =
233
+ expectedCommonBaseAttributes
234
+ .toBuilder ()
235
+ .putAll (expectedCommonRequestAttributes )
236
+ .put (BuiltInMetricsConstant .STATUS_KEY , "OK" )
237
+ .put (BuiltInMetricsConstant .METHOD_KEY , "Spanner.ExecuteStreamingSql" )
238
+ .build ();
239
+
240
+ MetricData operationLatencyMetricData =
241
+ getMetricData (metricReader , BuiltInMetricsConstant .OPERATION_LATENCIES_NAME );
242
+ assertNotNull (operationLatencyMetricData );
243
+ long operationLatencyValue =
244
+ getAggregatedValue (operationLatencyMetricData , expectedAttributes );
245
+ assertThat (operationLatencyValue ).isIn (Range .closed (MIN_LATENCY , elapsed ));
246
+
247
+ MetricData attemptLatencyMetricData =
248
+ getMetricData (metricReader , BuiltInMetricsConstant .ATTEMPT_LATENCIES_NAME );
249
+ assertNotNull (attemptLatencyMetricData );
250
+ long attemptLatencyValue = getAggregatedValue (attemptLatencyMetricData , expectedAttributes );
251
+ assertThat (attemptLatencyValue ).isIn (Range .closed (MIN_LATENCY , elapsed ));
252
+
253
+ MetricData operationCountMetricData =
254
+ getMetricData (metricReader , BuiltInMetricsConstant .OPERATION_COUNT_NAME );
255
+ assertNotNull (operationCountMetricData );
256
+ assertThat (getAggregatedValue (operationCountMetricData , expectedAttributes )).isEqualTo (1 );
257
+
258
+ MetricData attemptCountMetricData =
259
+ getMetricData (metricReader , BuiltInMetricsConstant .ATTEMPT_COUNT_NAME );
260
+ assertNotNull (attemptCountMetricData );
261
+ assertThat (getAggregatedValue (attemptCountMetricData , expectedAttributes )).isEqualTo (1 );
262
+
263
+ MetricData gfeLatencyMetricData =
264
+ getMetricData (metricReader , BuiltInMetricsConstant .GFE_LATENCIES_NAME );
265
+ long gfeLatencyValue = getAggregatedValue (gfeLatencyMetricData , expectedAttributes );
266
+ assertEquals (fakeServerTiming .get (), gfeLatencyValue , 0 );
267
+
268
+ assertFalse (
269
+ checkIfMetricExists (metricReader , BuiltInMetricsConstant .GFE_CONNECTIVITY_ERROR_NAME ));
270
+
271
+ MetricData afeLatencyMetricData =
272
+ getMetricData (metricReader , BuiltInMetricsConstant .AFE_LATENCIES_NAME );
273
+ long afeLatencyValue = getAggregatedValue (afeLatencyMetricData , expectedAttributes );
274
+ assertEquals (fakeAFEServerTiming .get (), afeLatencyValue , 0 );
275
+ assertFalse (
276
+ checkIfMetricExists (metricReader , BuiltInMetricsConstant .AFE_CONNECTIVITY_ERROR_NAME ));
277
+ } finally {
278
+ writeableEnvironmentVariables .remove ("GOOGLE_CLOUD_SPANNER_MULTIPLEXED_SESSIONS" );
279
+ }
280
+ }
281
+
217
282
@ Test
218
283
public void testMetricsWithGaxRetryUnaryRpc () {
219
284
Stopwatch stopwatch = Stopwatch .createStarted ();
@@ -284,10 +349,6 @@ public void testNoNetworkConnection() {
284
349
return null ;
285
350
});
286
351
287
- ApiTracerFactory metricsTracerFactory =
288
- new MetricsTracerFactory (
289
- new OpenTelemetryMetricsRecorder (openTelemetry , BuiltInMetricsConstant .METER_NAME ),
290
- attributes );
291
352
Spanner spanner =
292
353
builder
293
354
.setProjectId ("test-project" )
@@ -305,7 +366,7 @@ public void testNoNetworkConnection() {
305
366
// Setting this to false so that Spanner Options does not register Metrics Tracer
306
367
// factory again.
307
368
.setBuiltInMetricsEnabled (false )
308
- .setApiTracerFactory (metricsTracerFactory )
369
+ .setApiTracerFactory (createMetricsTracerFactory () )
309
370
.build ()
310
371
.getService ();
311
372
String instance = "i" ;
@@ -370,7 +431,7 @@ public void testNoServerTimingHeader() throws IOException, InterruptedException
370
431
// Setting this to false so that Spanner Options does not register Metrics Tracer
371
432
// factory again.
372
433
.setBuiltInMetricsEnabled (false )
373
- .setApiTracerFactory (metricsTracerFactory )
434
+ .setApiTracerFactory (createMetricsTracerFactory () )
374
435
.build ()
375
436
.getService ();
376
437
DatabaseClient databaseClientNoHeader =
@@ -391,6 +452,8 @@ public void testNoServerTimingHeader() throws IOException, InterruptedException
391
452
MetricData gfeConnectivityMetricData =
392
453
getMetricData (metricReader , BuiltInMetricsConstant .GFE_CONNECTIVITY_ERROR_NAME );
393
454
assertThat (getAggregatedValue (gfeConnectivityMetricData , expectedAttributes )).isEqualTo (1 );
455
+ assertFalse (checkIfMetricExists (metricReader , BuiltInMetricsConstant .AFE_LATENCIES_NAME ));
456
+ assertFalse (checkIfMetricExists (metricReader , BuiltInMetricsConstant .GFE_LATENCIES_NAME ));
394
457
assertFalse (
395
458
checkIfMetricExists (metricReader , BuiltInMetricsConstant .AFE_CONNECTIVITY_ERROR_NAME ));
396
459
spannerNoHeader .close ();
0 commit comments